Solved

drawing Graphics and mouse position simultaneously

Posted on 2004-09-12
6
182 Views
Last Modified: 2010-05-18
I am using canvas.moveto and canvas.lineto to draw a stepped line that is moving from right to left, by drawing, changing the color to tha background and redrawing. I want to try to follow the line while it is being drawn, and moving, with the mouse, then compare the mouse path with the actual line. Is this possible? The stepped line coordinates are in an array (columns 1 to 4 for starting point and endpoint) and I want the mouse coordinates in the same array (columns 5 and 6).

Can onmousemove be active while already drawing without the mouse?

I need a very urgent answer!!!
Thanks
Delene
0
Comment
Question by:Delene_Heukelman
  • 3
  • 2
6 Comments
 
LVL 12

Expert Comment

by:esoftbg
ID: 12039333
Something like that ?

procedure Draw_Canvas_Line(Canvas: TCanvas; P1, P2: TPoint; Cl: TColor);
var
  P0:     TPoint;
  IX:     Integer;
  IY:     Integer;
  DX:     Integer;
  DY:     Integer;
  T:      Extended;
begin
  DX := P2.X - P1.X;
  DY := P2.Y - P1.Y;
  if (DX=0) then
  begin
    Canvas.Pen.Color := Cl;
    if (P1.Y<P2.Y) then
    begin
      for IY := P1.Y to P2.Y-1 do
      begin
        Canvas.MoveTo(P1.X, IY);
        Canvas.LineTo(P1.X, IY+1);
        Sleep(100);
        Application.ProcessMessages;
      end;
    end
    else
    begin
      for IY := P1.Y downto P2.Y-1 do
      begin
        Canvas.MoveTo(P1.X, IY);
        Canvas.LineTo(P1.X, IY-1);
        Sleep(100);
        Application.ProcessMessages;
      end;
    end
  end
  else
  if (DY=0) then
  begin
    Canvas.Pen.Color := Cl;
    if (P1.X<P2.X) then
    begin
      for IX := P1.X to P2.X-1 do
      begin
        Canvas.MoveTo(IX, P1.Y);
        Canvas.LineTo(IX+1, P1.Y);
        Sleep(100);
        Application.ProcessMessages;
      end;
    end
    else
    begin
      for IX := P1.X downto P2.X-1 do
      begin
        Canvas.MoveTo(IX, P1.Y);
        Canvas.LineTo(IX-1, P1.Y);
        Sleep(100);
        Application.ProcessMessages;
      end;
    end
  end
  else
  begin
    T := DY / DX;
    Canvas.Pen.Color := Cl;
    if (DX>=DY) then
    begin
      if (P1.X<P2.X) then
      begin
        for IX := P1.X to P2.X {-1} do
        begin
          P0.X := IX;
          P0.Y := P1.Y + Round((IX - P1.X) * T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          Sleep(100);
          Application.ProcessMessages;
        end;
      end
      else
      begin
        for IX := P1.X downto P2.X {-1} do
        begin
          P0.X := IX;
          P0.Y := P1.Y + Round((IX - P1.X) * T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          Sleep(100);
          Application.ProcessMessages;
        end;
      end;
    end
    else
    begin
      if (P1.Y<P2.Y) then
      begin
        for IY := P1.Y to P2.Y {-1} do
        begin
          P0.Y := IY;
          P0.X := P1.X + Round((IY - P1.Y) / T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          Sleep(100);
          Application.ProcessMessages;
        end;
      end
      else
      begin
        for IY := P1.Y downto P2.Y {-1} do
        begin
          P0.Y := IY;
          P0.X := P1.X + Round((IY - P1.Y) / T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          Sleep(100);
          Application.ProcessMessages;
        end;
      end;
    end;
  end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  Draw_Canvas_Line(Img.Canvas, Point(8,8), Point(48,120), clBlack);
  Draw_Canvas_Line(Img.Canvas, Point(48,120), Point(112,96), clBlack);
  Draw_Canvas_Line(Img.Canvas, Point(112,96), Point(120,8), clBlack);
  Draw_Canvas_Line(Img.Canvas, Point(120,8), Point(8,8), clBlack);
end;
0
 
LVL 12

Expert Comment

by:esoftbg
ID: 12039672
download a super example from:
page:        http://www.geocities.com/esoftbg/
  link:        Q_21127913.zip

//........

procedure Draw_Canvas_Line(Canvas: TCanvas; P1, P2: TPoint; Cl: TColor; PT: TPoint; Wait: Integer);
var
  P0:     TPoint;
  IX:     Integer;
  IY:     Integer;
  DX:     Integer;
  DY:     Integer;
  T:      Extended;
begin
  DX := P2.X - P1.X;
  DY := P2.Y - P1.Y;
  if (DX=0) then
  begin
    Canvas.Pen.Color := Cl;
    if (P1.Y<P2.Y) then
    begin
      for IY := P1.Y to P2.Y-1 do
      begin
        Canvas.MoveTo(P1.X, IY);
        Canvas.LineTo(P1.X, IY+1);
        SetCursorPos(PT.X + P1.X, PT.Y + IY+1);
        Sleep(Wait);
        Application.ProcessMessages;
      end;
    end
    else
    begin
      for IY := P1.Y downto P2.Y+1 do
      begin
        Canvas.MoveTo(P1.X, IY);
        Canvas.LineTo(P1.X, IY-1);
        SetCursorPos(PT.X + P1.X, PT.Y + IY-1);
        Sleep(Wait);
        Application.ProcessMessages;
      end;
    end
  end
  else
  if (DY=0) then
  begin
    Canvas.Pen.Color := Cl;
    if (P1.X<P2.X) then
    begin
      for IX := P1.X to P2.X-1 do
      begin
        Canvas.MoveTo(IX, P1.Y);
        Canvas.LineTo(IX+1, P1.Y);
        SetCursorPos(PT.X + IX+1, PT.Y + P1.Y);
        Sleep(Wait);
        Application.ProcessMessages;
      end;
    end
    else
    begin
      for IX := P1.X downto P2.X+1 do
      begin
        Canvas.MoveTo(IX, P1.Y);
        Canvas.LineTo(IX-1, P1.Y);
        SetCursorPos(PT.X + IX-1, PT.Y + P1.Y);
        Sleep(Wait);
        Application.ProcessMessages;
      end;
    end
  end
  else
  begin
    T := DY / DX;
    Canvas.Pen.Color := Cl;
    if (DX>=DY) then
    begin
      if (P1.X<P2.X) then
      begin
        for IX := P1.X to P2.X {-1} do
        begin
          P0.X := IX;
          P0.Y := P1.Y + Round((IX - P1.X) * T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          SetCursorPos(PT.X + P0.X, PT.Y + P0.Y);
          Sleep(Wait);
          Application.ProcessMessages;
        end;
      end
      else
      begin
        for IX := P1.X downto P2.X {-1} do
        begin
          P0.X := IX;
          P0.Y := P1.Y + Round((IX - P1.X) * T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          SetCursorPos(PT.X + P0.X, PT.Y + P0.Y);
          Sleep(Wait);
          Application.ProcessMessages;
        end;
      end;
    end
    else
    begin
      if (P1.Y<P2.Y) then
      begin
        for IY := P1.Y to P2.Y {-1} do
        begin
          P0.Y := IY;
          P0.X := P1.X + Round((IY - P1.Y) / T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          SetCursorPos(PT.X + P0.X, PT.Y + P0.Y);
          Sleep(Wait);
          Application.ProcessMessages;
        end;
      end
      else
      begin
        for IY := P1.Y downto P2.Y {-1} do
        begin
          P0.Y := IY;
          P0.X := P1.X + Round((IY - P1.Y) / T);
          Canvas.MoveTo(P1.X, P1.Y);
          Canvas.LineTo(P0.X, P0.Y);
          SetCursorPos(PT.X + P0.X, PT.Y + P0.Y);
          Sleep(Wait);
          Application.ProcessMessages;
        end;
      end;
    end;
  end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  PT:     TPoint;
begin
  PT := Form1.Img.ClientToScreen(Point(0, 0));
  Draw_Canvas_Line(Img.Canvas, Point(8,8), Point(8,120), clBlack, PT, 48);
  Draw_Canvas_Line(Img.Canvas, Point(8,120), Point(112,96), clBlack, PT, 48);
  Draw_Canvas_Line(Img.Canvas, Point(112,96), Point(120,8), clBlack, PT, 128);
  Draw_Canvas_Line(Img.Canvas, Point(120,8), Point(8,8), clBlack, PT, 48);
end;
0
 

Author Comment

by:Delene_Heukelman
ID: 12047032
No, possibly I did not explain it very well, or I am too inexperienced. I need the mouse coordinates captured to an array while the drawing of the line takes place. The user sees the line that is moving left over the screen, and tries to follow it with the mouse. I want to be able to compare the actual line and the path the mouse followed, so both must be in an array.

I tried to interrupt the line drawing procedure after each section of the stepped line is drawn, with the timer enabled, to capture the onmousemove coordinates and return to the drawing procedure, but when I disable the timer only the last coordinates are available. It seems to destroy the values of the variables when terminated.

I used a global array to save the mouse coordinates in, and still when the timer is disabled, the array does not contain the mousevalues displayed from the array while the timer is enabled. How do I keep the array values after the timer is disabled?
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 33

Assisted Solution

by:Slick812
Slick812 earned 500 total points
ID: 12047319
I think the system timer messages are never delivered, as I understand it, there is never more than ONE timer message in the thread's message queue, so you only get a single position point, , you are probally doing your line Drawing in a loop without a Allpication ProcessMessages being called, you might consider moving your line drawing calls to the same Timer procedure that your GetCursorPos( )  is in. . . .  or add a Allplication ProcessMessages to your loop or show some of your code
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 500 total points
ID: 12057472
I can not get much information here about How you are coding or the methods you may use, here is some simple stright line draw in a timer (no line steps, not sure what your steps are), which records the line draw points and the Cursor position points. . . .


type
  T2Points = record
    DrawPnt, MousePnt: TPoint;
    end;

  TForm2 = class(TForm)



var
  Form2: TForm2;

implementation

uses Math;



procedure TForm2.but_DrawLineClick(Sender: TObject);
begin
// this button click starts the Line draw
DrawNum := 0;
setLength(aryPoints,0);
Timer1.Interval := 100;
Timer1.Enabled := True;
end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
setLength(aryPoints, Length(aryPoints)+1);
// Draws line on Form Canvas
Canvas.MoveTo(DrawNum *10, 50);
Canvas.LineTo((DrawNum+1)* 10, 50);
aryPoints[High(aryPoints)].DrawPnt.x := (DrawNum+1)* 10;
aryPoints[High(aryPoints)].DrawPnt.y := 50;
// add Cursor Position to array
GetCursorPos(aryPoints[High(aryPoints)].MousePnt);
windows.ScreenToClient(Handle, aryPoints[High(aryPoints)].MousePnt);
Inc(DrawNum);
if DrawNum = 44 then Timer1.Enabled := False;
// draws 44 line segments
end;

procedure TForm2.but_TestArrayPntsClick(Sender: TObject);
var
i, Hits: Integer;
begin
// this button click will test the array of points for a "Close" mouse position
if Length(aryPoints) = 0 then Exit;
Hits := 0;
// test the distance from the DrawPnt to the MousePnt. if less than 11 then hit
for i := 0 to High(aryPoints) do
if Round(Sqrt(SumOfSquares([abs(aryPoints[i].DrawPnt.y-aryPoints[i].MousePnt.y),
         abs(aryPoints[i].DrawPnt.x-aryPoints[i].MousePnt.x)]))) < 11 then
  Inc(Hits);
ShowMessage('Number of Hits is  '+IntToStr(Hits));
end;

 = = = = = = = = = = = = = = = = = =  = = =
ask questions if you need more info
0
 
LVL 33

Expert Comment

by:Slick812
ID: 12057503
I forgot this




  private
    { Private declarations }
    DrawNum: Integer;
    aryPoints: Array of T2Points;
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now