65.9K
CodeProject 正在变化。 阅读更多。
Home

基于多选的控件跟踪器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (29投票s)

2001年12月20日

2分钟阅读

viewsIcon

261329

downloadIcon

7216

一个 CRectTracker 派生类,它可以做更多的事情

引言

在开发设计器和CAD相关应用程序时,通常需要移动和调整所选对象的功能。MFC运行时提供了一个类,即 CRectTracker,它可以做类似的事情,但它有几个缺点,最重要的是它没有多对象选择和调整功能。本文介绍了一个类,CControlTracker,它比CRectTracker的功能更强大。

Control Tracker

它继承自CRectTracker,并且本质上与CRectTracker具有相同的接口。CControlTracker与另一个类CControlRect紧密合作,后者继承自CRectTrackerCWnd。这意味着你可以使用CControlRect创建任何控件(通过调用CWnd::Create),并将其添加到CControlTracker管理的控件列表中。然后,只需重写OnLButtonDownOnSetCursor,就可以获得所有高级的移动/调整控件功能。

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);
}

类设计

CControlRect继承自CWnd,因此你可以将CControlRect*传递到任何需要CWnd*的地方。它还继承自CRectTracker。这是为了允许每个控件“跟踪”自身。你可以安全地创建所有控件,包括按钮、静态文本框和ListBox控件,甚至ActiveX控件,就像使用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管理所有CControlRect类的对象。它维护一个通过调用CControlTracker::Add添加的所有控件的数组。它还维护一个当前所选对象的数组。只为选定的对象绘制句柄。

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();
...
};

如何使用它

在你的类中创建CControlTrackerCControlRect(控件)的实例。我已经在我的应用程序窗口类中创建了控件。

class CMainFrame : public CFrameWnd
{
	CControlTracker m_ControlTracker;
	CControlRect r1, r2;
	...
};

重写OnLButtonDownOnSetCursorOnDrawOnCreate。在Parent类的OnCreate成员中,添加以下代码

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

未来工作

在不久的将来,我将致力于将LineTracker功能整合到此跟踪器中。使用这个类,你可以轻松地创建一个很酷的UML编辑器。如果你想提出任何关于设计或功能的改进建议,请告诉我。

历史

  • 2001年12月20日:初始版本

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.