Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «О Ρ‡Ρ‘ΠΌ Π½Π΅ ΠΏΠΈΡˆΡƒΡ‚ Π² ΠΊΠ½ΠΈΠ³Π°Ρ… ΠΏΠΎ DelphiΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 39

Автор А. Π“Ρ€ΠΈΠ³ΠΎΡ€ΡŒΠ΅Π²

 R: TRect;

begin

 POldPanelWndProc(Msg);

 if Msg.Msg = WM_NCHITTEST then

 begin

  // Вся Ρ…ΠΈΡ‚Ρ€ΠΎΡΡ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ сообщСния WM_NCHITTEST

  // Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠΌ ΠΏΠ΅Ρ€Π΅Π²ΠΎΠ΄Π΅ экранных ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚

  // Π² клиСнтскиС ΠΈ Π² нСсколько ΠΌΡƒΡ‚ΠΎΡ€Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ΅ попадания

  // ΠΌΡ‹ΡˆΠΈ Π½Π° сторону Ρ€Π°ΠΌΠΊΠΈ ΠΈΠ»ΠΈ Π² Π΅Π΅ ΡƒΠ³ΠΎΠ». Π”Π΅Π»ΠΎ упрощаСтся

  // Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ ΠΏΠ°Π½Π΅Π»ΠΈ Π½Π΅Ρ‚ нСклиСнтской части, поэтому

  // Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Π»Π΅Π²Ρ‹ΠΉ ΡƒΠ³ΠΎΠ» ΠΎΠΊΠ½Π° ΠΈ Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ Π»Π΅Π²Ρ‹ΠΉ ΡƒΠ³ΠΎΠ» клиСнтской

  // части ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‚.

  Pt := PanelHole.ScreenToClient(Point(Msg.LParamLo, Msg.LParamHi));

  if Pt.X < BorderMouseSensivity then

   if Pt.Y < CornerMouseSensivity then Msg.Result := HTTOPLEFT

   else

    if Pt.Y >= PanelHole.Height - CornerMouseSensivity then

Msg.Result := HTBOTTOMLEFT

    else Msg.Result := HTLEFT

   else

    if Pt.X >= PanelHole.Width - BorderMouseSensivity then

     if Pt.Y < CornerMouseSensivity then Msg.Result := HTTOPRIGHT

     else

      if Pt.Y >= PanelHole.Height - CornerMouseSensivity then

       Msg.Result := HTBOTTOMRIGHT

      else Msg.Result := HTRIGHT

    else

     if Pt.Y < BorderMouseSensivity then

      if Pt.X < CornerMouseSensivity then Msg.Result := HTTOPLEFT

      else

       if Pt.X >= PanelHole.Width - CornerMouseSensivity then

        Msg.Result := HTTOPRIGHT

       else Msg.Result := HTTOP

     else

