Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Hi,

Is there anyone out there who know if it's possible to draw a line on the "canvas" and have it reacting on mouseclick.

Example of the setup is I have five buttons on the form and connect them with lines.

I then want to be able to click on the line and get information on for instance the X and Y points of the endpoints.

If it's possible i also want to assign a "name" to this line to be able to sort wich line is selected if I have for instance 15 lines in a star pattern.

Hoping for this as I have tried myself and failed..

Is there anyone out there who know if it's possible to draw a line on the "canvas" and have it reacting on mouseclick.

Example of the setup is I have five buttons on the form and connect them with lines.

I then want to be able to click on the line and get information on for instance the X and Y points of the endpoints.

If it's possible i also want to assign a "name" to this line to be able to sort wich line is selected if I have for instance 15 lines in a star pattern.

Hoping for this as I have tried myself and failed..

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

here is sample unit. It generates 10 random lines. All lines drawn in OnPaint method.

Moving the mouse (OnMouseMove) over the one of line you can see how cursor changed to crHandPoint.

Clickin on line (OnMouseDown) you can change it's "Selected" property.

Be sure you include "Contnrs" unit in your uses clause.

Enjoy :-)

------

Igor.

unit Unit1;

interface

uses

Windows, Classes, Graphics, Controls, Forms,

Contnrs;

type

TLine = class(TObject)

A: TPoint;

B: TPoint;

Selected: Boolean;

end;

TForm1 = class(TForm)

procedure FormPaint(Sender: TObject);

procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure FormCreate(Sender: TObject);

procedure FormMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

private

public

Lines: TObjectList;

end;

var

Form1: TForm1;

implementation

{$R *.DFM}

// check that point P lie on line with coordinates X1.Y1 - X2.Y2

// Delta - possible distance from the line's point

function PointOnLine(X1,Y1, X2,Y2: Integer; P: TPoint; Delta: Integer): Boolean;

var

Step: Real;

R: TRect;

N: Integer;

Z: Real;

begin

Result := False;

if (Abs(X2-X1) > Abs(Y2-Y1)) and (X2-X1 <> 0) then

begin

Step := (Y2- Y1)/abs((X2 - X1));

if X2 > X1 then N := 1 else N := -1;

Z := Y1;

while X1 <> X2 do

begin

SetRect(R, X1, Round(Z), X1, Round(Z));

InflateRect(R, Delta, Delta);

if PtInRect(R, P) then

begin

Result := True;

Break;

end;

Z := Z + Step;

X1 := X1 + N;

end;

end

else

if Y2 - Y1 <> 0 then

begin

Step := (X2 - X1)/abs((Y2 - Y1));

if Y2 > Y1 then N := 1 else N := -1;

Z := X1;

while Y1 <> Y2 do

begin

SetRect(R, Round(Z), Y1, Round(Z), Y1);

InflateRect(R, Delta, Delta);

if PtInRect(R, P) then

begin

Result := True;

Break;

end;

Z := Z + Step;

Y1 := Y1 + N;

end;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

var

I: Integer;

L: TLine;

begin

Randomize;

Lines := TObjectList.Create(true);

// create 10 random lines

for I := 1 to 10 do

begin

L := TLine.Create;

L.A.X := Random(Width);

L.B.X := Random(Width);

L.A.Y := Random(Height);

L.B.Y := Random(Height);

Lines.Add(L);

end;

end;

procedure TForm1.FormPaint(Sender: TObject);

var

I: Integer;

L: TLine;

begin

// draw generated lines

with Form1.Canvas do

for I := 0 to Lines.Count - 1 do

begin

L := TLine(Lines[I]);

if L.Selected then

Pen.Color := clRed

else

Pen.Color := clBlack;

MoveTo(L.A.X, L.A.Y);

LineTo(L.B.X, L.B.Y);

end;

end;

procedure TForm1.FormMouseMove(Sende

Y: Integer);

var

P: TPoint;

I: Integer;

L: TLine;

begin

P.X := X;

P.Y := Y;

Cursor := crDefault;

// detect when mouse over the one of line

for I := 0 to Lines.Count - 1 do

begin

L := TLine(Lines[I]);

if PointOnLine(L.A.X, L.A.Y, L.B.X, L.B.Y, P, 3) then

