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

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

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

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

ΠžΡΡ‚Π°Π»ΡΡ послСдний шаг β€” ΠΎΠ±ΡŠΡΡΠ½ΠΈΡ‚ΡŒ систСмС, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚, ΡƒΡ…Π²Π°Ρ‚ΠΈΠ² Π·Π° стрСлки, ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Ρ„ΠΎΡ€ΠΌΡ‹. ΠžΡ‡Π΅Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ дСлаСтся это Ρ‡Π΅Ρ€Π΅Π· ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ WM_NCHITTEST. Вопрос Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ ΡƒΠ·Π½Π°Ρ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΌΡ‹ΡˆΠΈ ΠΏΠΎΠΏΠ°Π΄Π°ΡŽΡ‚ Π²Π½ΡƒΡ‚Ρ€ΡŒ нарисованной стрСлки, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ стрСлка являСтся ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ слоТной Ρ„ΠΎΡ€ΠΌΡ‹, Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ это Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ просто. Данная Π·Π°Π΄Π°Ρ‡Π° Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ€Π΅Π³ΠΈΠΎΠ½ΠΎΠ²: ΠΏΠΎΠΏΠ°Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ курсора Π² Ρ€Π΅Π³ΠΈΠΎΠ½ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· стрСлок отслСТиваСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ стандартной Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ PtInRegion (листинг 1.57).

Листинг 1.57. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ WM_NCHITTEST Ρ„ΠΎΡ€ΠΌΡ‹

procedure TFormHole.WMNCHitTest(var Msg: TWMNCHitTest);

var

 Pt: TPoint;

begin

 // Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ Π½Π΅ΠΊΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΡƒΡŽ ΠΎΠ±Π»Π°ΡΡ‚ΡŒ,

 // Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ унаслСдованный ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ

 inherited;

 // НС Π·Π°Π±Ρ‹Π²Π°Π΅ΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ WM_NCHITTEST Π΄Π°ΡŽΡ‚ экранныС,

 // Π° Π½Π΅ клиСнтскиС ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹

 Pt := ScreenToClient(Point(Msg.XPos, Msg.YPos));

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

 if PtInRegion(ArrowTopLeft, Pt.X, Pt.Y) then

  Msg.Result := HTTOPLEFT

 else if PtInRegion(ArrowTopRight, Pt.X, Pt.Y) then

  Msg.Result := HTTOPRIGHT

 else

  if PtInRegion(ArrowBottomLeft, Pt.X, Pt.Y) then

   Msg.Result := HTBOTTOMLEFT

  else

   if PtInRegion(ArrowBottomRight, Pt.X, Pt.Y) then

    Msg.Result := HTBOTTOMRIGHT;

end;

Π’ΠΎΡ‚ ΠΈ всС. Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π½Π΅Ρ…ΠΈΡ‚Ρ€Ρ‹Ρ… ΠΏΡ€ΠΈΠ΅ΠΌΠΎΠ² ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠ»ΠΈ ΠΎΠΊΠ½ΠΎ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ Π½Π΅ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΉ Π²ΠΈΠ΄ (см. рис. 1.14).

1.3.4. ΠžΠ±ΠΎΠ±Ρ‰Π°ΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ 4 β€” Π›ΠΈΠ½ΠΈΠΈ нСстандартного стиля

GDI позволяСт Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ½ΠΈΠΈ Ρ€Π°Π·Π½Ρ‹Ρ… стилСй, Π½ΠΎ Π±Ρ‹Π²Π°ΡŽΡ‚ ситуации, ΠΊΠΎΠ³Π΄Π° стандартных возмоТностСй ΠΏΠΎ измСнСнию стиля Π»ΠΈΠ½ΠΈΠΉ Π½Π΅ Ρ…Π²Π°Ρ‚Π°Π΅Ρ‚. Π’ этом Ρ€Π°Π·Π΄Π΅Π»Π΅ ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ, ΠΊΠ°ΠΊ Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ½ΠΈΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ стиля (Π½Π°Ρ‡Π½Π΅ΠΌ с прямых, ΠΏΠΎΡ‚ΠΎΠΌ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ ΠΊ ΠΊΡ€ΠΈΠ²Ρ‹ΠΌ Π‘Π΅Π·ΡŒΠ΅), Π° Ρ‚Π°ΠΊΠΆΠ΅ сдСлаСм "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²ΡƒΡŽ" линию, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ‚ΡΠ½ΡƒΡ‚ΡŒ ΠΌΡ‹ΡˆΡŒΡŽ.

