Click here to Skip to main content
15,888,316 members
Articles / Desktop Programming / MFC
Article

LineTracker: A CRectTracker-like Class for Lines

Rate me:
Please Sign up or sign in to vote.
4.77/5 (13 votes)
9 Apr 2002CPOL1 min read 132.7K   3.7K   64   16
This class will track lines like CRectTracker tracks rects
Image 1

Introduction

While working on a recent project, I noticed that Microsoft doesn't provide any kind of class to track line-based objects. I took a peek at the CRectTracker class and then I wrote my own class that is similar to CRectTracker.

The implementation is very much like CRectTracker and most of the function names are the same. I only need to track a single line in my project, so I didn't add support for multiple lines to be tracked at once. Although I didn't add multiple line support, there are a few variables and functions that are the beginnings of adding this functionality

Ok, now let's get on to the part you've been waiting for. I have encapsulated a lot of logic for the OnLButtonDown() handler inside my class. Let's take a look at the OnLButtonDown() hander from the demo application:

C++
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{

    // Let CLineTracker do its thing
    if (!m_pLineTracker->OnLButtonDown(this, nFlags, point, &m_LineList)) 
    {

        // If not lines were hit then start a local CLineTracker 
        // to rubber band a new line
        CLineTracker tracker;

        if (tracker.TrackRubberLine(this, point)) 
        {

            // Make sure we have a line that is long enough
            if ((abs(tracker.m_points.Width()) > 20) || 
                (abs(tracker.m_points.Height()) > 20)) 
            { 

                // Add the line to our (very simple) linked list
                CLineItem* pLine = new CLineItem();

                pLine->m_rcPoints.SetRect(tracker.m_points.left,
                    tracker.m_points.top, tracker.m_points.right,
                    tracker.m_points.bottom);
                m_LineList.Add(pLine);

            }

        }

    }

    Invalidate();

    CWnd::OnLButtonDown(nFlags, point);
}

The one parameter that may need to be explained is &m_LineList. This is a pointer to a simple linked list of lines. See the classes CLineList and CLineItem in the demo project. CLineTracker's OnLButtonDown() function scans through the linked list to see if any lines are selected, moved, or have their "handles" tracked.

To make sure that the mouse cursor is changed to reflect the tracking operation status, you need to add some code to your OnSetCursor() message handler. Here's the OnSetCursor() handler from the demo application:

C++
BOOL CChildView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
    // Make sure the line tracker gets a chance to change the cursor
    if (m_pLineTracker->SetCursor(pWnd, nHitTest))
        return TRUE;

    return CWnd::OnSetCursor(pWnd, nHitTest, message);
}

Now we need to make sure that CLineTracker's "handles" are drawn. In the demo application, the OnPaint() handler takes care of this. Here's the demo applications's OnPaint() code:

C++
void CChildView::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    
    // Draw the lines (arrows)
    CLineItem* pLine;

    pLine = m_LineList.GetFirst();

    CPoint ptStart;
    CPoint ptEnd;

    while(pLine) 
    {

        ptStart.x = pLine->m_rcPoints.left;
        ptStart.y = pLine->m_rcPoints.top;

        ptEnd.x = pLine->m_rcPoints.right;
        ptEnd.y = pLine->m_rcPoints.bottom;

        DrawArrow(&dc, ptStart, ptEnd);

        pLine = pLine->m_pNext;
    }
    
    // Give the tracker a chance to draw itself
    m_pLineTracker->Draw(&dc);

    // Do not call CWnd::OnPaint() for painting messages
}

This is my first-ever source code submission and I hope this class provides some useful ideas to some of you fellow developers out there.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I started learning C and 68K assembly language on an Atari ST around 1985 or so using the Mark Williams compiler. I was instantly hooked.

My favorite languages are: C/C++, C#, Ruby, and Python.

My first PC clone was a 386SX-25MHz with 4MB of RAM. OMG | :OMG:

Comments and Discussions

 
QuestionHow can I serialize this class ? Pin
mesajflaviu9-Jul-10 4:47
mesajflaviu9-Jul-10 4:47 
Generalyour class in VC6++ by MFC library Pin
thanhvu8-Oct-05 16:33
thanhvu8-Oct-05 16:33 
GeneralConvert DevicePoint To Logical Point Pin
rdfcode27-Apr-05 11:15
rdfcode27-Apr-05 11:15 
QuestionHow is line erased Pin
Anonymous1-Mar-04 1:47
Anonymous1-Mar-04 1:47 
Generalawesome Pin
nonocast23-Dec-03 21:43
nonocast23-Dec-03 21:43 
GeneralRe: awesome Pin
Dana Holt24-Dec-03 4:37
Dana Holt24-Dec-03 4:37 
When I created the class my needs were pretty simple. It's meant to be a base to build on, just a concept of how this problem could be approached.

--
Dana Holt
Xenos Software LLC
GeneralError In Compilation Pin
AhmedOsamaMoh19-Nov-03 2:05
AhmedOsamaMoh19-Nov-03 2:05 
QuestionHow To Use It In CSrollView Pin
15-Nov-03 5:00
suss15-Nov-03 5:00 
GeneralReally cool, thanks... Pin
Brendan Tregear28-Aug-03 17:14
Brendan Tregear28-Aug-03 17:14 
GeneralRe: Really cool, thanks... Pin
Dana Holt24-Dec-03 4:40
Dana Holt24-Dec-03 4:40 
GeneralC# Counterpart Pin
coolshot14-Mar-03 14:07
coolshot14-Mar-03 14:07 
GeneralRe: C# Counterpart Pin
Dana Holt10-May-03 13:49
Dana Holt10-May-03 13:49 
GeneralCan't compile.... Pin
29-Apr-02 7:12
suss29-Apr-02 7:12 
GeneralRe: Can't compile.... Pin
Dana Holt30-Apr-02 1:15
Dana Holt30-Apr-02 1:15 
GeneralRe: Can't compile.... Pin
Skizmo29-Mar-05 4:06
Skizmo29-Mar-05 4:06 
GeneralRe: Can't compile.... Pin
xox_c0bra_xox14-Apr-10 10:43
xox_c0bra_xox14-Apr-10 10:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.