Cursor := crHandPoint;

end;

end;

procedure TForm1.FormMouseDown(Sende

Shift: TShiftState; X, Y: Integer);

var

P: TPoint;

I: Integer;

L: TLine;

begin

P.X := X;

P.Y := Y;

// select deselect line when mouse clicked on it

for I := 0 to Lines.Count - 1 do

begin

L := TLine(Lines[I]);

if PointOnLine(L.A.X, L.A.Y, L.B.X, L.B.Y, P, 3) then

begin

L.Selected := not L.Selected;

Invalidate;

end;

end;

end;

procedure TForm1.FormDestroy(Sender:

begin

Lines.Free;

end;

end.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trialJust another way:

DrawLine adds a line to a StringList with coordinates and name. Label1 shows current line name and coordinates(OnMouseMove).

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

StdCtrls;

type

TForm1 = class(TForm)

Label1: TLabel;

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,

Y: Integer);

procedure FormPaint(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

LineList : TStringList;

implementation

{$R *.DFM}

const

Sensitivity = 50;

function Min(X1,X2: integer): integer;

begin

if X1 <= X2 then result := X1

else result := X2;

end;

function Max(X1,X2: integer): integer;

begin

if X1 >= X2 then result := X1

else result := X2;

end;

procedure DrawLine(X1,Y1,X2,Y2: integer; Name: string);

begin

with Form1.Canvas do begin

MoveTo(X1,Y1);

LineTo(X2,Y2);

end;

LineList.Add(Format('%.4d'

end;

function OverLine(X,Y: integer): integer;

var

X1,Y1,X2,Y2: integer;

i: integer;

begin

result := -1;

for i := 0 to LineList.Count - 1 do begin

X1 := StrToInt(Copy(LineList[i],

Y1 := StrToInt(Copy(LineList[i],

X2 := StrToInt(Copy(LineList[i],

Y2 := StrToInt(Copy(LineList[i],

if (Y-Y1 <> 0) and (Y-Y1 <> 0) and (X-X2 <> 0) and (X1-X2 <> 0) then begin

if (X >= Min(X1,X2)) and (X <= Max(X1,X2)) and (Y >= Min(Y1,Y2)) and (Y <= Max(Y1,Y2)) then begin

if (Round(((X - X1)/(Y - Y1))*Sensitivity) = Round(((X2 - X1)/(Y2 - Y1))*Sensitivity)) or

(Round(((Y - Y2)/(X - X2))*Sensitivity) = Round(((Y1 - Y2)/(X1 - X2))*Sensitivity)) then begin

result := i;

exit;

end;

end;

end;

end;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

LineList := TStringList.Create;

end;

procedure TForm1.FormDestroy(Sender:

begin

LineList.Free;

end;

procedure TForm1.FormPaint(Sender: TObject);

begin

DrawLine(5,200,100,5,'Line

DrawLine(5,5,100,200,'Line

end;

procedure TForm1.FormMouseMove(Sende

Y: Integer);

var

i: integer;

s: string;

begin

i := OverLine(X,Y);

if i > -1 then begin

s := LineList[i];

Label1.Caption := Copy(s,17,Length(s) - 16) + ' ' +

Copy(s,1,4) + ',' + Copy(s,5,4) + ',' +

Copy(s,9,4) + ',' + Copy(s,13,4);

end else Label1.Caption := '';

end;

end.

Regards, Geo

By now you know how to draw a line on a canvas.

A method to get where you are going would be to use the MoveTo and LineTo methods of the TCanvas Class.

But prior to using this make up coordinates that you may store in an array( ICoordinates : Array[0..10] of Integer;)

this will help you keep track of the starting and ending points of the line.

On your mouse down method you may track the mouse coordinates and compare them to the points in the array.

Facts:

You draw the lines so you know ICoordinates[0] = x Mouse coordinate of the first line, etc

So knowing the order of the lines and the order of the coordinates, the index of the array can work as a tag value of any control.

Good Luck Manata

I have been sick for a few days and haven't been able too check the answers yet.

I will try to see if and how to use what you have written and I come back with more questions if I don't understand something.

//Ulf

Delphi

From novice to tech pro — start learning today.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with Premium.
Start your 7-day free trial.

use tshape(s)