1.3.4.1. ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ Ρ‚ΠΎΡ‡Π΅ΠΊ прямой

РисованиС нСстандартных Π»ΠΈΠ½ΠΈΠΉ выполняСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ: Π²Ρ‹Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ всСх пиксСлов, ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… Π΄Π°Π½Π½ΡƒΡŽ ΠΏΡ€ΡΠΌΡƒΡŽ, Π° ΠΏΠΎΡ‚ΠΎΠΌ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· Π½ΠΈΡ… (Π° ΠΏΡ€ΠΈ нСобходимости β€” ΠΈ какая-Π»ΠΈΠ±ΠΎ Π΅Π³ΠΎ ΠΎΠΊΡ€Π΅ΡΡ‚Π½ΠΎΡΡ‚ΡŒ) Ρ€Π°ΡΠΊΡ€Π°ΡˆΠΈΠ²Π°ΡŽΡ‚ΡΡ Π½ΡƒΠΆΠ½Ρ‹ΠΌ Ρ†Π²Π΅Ρ‚ΠΎΠΌ. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ вопрос ΠΎΠ± ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠΈ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ пиксСлов.

БущСствуСт ряд Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² вычислСния этих ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚. НаиболСС извСстный ΠΈΠ· Π½ΠΈΡ… β€” Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ БрСзСнхэма (Bresengham), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ€Π°Π²Π½ΠΎΠΌΠ΅Ρ€Π½ΠΎΠΌ разбрасывании "ступСнСк" Ρ€Π°Π·Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹ вдоль Π»ΠΈΠ½ΠΈΠΈ. Π’ Windows ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ GIQ (Grid Intersection Quantization). ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ пиксСл окруТаСтся Π²ΠΎΠΎΠ±Ρ€Π°ΠΆΠ°Π΅ΠΌΡ‹ΠΌ Ρ€ΠΎΠΌΠ±ΠΎΠΌ ΠΈΠ· Ρ‡Π΅Ρ‚Ρ‹Ρ€Π΅Ρ… пиксСлов. Если прямая ΠΈΠΌΠ΅Π΅Ρ‚ ΠΎΠ±Ρ‰ΠΈΠ΅ Ρ‚ΠΎΡ‡ΠΊΠΈ с этим Ρ€ΠΎΠΌΠ±ΠΎΠΌ, Ρ‚ΠΎ пиксСл рисуСтся.

Π‘Π°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Ρ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Ρ‚Π°ΠΊΠΈΡ… Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² Π½Π΅Ρ‚ нСобходимости β€” Π² Windows сущСствуСт функция LineDDA, которая Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π²ΡˆΠ΅ΠΉ Π΅Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π»ΠΈΠ½ΠΈΠΈ. Π­Ρ‚Π° функция Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π½Π°Ρ‡Π°Π»Π° ΠΈ ΠΊΠΎΠ½Ρ†Π° Π»ΠΈΠ½ΠΈΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒΡΡ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ пиксСлов. Данная функция Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π° Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅. Π—Π° врСмя выполнСния LineDDA эта функция Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ€Π°Π·, сколько пиксСлов содСрТит линия (ΠΊΠ°ΠΊ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π² Windows, послСдний пиксСл Π½Π΅ считаСтся ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‰ΠΈΠΌ прямой). ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ Π΅ΠΉ Π±ΡƒΠ΄ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒΡΡ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ³ΠΎ пиксСла, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ пиксСлы Π±ΡƒΠ΄ΡƒΡ‚ упорядочСны ΠΎΡ‚ Π½Π°Ρ‡Π°Π»Π° ΠΊ ΠΊΠΎΠ½Ρ†Ρƒ прямой.

Π’ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Lines (рис. 1.15) с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ LineDDA рисуСтся ΠΏΡΡ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠΎΠ² Π»ΠΈΠ½ΠΈΠΉ. Рассмотрим Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ самого слоТного ΠΈΠ· Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΡ‹Ρ… ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΎΠΉ Ρ‚ΠΈΠΏΠΎΠ² Π»ΠΈΠ½ΠΈΠΈ ("ЗСлСная Π΅Π»ΠΎΡ‡ΠΊΠ°"), ΠΊΠ°ΠΊ это дСлаСтся (листинг 1.58).

Рис. 1.15. Окно ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Lines


Листинг 1.58. РисованиС Π»ΠΈΠ½ΠΈΠΈ слоТного стиля

