基于多选的控件跟踪器






4.81/5 (29投票s)
2001年12月20日
2分钟阅读

261329

7216
一个 CRectTracker 派生类,它可以做更多的事情
引言
在开发设计器和CAD相关应用程序时,通常需要移动和调整所选对象的功能。MFC运行时提供了一个类,即 CRectTracker
,它可以做类似的事情,但它有几个缺点,最重要的是它没有多对象选择和调整功能。本文介绍了一个类,CControlTracker
,它比CRectTracker
的功能更强大。
它继承自CRectTracker
,并且本质上与CRectTracker
具有相同的接口。CControlTracker
与另一个类CControlRect
紧密合作,后者继承自CRectTracker
和CWnd
。这意味着你可以使用CControlRect
创建任何控件(通过调用CWnd::Create
),并将其添加到CControlTracker
管理的控件列表中。然后,只需重写OnLButtonDown
和OnSetCursor
,就可以获得所有高级的移动/调整控件功能。
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();
...
};
如何使用它
在你的类中创建CControlTracker
和CControlRect
(控件)的实例。我已经在我的应用程序窗口类中创建了控件。
class CMainFrame : public CFrameWnd
{
CControlTracker m_ControlTracker;
CControlRect r1, r2;
...
};
重写OnLButtonDown
、OnSetCursor
、OnDraw
和OnCreate
。在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日:初始版本
许可证
本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。
作者可能使用的许可证列表可以在此处找到。