This article introduces a class, CControlTracker, that does much more than what CRectTracker does. We will take a look at the class design and also learn how to use the class.
Introduction
Often in developing designer and CAD related applications, one needs the functionality of moving and resizing selected objects around. MFC run-time provides one class, i.e., CRectTracker
that does something like this, but it has several shortcomings, the most important one being that it does not have functionality for multiple object selection and resizing. This article introduces a class, CControlTracker
, that does much more than what CRectTracker
does.
It inherits from CRectTracker
and essentially has the same interface as CRectTracker
. CControlTracker
works closely with another class CControlRect
, which inherits from CRectTracker
and CWnd
. This means that you can use CControlRect
to create any control (by calling CWnd::Create
) and add in the list of controls managed by CControlTracker
. Then by simply overriding OnLButtonDown
and OnSetCursor
, you can get all the advanced functionality of moving/resizing controls:
void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ControlTracker.Track( point , nFlags , true );
CFrameWnd::OnLButtonDown(nFlags, point);
}
BOOL CMainFrame::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if( m_ControlTracker.SetCursor( nHitTest, message ) )
return TRUE;
return CFrameWnd::OnSetCursor(pWnd, nHitTest, message);
}
Class Design
CControlRect
inherits from CWnd
, so you can pass CControlRect*
wherever CWnd*
is expected. It also inherits from CRectTracker
. This is to allow every Control to "Track" itself. You can safely create all controls including buttons, static and ListBox
controls and even activex controls, just as the way you would do with CWnd
.
class CControlRect : public CRectTracker , public CWnd {
public:
enum WindowType
{
enmScrollBar, enmStatic, enmButton,
enmEdit, enmListBox, enmComboBox
};
BOOL Create( WindowType wndType, ... );
BOOL Create( LPCTSTR lpszClassName, ... );
void Track( CWnd* pWnd, CPoint point,
BOOL bAllowInvert = FALSE,
CWnd* pWndClipTo = NULL );
void SetRect( int x1, int y1, int x2, int y2 );
void SetRect( const CRect & rect );
private:
BOOL m_bSelected;
UINT GetHandleMask() const;
void Initialize();
...
};
CControlTracker
manages all objects of CControlRect
class. It keeps an array of all controls added by a call to CControlTracker::Add
. It also keeps an array of currently selected objects. Handles are only drawn for selected objects.
class CControlTracker : public CRectTracker
{
public:
void Create( CWnd* pParentWnd );
void Add( CControlRect* pObject );
BOOL Track( const CPoint & point, UINT nFlags = 0,
BOOL bTrackRubberBand = TRUE );
BOOL SetCursor( UINT nHitTest, UINT message );
BOOL IsSelected( CControlRect* pObject ) const;
BOOL Select( CControlRect* pObject );
BOOL DeSelect( CControlRect* pObject );
BOOL Toggle( CControlRect* pObject );
void Draw( CDC* pDC ) const;
int DeSelectAll();
...
};
How to Use It
Create instances of CControlTracker
and CControlRect
(controls) in your class. I have created controls in my application window class:
class CMainFrame : public CFrameWnd
{
CControlTracker m_ControlTracker;
CControlRect r1, r2;
...
};
Override OnLButtonDown
, OnSetCursor
, OnDraw
and OnCreate
. In the OnCreate
member of the Parent
class, add the following code:
m_ControlTracker.Create( this );
r1.Create( CControlRect::enmStatic, "Static Text Control",
this , SS_CENTERIMAGE | SS_BITMAP, CRect( 10,10,70,70 ) );
r2.Create( CControlRect::enmEdit, "Button Control",
this, WS_DISABLED, CRect( 160,110,300,250 ) );
m_ControlTracker.Add( &r1 );
m_ControlTracker.Add( &r2 );
Future Work
In the near future, I would be working on incorporating LineTracker
functionality into this tracker. You would be able to make a cool UML editor with ease using this class. Please do let me know if you want to suggest any improvements in the design or functionality.
History
- 20th December, 2001: Initial version
License
This article has no explicit license attached to it, but may contain usage terms in the article text or the download files themselves. If in doubt, please contact the author via the discussion board below.
A list of licenses authors might use can be found here.