// константы для Ρ‚ΠΈΠΏΠ° "ЗСлСная Π΅Π»ΠΎΡ‡ΠΊΠ°"

const

 // Π£Π³ΠΎΠ» отклонСния "ΠΈΠ³ΠΎΠ»ΠΊΠΈ" ΠΎΡ‚ направлСния Π»ΠΈΠ½ΠΈΠΈ

 FirNeedleAngle = 30;

 //Π”Π»ΠΈΠ½Π° ΠΈΠ³ΠΎΠ»ΠΊΠΈ

 FirNeedleLength = 8;


var

 Counter: Integer; // Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ Ρ‚ΠΎΡ‡Π΅ΠΊ Π»ΠΈΠ½ΠΈΠΈ

 // Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ для построСния "Π΅Π»ΠΎΡ‡ΠΊΠΈ"

 DX1, DY1, DX2, DY2: Integer;


// Линия Π² Π²ΠΈΠ΄Π΅ "Π΅Π»ΠΎΡ‡ΠΊΠΈ"

procedure LineDrawFir(X, Y: Integer; Canvas: TCanvas); stdcall;

begin

 with Canvas do case Counter mod 10 of

  0: begin

   MoveTo(X, Y);

   LineTo(X + DX1, Y + DY1);

  end;

  5:

  begin

   MoveTo(X, Y);

   LineTo(X + DX2, Y + DY2);

  end;

 end;

 Inc(Counter);

end;


procedure TLinesForm.Line(X1, Y1, X2, Y2: Integer);

var

 Angle: Extended;

begin

 case RGroupLine.ItemIndex of

  ...

  4:

 begin

   Counter := 0;

   Angle := ArcTan2(Y2 - Y1, X2 - X1);

   DX1 := Round(FirNeedleLength *

    Cos(Angle + Pi / 180 * FirNeedleAngle));

   DY1 := Round(FirNeedleLength *

    Sin(Angle + Pi / 180 * FirNeedleAngle));

   DX2 := Round(FirNeedleLength *

    Cos(Angle - Pi / 180 * FirNeedleAngle));

   DY2 := Round(FirNeedleLength *

    Sin(Angle - Pi / 180 * FirNeedleAngle));

   LineDDA(X1, Y1, X2, Y2, @LineDrawFir, Integer(Canvas));

  end;

 end;

end;

КаТдая "ΠΈΠ³ΠΎΠ»ΠΊΠ°" β€” это линия Π΄Π»ΠΈΠ½ΠΎΠΉ FirNeedleLength пиксСлов, ΠΎΡ‚ΠΊΠ»ΠΎΠ½ΡΡŽΡ‰Π°ΡΡΡ ΠΎΡ‚ направлСния прямой Π½Π° ΡƒΠ³ΠΎΠ» FirNeedleAngle градусов. "Иголки" ΠΎΡ‚ΠΊΠ»ΠΎΠ½ΡΡŽΡ‚ΡΡ ΠΏΠΎΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ Π² ΠΎΠ΄Π½Ρƒ, Ρ‚ΠΎ Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ сторону ΠΎΡ‚ прямой. Π’ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ Line сначала Ρ€Π°ΡΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ смСщСния ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ ΠΊΠΎΠ½Ρ†Π° "ΠΈΠ³ΠΎΠ»ΠΊΠΈ" ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π°Ρ‡Π°Π»Π° ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ DX1, DY1, DX2, DY2. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ Counter слуТит для опрСдСлСния Π½ΠΎΠΌΠ΅Ρ€Π° Ρ‚ΠΎΡ‡ΠΊΠΈ. ΠŸΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ LineDDA ΠΎΠ½Π° инициализируСтся Π½ΡƒΠ»Π΅ΠΌ. Π—Π°Ρ‚Π΅ΠΌ вызываСтся функция LineDDA, Π² качСствС ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ пСрСдаСтся ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° LineDrawFir. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ этого функция LineDrawFir Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π·Π²Π°Π½Π° ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· пиксСлов, ΡΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΡ… линию, начиная с (X1, Y1). LineDrawFir Π²Π΅Π΄Π΅Ρ‚ подсчСт пиксСлов, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· увСличивая Counter Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ. Если остаток ΠΎΡ‚ дСлСния Π½ΠΎΠΌΠ΅Ρ€Π° Ρ‚ΠΎΡ‡ΠΊΠΈ Π½Π° 10 Ρ€Π°Π²Π΅Π½ 0, рисуСтся "ΠΈΠ³ΠΎΠ»ΠΊΠ°", ΠΎΡ‚ΠΊΠ»ΠΎΠ½ΡΡŽΡ‰Π°ΡΡΡ Π² ΠΏΠΎΠ»ΠΎΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ, Ссли 5 β€” Π² ΠΎΡ‚Ρ€ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΌ. Π’ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… случаях Π½Π΅ рисуСтся Π½ΠΈΡ‡Π΅Π³ΠΎ. Π’Π°ΠΊ получаСтся "Π΅Π»ΠΎΡ‡ΠΊΠ°".