if Pt.Y >= PanelHole.Height - BorderMouseSensivity then

       if Pt.X < CornerMouseSensivity then

        Msg.Result := HTBOTTOMLEFT

       else

        if Pt.X >= PanelHole.Width - CornerMouseSensivity then

         Msg.Result := HTBOTTOMRIGHT

        else Msg. Result := HTBOTTOM;

 end

 else if Msg.Msg = WM_SIZE then

 begin

  // ΠŸΠ΅Ρ€Π΅ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ Ρ€Π΅Π³ΠΈΠΎΠ½ SetRegion;

  // УстанавливаСм Π½ΠΎΠ²Ρ‹Π΅ ограничСния для Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π°.

  // ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‰ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π΄Ρ‹Ρ€ΠΊΠΈ

  Constraints.MinWidth :=

   Width - ClientWidth + PanelHole.Left + MinHoleSize + HoleDistance;

  Constraints.MinHeight :=

   Height - ClientHeight + PanelHole.Top + MinHoleSize + HoleDistance;

 end

 else if Msg.Msg = WM_SIZING then

 begin

  // ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ R,

  // ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ пСрСсчитывая ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΈΠ· экранных

  // Π² клиСнтскиС

  R.TopLeft := ScreenToClient(PRect(Msg.LParam)^.TopLeft);

  R.BottomRight := ScreenToClient(PRect(Msg.LParam)^.BottomRight);

  // Если ΡˆΠΈΡ€ΠΈΠ½Π° слишком ΠΌΠ°Π»Π°, провСряСм, Π·Π° ΠΊΠ°ΠΊΡƒΡŽ

  // сторону тянСт ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ. Если Π·Π° Π»Π΅Π²ΡƒΡŽ -

  // ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π»Π΅Π²ΠΎΠΉ стороны, Ссли Π·Π°

  // ΠΏΡ€Π°Π²ΡƒΡŽ - Π΅Π΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹

  if R.Right - R.Left < MinHoleSize then

   if Msg.WParam in [WMSZ_BOTTOMLEFT, WMSZ_LEFT, WMSZ_TOPLEFT] then

    R.Left := R.Right - MinHoleSize

   else

    R.Right := R.Left + MinHoleSize;

    // Аналогично дСйствуСм, Ссли слишком ΠΌΠ°Π»Π° высота

    if R.Bottom - R.Top < MinHoleSize then

     if Msg.WParam in [WMSZ_TOP, WMSZ_TOPLEFT, WMSZ_TOPRIGHT] then

      R.Top := R.Bottom - MinHoleSize

     else R.Bottom := R.Top + MinHoleSize;

  // Π‘Π΄Π²ΠΈΠ³Π°Π΅ΠΌ стороны, слишком Π±Π»ΠΈΠ·ΠΊΠΎ подошСдшиС

  // ΠΊ Π³Ρ€Π°Π½ΠΈΡ†Π°ΠΌ ΠΎΠΊΠ½Π°

  if R.Left < HoleDistance then R.Left := HoleDistance;

  if R.Top < HoleDistance then R.Top := HoleDistance;

  if R.Right > ClientWidth - HoleDistance then

   R.Right := ClientWidth - HoleDistance;

  if R.Bottom > ClientHeight - HoleDistance then

   R.Bottom := ClientHeight - HoleDistance;

  // ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ R, пСрСводя Π΅Π³ΠΎ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹

  // ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² экранныС

  PRect(Msg.LParam)^.TopLeft := ClientToScreen(R.TopLeft);

  PRect(Msg.LParam)^.BottomRight := ClientToScreen(R.BottomRight);

 end;

end;

ΠžΡΡ‚Π°Π΅Ρ‚ΡΡ Π΅Ρ‰Π΅ ΠΎΠ΄Π½Π° ситуация, ΠΊΠΎΠ³Π΄Π° Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ "Π΄Ρ‹Ρ€ΠΊΠΈ" ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ΄ΠΎΠΉΡ‚ΠΈ ΠΊ Π³Ρ€Π°Π½ΠΈΡ†Π°ΠΌ ΠΎΠΊΠ½Π° слишком Π±Π»ΠΈΠ·ΠΊΠΎ: ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ мСняСт Π½Π΅ Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ "Π΄Ρ‹Ρ€ΠΊΠΈ", Π° Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ самого ΠΎΠΊΠ½Π°. Π§Ρ‚ΠΎΠ±Ρ‹ этого Π½Π΅ ΡΠ»ΡƒΡ‡ΠΈΠ»ΠΎΡΡŒ, Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ измСнСния Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π° ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Π΄Ρ‹Ρ€ΠΊΠΈ β€” для этого Π½Π°ΠΌ потрСбуСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΏΠ°Π½Π΅Π»ΠΈ ΠΈ ΠΏΠ΅Ρ€Π΅ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ€Π΅Π³ΠΈΠΎΠ½. ΠŸΠ΅Ρ€Π΅ΡΡ‡Π΅Ρ‚ Ρ€Π΅Π³ΠΈΠΎΠ½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌ ΠΈ Π² случаС увСличСния Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π°: Ссли Π΅Π³ΠΎ Π½Π΅ ΠΏΠ΅Ρ€Π΅ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ, получится, Ρ‡Ρ‚ΠΎ Ρ‡Π°ΡΡ‚ΡŒ ΠΎΠΊΠ½Π° Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠΎΠΏΠ°Π΄Π°Ρ‚ΡŒ Π² Ρ€Π΅Π³ΠΈΠΎΠ½ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚Ρ€Π΅Π·Π°Π½Π°. ВсС пСрСчислСнныС дСйствия Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ сообщСния WM_SIZE ΠΎΠΊΠ½Π° (листинг 1.54).

Листинг 1.54. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ сообщСния WM_SIZE Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π°

procedure TFormHole.WMSize(var Msg: TWMSize);

begin

 inherited;

 // ΠŸΡ€ΠΈ ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π° ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π΄Ρ‹Ρ€ΠΊΠΈ,

 // Ссли Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ ΠΎΠΊΠ½Π° подошли слишком Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ Π½Π΅ΠΉ

 if PanelHole.Left + PanelHole.Width > ClientWidth - HoleDistance then

  PanelHole.Width := ClientWidth - HoleDistance - PanelHole.Left;

 if PanelHole.Top + PanelHole.Height > ClientHeight - HoleDistance then

  PanelHole.Height := ClientHeight - HoleDistance - PanelHole.Top;

 // На случай увСличСния ΠΎΠΊΠ½Π° пСрСсчитываСм Π΅Π³ΠΎ Ρ€Π΅Π³ΠΈΠΎΠ½,

 // ΠΈΠ½Π°Ρ‡Π΅ Ρ‚Π° Ρ‡Π°ΡΡ‚ΡŒ, которая добавилась, окаТСтся Π·Π° Π΅Π³ΠΎ

 // ΠΏΡ€Π΅Π΄Π΅Π»Π°ΠΌΠΈ ΠΈ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΡ‚Ρ€Π΅Π·Π°Π½Π° SetRegion;

 // ΠŸΠ΅Ρ€Π΅ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Π΅ΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ стрСлок

 CalculateArrows;

 Invalidate;

end;

НапослСдок Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΎΠ΄ΠΈΠ½ "Π±Π°Π½Ρ‚ΠΈΠΊ": красныС стрСлки ΠΏΠΎ ΡƒΠ³Π»Π°ΠΌ Ρ„ΠΎΡ€ΠΌΡ‹, Π·Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡ‚ΡΠ½ΡƒΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€. КаТдая стрСлка Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒΡΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΌ Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠΌ. ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ² Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ привязаны ΠΊ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΌ ΡƒΠ³Π»Π°ΠΌ ΠΎΠΊΠ½Π°, поэтому ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠ² ΠΎΠΊΠ½Π° эти ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ придСтся ΠΏΠ΅Ρ€Π΅ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ (Π² листингС 1.54 ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ²). ВсС стрСлки выглядят ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ, Π½ΠΎ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Π·Π΅Ρ€ΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΎΡ‚Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π΄Ρ€ΡƒΠ³ Π΄Ρ€ΡƒΠ³Π°. Π§Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ стрСлок, ΠΌΡ‹ Π·Π°Π΄Π°Π΄ΠΈΠΌ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΎΠ΄Π½ΠΎΠΉ нарисованной Π·Π°Ρ€Π°Π½Π΅Π΅ стрСлки Π² Π²ΠΈΠ΄Π΅ константы, Π° ΠΏΠΎΡ‚ΠΎΠΌ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° основС этих Π΄Π°Π½Π½Ρ‹Ρ… ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… стрСлок, отраТая ΠΈΡ… ΠΎΡ‚ Π½ΡƒΠΆΠ½ΠΎΠΉ плоскости ΠΈ добавляя Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ΅ смСщСниС (листинг 1.55).

Листинг 1.55. РасчСт ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ стрСлок

// ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π²Π΅Ρ€Ρ…Π½Π΅ΠΉ Π»Π΅Π²ΠΎΠΉ стрСлки, отсчитанныС ΠΎΡ‚ Ρ‚ΠΎΡ‡ΠΊΠΈ

// (0,0). Для получСния ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… стрСлок эти Ρ‚ΠΎΡ‡ΠΊΠΈ

// Π±ΡƒΠ΄ΡƒΡ‚ ΡΠΌΠ΅Ρ‰Π°Ρ‚ΡŒΡΡ ΠΈ ΠΎΡ‚Ρ€Π°ΠΆΠ°Ρ‚ΡŒΡΡ

const

 ArrowTemplate: TArrowCoords = (

  (X:0; Y:0), (X:24; Y:0), (X:17; Y:7), (X:29; Y:19),

  (X:19; Y:29), (X:7; Y:17), (X:0; Y:24));


procedure TFomHole.CalculateArrows;

var

 Arrow: TArrowCoords;

 I: Integer;

