Click here to Skip to main content
Click here to Skip to main content

A Multiple Selection based Control Tracker

, 19 Dec 2001
Rate this:
Please Sign up or sign in to vote.
A CRectTracker derived class that is able to do much more
<!-- Download Links -->

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.

Control Tracker

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:
// Controls enumerated in WindowType
	enum WindowType
	{
	enmScrollBar, enmStatic, enmButton, 
	enmEdit, enmListBox, enmComboBox
	};

// Can use enumerated type to create control
	BOOL Create( WindowType wndType, ... );
// Can also use class name to create control
	BOOL Create( LPCTSTR lpszClassName, ... );
// Tracks movement rectangle for control
	void Track( CWnd* pWnd, CPoint point, 
			BOOL bAllowInvert = FALSE, 
			CWnd* pWndClipTo = NULL );
// Sets bounding rectangle for control
	void SetRect( int x1, int y1, int x2, int y2 );
	void SetRect( const CRect & rect );
private:
// Tells weather the control is currently selected
	BOOL m_bSelected;
// Returns handle masks
	UINT GetHandleMask() const;
// Sets default attributes for CRectTracker
	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:
// Creates the Control Tracker Object
	void Create( CWnd* pParentWnd );
// Adds the Control to the Tracker
	void Add( CControlRect* pObject );
// Starts tracking all the controls
	BOOL Track( const CPoint & point, UINT nFlags = 0, 
				BOOL bTrackRubberBand = TRUE );
// Sets the cursor on all the controls
	BOOL SetCursor( UINT nHitTest, UINT message );
// Tells weather the specified control is selected or not
	BOOL IsSelected( CControlRect* pObject ) const;
// Selects the specified control
// Returns TRUE if it was initially unselected else FALSE
	BOOL Select( CControlRect* pObject );
// DeSelects the specified control.
// Returns TRUE if it was initially selected else FALSE
	BOOL DeSelect( CControlRect* pObject );
// Toggles the state of the object 
// Returns TRUE if control was selected, otherwise returns FALSE
	BOOL Toggle( CControlRect* pObject );
// Draws all the controls
	void Draw( CDC* pDC ) const;
// DeSelects all the controls
// Returns the number of controls that were selected
	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:
// Create ControlTracker
m_ControlTracker.Create( this );

// Create Controls
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 ) );

// Add controls in the tracking list of ControlTracker
	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 quite ease using this class. Please do let me know if you want to suggest any improvements in the design or functionality.

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

Share

About the Author

@deel@bbas
Web Developer
United States United States
No Biography provided

Comments and Discussions

 
QuestionHow to select my picture and stretch my picture PinmemberMember 1074064128-Apr-14 17:40 
Generalvery useful example! Pinmemberqusuo31-Jan-13 22:18 
QuestionAbout the license Pinmemberchris0050065-Apr-12 17:30 
Questiontrack custom control Pinmemberoldbishop16-Jan-12 10:52 
GeneralMy vote of 5 Pinmemberzhangyongf4-Aug-10 21:30 
QuestionThe number of control rectangles seems to be limited to 5 PinmemberJOHN117-Sep-09 8:22 
QuestionHow to delete a tracker control? Pinmemberimacess24-Sep-08 14:32 
QuestionC# code for Multiple selection based Control Tracker ????? Pinmembersouravgantait22-Jul-08 16:31 
GeneralCTrackerRect rotation Pinmemberduvaft7-Sep-04 21:43 
GeneralFreeHand Rotation Angle Pinmembersuyatchi19-Jun-04 0:11 
QuestionHow can I implement a rectangle tracker over a bitmap ? PinmemberGem28-Mar-04 22:14 
GeneralWM_LBUTTONUP is not being captured PinmemberBabak Asadi23-Apr-03 13:05 
GeneralRe: WM_LBUTTONUP is not being captured PinmemberBabak Asadi23-Apr-03 13:52 
GeneralRe: WM_LBUTTONUP is not being captured Pinmembersanskypotov17-Jun-03 23:16 
QuestionHow to delete a control? Pinmemberzhang_dq20-Apr-03 21:20 
General[Message Deleted] PinmemberHaresh Borse16-Apr-03 20:02 
GeneralRe: How to extend this functionality for user defined controls PinmemberHowardJones18-May-03 9:56 
GeneralRe: How to extend this functionality for user defined controls PinmemberNiko Tanghe20-Nov-03 0:36 
QuestionHow do I set the font for a static text control? PinmemberBabak Asadi16-Apr-03 15:15 
AnswerRe: How do I set the font for a static text control? PinmemberNitron16-Apr-03 15:54 
GeneralRe: How do I set the font for a static text control? PinmemberBabak Asadi16-Apr-03 19:13 
GeneralCRectTracker::GetHandleMask Pinmembernewbee31-Jan-03 7:43 
GeneralRe: CRectTracker::GetHandleMask Pinmember[ELNINO]8-Sep-03 5:27 
GeneralRe: CRectTracker::GetHandleMask Pinmembernewbee8-Sep-03 7:04 
GeneralCircular selection tool Pinmembernitashr31-Jan-03 3:41 

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

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

| Advertise | Privacy | Mobile
Web03 | 2.8.140821.2 | Last Updated 20 Dec 2001
Article Copyright 2001 by @deel@bbas
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid