How do I recognize a mouse click on a line?

**Q:** How do I recognize a mouse click on a line?

**A:** Lines, once drawn, does not exist as a separate entity in Visual C++ applications, unlike CAD-like drawing applications. If you want to detect / select a line using mouse click, you will have to store the line details in the application and draw them on screen when it has to be displayed.

Easiest method to store a line is by storing its end points. I defined a convenient class **CLine** for this

Code:

*class CLine *

{

friend CDC& operator<<(CDC&, CLine&);

public:

POINT Pt[2];

CLine(POINT, POINT);

double Dist(POINT);

};

where the end points are declared as data member of *POINT* pair. The constructor stores the parameters as its end points:

Code:

*CLine::CLine(POINT start, POINT end)*

{

Pt[0] = start;

Pt[1] = end;

}

The function **Dist** returns the perpendicular distance from the point parameter to the line. The perpendicular distance is calculated using Analytical Geometry as

Code:

*double CLine::Dist(POINT pt)*

{

int DelX = Pt[1].x - Pt[0].x;

int DelY = Pt[1].y - Pt[0].y;

double D = sqrt(pow(DelX, 2) + pow(DelY, 2));

double Ratio = (double) ((pt.x - Pt[0].x) * DelX +

(pt.y - Pt[0].y) * DelY) / (DelX * DelX + DelY * DelY);

if (Ratio * (1 - Ratio) < 0)

return -1;

return (double) abs(DelX * (pt.y - Pt[0].y) - DelY * (pt.x - Pt[0].x)) / D;

}

Here, it is also calculated whether the foot of the perpendicular is within the bounds of the line also. If it is, actual value of perpendicular distance is returned. Otherwise, -1 is returned to indicate that the point is before the starting point or after the end point.

In the view, we can check whether the perpendicular distance from the mouse cursor point to the line is less than a pre-defined distance, in which case, you can say that the mouse is over the line. You can determine whether you are clicking on the line or not in your *OnLButtonUp* message handler function of *WM_LBUTTONUP* message.

Code:

*void CClickLineView::OnLButtonUp(UINT nFlags, CPoint point) *

{

// TODO: Add your message handler code here and/or call default

double D = pLine->Dist(point);

int Size = min(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR));

if (D >= 0 && D < Size / 10)

{

// Mouse is over the line

...

}

CView::OnLButtonUp(nFlags, point);

}