begin

 // ВычислСниС Ρ€Π΅Π³ΠΈΠΎΠ½Π° Π»Π΅Π²ΠΎΠΉ Π²Π΅Ρ€Ρ…Π½Π΅ΠΉ стрСлки

 // ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ просто ΡΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π½Π° ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ

 for I := 0 to High(Arrow) do

 begin

  Arrow[I].X := ArrowTemplate[I].X + ArrowOffset;

  Arrow[I].Y := ArrowTemplate[I].Y + ArrowOffset;

 end;

 // ΠŸΡ€ΠΈ нСобходимости ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅ΠΌ старый Ρ€Π΅Π³ΠΈΠΎΠ½

 if ArrowTopLeft <> 0 then DeleteObject(ArrowTopLeft);

 ArrowTopLeft :=

  CreatePolygonRgn(Arrow[0], Length(Arrow), WINDING);

 // ВычислСниС Ρ€Π΅Π³ΠΈΠΎΠ½Π° ΠΏΡ€Π°Π²ΠΎΠΉ Π²Π΅Ρ€Ρ…Π½Π΅ΠΉ стрСлки

 // ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΠΎ X ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ ΠΈ ΡΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ

 // Π½Π° ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ края ΠΎΠΊΠ½Π°

 for I := 0 to High(Arrow) do

 begin

  Arrow[I].X := ClientWidth - ArrowOffset - 1 - ArrowTemplate[I].X;

  Arrow[I].Y := ArrowTemplate[I].Y + ArrowOffset;

 end;

 if ArrowTopRight <> 0 then DeleteObject(ArrowTopRight);

 ArrowTopRight := CreatePolygonRgn(Arrow[0], Length(Arrow), WINDING);

 // ВычислСниС Ρ€Π΅Π³ΠΈΠΎΠ½Π° Π»Π΅Π²ΠΎΠΉ Π½ΠΈΠΆΠ½Π΅ΠΉ стрСлки

 // ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΠΎ Y ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ ΠΈ ΡΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ

 // Π½Π° ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΠΈΠΆΠ½Π΅Π³ΠΎ края ΠΎΠΊΠ½Π°

 for I := 0 to High(Arrow) do

 begin

  Arrow[I].X := ArrowTemplate[I].X + ArrowOffset;

  Arrow[I].Y := ClientHeight - ArrowOffset - 1 - ArrowTemplate[I].Y;

 end;

 if ArrowBottomLeft <> 0 then DeleteObject(ArrowBottomLeft);

 ArrowBottomLeft := CreatePolygonRgn(Arrow[0], Length(Arrow), WINDING);

 // ВычислСниС Ρ€Π΅Π³ΠΈΠΎΠ½Π° ΠΏΡ€Π°Π²ΠΎΠΉ Π½ΠΈΠΆΠ½Π΅ΠΉ стрСлки

 // ΠšΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΏΠΎ ΠΎΠ±Π΅ΠΈΠΌ осям ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ ΠΈ ΡΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ

 // Π½Π° ΠΏΠΎΡΡ‚ΠΎΡΠ½Π½ΡƒΡŽ Π²Π΅Π»ΠΈΡ‡ΠΈΠ½Ρƒ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΡ€Π°Π²ΠΎΠ³ΠΎ Π½ΠΈΠΆΠ½Π΅Π³ΠΎ ΡƒΠ³Π»Π° ΠΎΠΊΠ½Π°

 for I := 0 to High(Arrow) do

 begin

  Arrow[I].X := ClientWidth - ArrowOffset - 1 - ArrowTemplate[I].X;

  Arrow[I].Y := ClientHeight - ArrowOffset - 1 - ArrowTemplate[I].Y;

 end;

 if ArrowBottomRight <> 0 then DeleteObject(ArrowBottomRight);

 ArrowBottomRight := CreatePolygonRgn(Arrow[0], Length(Arrow), WINDING);

end;

Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ шаг β€” рисованиС стрСлки Π½Π° Ρ„ΠΎΡ€ΠΌΠ΅. ДСлаСтся это ΠΎΡ‡Π΅Π½ΡŒ просто (листинг 1.56).

Листинг 1.56. РисованиС стрСлок Π½Π° Ρ„ΠΎΡ€ΠΌΠ΅

procedure TFormHole.FormPaint(Sender: TObject);

begin

 // Π—Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅ΠΌ Ρ€Π΅Π³ΠΈΠΎΠ½Ρ‹ стрСлок

 Canvas.Brush.Style := bsSolid;

 Canvas.Brush.Color := clRed;

 FillRgn(Canvas.Handle, ArrowTopLeft, Canvas.Brush.Handle);

 FillRgn(Canvas.Handle, ArrowTopRight, Canvas.Brush.Handle);

 FillRgn(Canvas.Handle, ArrowBottomLeft, Canvas.Brush.Handle);

 FillRgn(Canvas.Handle, ArrowBottomRight, Canvas.Brush.Handle);