1.3.4.2. "РСзиновая" линия ΠΈ растровыС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π½ΡƒΠΆΠ½ΠΎ Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ½ΠΈΠΈ. Для этого ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²ΡƒΡŽ" линию: ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ Π»Π΅Π²ΡƒΡŽ ΠΊΠ½ΠΎΠΏΠΊΡƒ ΠΌΡ‹ΡˆΠΈ ΠΈ, удСрТивая Π΅Π΅, ΠΏΠ΅Ρ€Π΅Π΄Π²ΠΈΠ³Π°Π΅Ρ‚ ΠΌΡ‹ΡˆΡŒ. Π”ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° ΠΊΠ½ΠΎΠΏΠΊΠ° удСрТиваСтся, Π·Π° курсором тянСтся линия. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ отпускаСт ΠΊΠ½ΠΎΠΏΠΊΡƒ, линия "впСчатываСтся" Π² рисунок.

Π‘Π°ΠΌΠ° ΠΏΠΎ сСбС рСализация "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²ΠΎΠΉ" Π»ΠΈΠ½ΠΈΠΈ ΠΎΡ‡Π΅Π½ΡŒ проста: ΠΏΡ€ΠΈ наступлСнии события OnMouseDown Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π½Π°Ρ‡Π°Π»Π° Π»ΠΈΠ½ΠΈΠΈ ΠΈ взводится Ρ„Π»Π°Π³, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ, Ρ‡Ρ‚ΠΎ Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Ρ€Π΅ΠΆΠΈΠΌ рисования "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²ΠΎΠΉ" Π»ΠΈΠ½ΠΈΠΈ. Π’Π°ΠΊΠΆΠ΅ Π·Π°ΠΏΠΎΠΌΠΈΠ½Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΊΠΎΠ½Ρ†Π° ΠΎΡ‚Ρ€Π΅Π·ΠΊΠ°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π° Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ совпадаСт с Π½Π°Ρ‡Π°Π»ΠΎΠΌ. Π’ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ΅ OnMouseMove, Ссли Π²ΠΊΠ»ΡŽΡ‡Π΅Π½ Ρ€Π΅ΠΆΠΈΠΌ рисования "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²ΠΎΠΉ" Π»ΠΈΠ½ΠΈΠΈ, стираСтся линия со старыми ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°ΠΌΠΈ ΠΊΠΎΠ½Ρ†Π° ΠΈ рисуСтся с Π½ΠΎΠ²Ρ‹ΠΌΠΈ. ΠŸΡ€ΠΈ наступлСнии OnMouseUp ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π²Ρ‹Ρ…ΠΎΠ΄ΠΈΡ‚ ΠΈΠ· Ρ€Π΅ΠΆΠΈΠΌΠ° рисования "Ρ€Π΅Π·ΠΈΠ½ΠΎΠ²ΠΎΠΉ" Π»ΠΈΠ½ΠΈΠΈ, рисуя ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Π΅Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ с Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΌΠΈ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Π°ΠΌΠΈ ΠΊΠΎΠ½Ρ†Π°.

Π‘Π°ΠΌΠΎΠ΅ слоТноС Π² этой ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ дСйствий β€” ΡΡ‚Π΅Ρ€Π΅Ρ‚ΡŒ Π½Π°Ρ€ΠΈΡΠΎΠ²Π°Π½Π½ΡƒΡŽ Ρ€Π°Π½Π΅Π΅ линию. Если Π±Ρ‹ Ρƒ нас Π±Ρ‹Π» ΠΎΠ΄Π½ΠΎΡ€ΠΎΠ΄Π½Ρ‹ΠΉ Ρ„ΠΎΠ½, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ просто Π½Π°Ρ€ΠΈΡΠΎΠ²Π°Ρ‚ΡŒ ΡΡ‚Π°Ρ€ΡƒΡŽ линию Π΅Ρ‰Π΅ Ρ€Π°Π· Ρ†Π²Π΅Ρ‚ΠΎΠΌ Ρ„ΠΎΠ½Π° β€” это выглядСло Π±Ρ‹ ΠΊΠ°ΠΊ Π΅Π΅ стираниС. Но ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Ρ„ΠΎΠ½ Π½Π΅ ΠΎΠ΄Π½ΠΎΡ€ΠΎΠ΄Π½Ρ‹ΠΉ, Π° составлСн ΠΈΠ· нарисованных Ρ€Π°Π½Π΅Π΅ Π»ΠΈΠ½ΠΈΠΉ, этот способ ΠΌΡ‹ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ.

Для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой Π·Π°Π΄Π°Ρ‡ΠΈ ΠΌΡ‹ здСсь рассмотрим самый простой ΠΌΠ΅Ρ‚ΠΎΠ΄ β€” инвСрсноС рисованиС (Π±ΠΎΠ»Π΅Π΅ слоТный ΠΌΠ΅Ρ‚ΠΎΠ΄ Π±ΡƒΠ΄Π΅Ρ‚ рассмотрСн Ρ‡ΡƒΡ‚ΡŒ ΠΏΠΎΠ·ΠΆΠ΅). ΠŸΡ€ΠΈ этом каТдая Ρ‚ΠΎΡ‡ΠΊΠ°, принадлСТащая Π»ΠΈΠ½ΠΈΠΈ, Π·Π°ΠΊΡ€Π°ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π½Π΅ ΠΊΠ°ΠΊΠΈΠΌ-Π»ΠΈΠ±ΠΎ фиксированным Ρ†Π²Π΅Ρ‚ΠΎΠΌ, Π° инвСртируСтся (Ρ‚.Π΅. ΠΊ Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΌΡƒ Ρ†Π²Π΅Ρ‚Ρƒ Ρ‚ΠΎΡ‡ΠΊΠΈ примСняСтся опСрация not). Для стирания Π»ΠΈΠ½ΠΈΠΈ просто рисуСм Π΅Π΅ Π΅Ρ‰Π΅ Ρ€Π°Π·: двойная инвСрсия восстанавливаСт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠΉ Ρ†Π²Π΅Ρ‚ Ρ‚ΠΎΡ‡Π΅ΠΊ (not not X = X для любого X).

ΠŸΡ€ΠΈ рисовании ΠΏΠ΅Ρ€ΠΎΠΌ ΠΈ ΠΊΠΈΡΡ‚ΡŒΡŽ GDI позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ растровыС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ†Π²Π΅Ρ‚ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ пиксСла Π² зависимости ΠΎΡ‚ Ρ†Π²Π΅Ρ‚Π° Ρ„ΠΎΠ½Π° ΠΈ ΠΏΠ΅Ρ€Π° ΠΈΠ»ΠΈ кисти. По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ примСняСтся опСрация R2_COPYPEN, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Ρ†Π²Π΅Ρ‚ Ρ„ΠΎΠ½Π° игнорируСтся, Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ Ρ†Π²Π΅Ρ‚ пиксСла совпадаСт с Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΏΠ΅Ρ€Π° ΠΈΠ»ΠΈ кисти. Π˜Π·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Ρ€Π°ΡΡ‚Ρ€ΠΎΠ²ΡƒΡŽ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ SetROP2 (Π΄Π²ΠΎΠΉΠΊΠ° Π² Π½Π°Π·Π²Π°Π½ΠΈΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ устанавливаСмая растровая опСрация ΠΈΠΌΠ΅Π΅Ρ‚ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° β€” Ρ†Π²Π΅Ρ‚ рисования ΠΈ Ρ†Π²Π΅Ρ‚ Ρ„ΠΎΠ½Π°: ΠΏΡ€ΠΈ Π²Ρ‹Π²ΠΎΠ΄Π΅ растровых рисунков ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ растровыС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с трСмя Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ β€” см. Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ BitBlt). Нас Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠΎΠ²Π°Ρ‚ΡŒ опСрация R2_NOT, которая ΠΈΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ„ΠΎΠ½ΠΎΠ²Ρ‹ΠΉ Ρ†Π²Π΅Ρ‚, игнорируя Ρ†Π²Π΅Ρ‚ ΠΏΠ΅Ρ€Π° ΠΈΠ»ΠΈ кисти.