基于 MFC 对话框应用程序中的分隔条






4.63/5 (5投票s)
在基于 MFC 对话框的应用程序中使用按钮作为分隔条。
引言
这是我第一次在 CodeProject 上发表文章。 CodeProject 对我非常有帮助。我想通过提交自己的文章来回馈作者提供的帮助。
在 MFC 中,CSplitterWnd
通常用于 MDI 或 SDI。我只是认为分隔条控件就是可拖动的按钮。所以我决定实现一个名为 CControlSplitter
的类,它派生自 CButton
,以便像 CSplitterWnd
一样用于基于对话框的 MFC 应用程序。
背景
实现非常简单。只要你了解如何对 MFC 控件进行子类化,你就能理解它的工作原理并改进它。
使用代码
在您的项目中,包含以下文件
- ControlSplitter.h
- ControlSplitter.cpp
在你的对话框头文件中包含 ControlSplitter.h
#include "ControlSplitter.h"
使用普通的按钮控件在你的对话框中添加分隔条按钮,它将作为分隔条使用,并设置其控件 ID,例如 IDC_SPLITTER1
。
使用 MFC 类向导,在你的对话框中为添加的分隔条按钮添加控件成员变量,类型为 CControlSplitter
。
添加成员控件变量后,必须实现以下内容
- 在你的对话框头文件中声明控件分隔条
//{{AFX_DATA(CSplitterDlg) ... CControlSplitter m_splitter; ... //}}AFX_DATA
- 使用对话框的
DoDataExchange
中的DDX_Control
对控件进行子类化。void CSplitterDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSplitterDlg) ... DDX_Control(pDX, IDC_SPLITTER, m_splitter); ... //}}AFX_DATA_MAP }
在你的对话框的 OnInitDialog() 方法中设置你的分隔条
- [必需] 设置控件分隔条的类型
m_splitter.SetType(CControlSplitter::CS_VERT);
可用的类型有
CS_NONE
(默认值)、CS_VERT
和CS_HORZ
。public: typedef enum { CS_VERT = 1, CS_HORZ = 2, CS_NONE = 0 };
- 将同级控件添加到分隔条的控件列表中。
控件分隔条有两个控件列表
- 顶部控件列表(对于
CS_VERT
类型)或左侧控件列表(对于CS_HORZ
类型) - 底部控件列表(对于
CS_VERT
类型)或右侧控件列表(对于CS_HORZ
类型)
要添加控件的顶部控件列表或左侧控件列表,请使用
AddToTopOrLeftCtrls
方法。m_splitter.AddToTopOrLeftCtrls(IDOK);
要添加控件的底部控件列表或右侧控件列表,请使用
AddToBottomOrRightCtrls
方法。m_splitter.AddToBottomOrRightCtrls(IDC_EDIT1);
这是
AddToTopOrLeftCtrls
和AddToBottomOrRightCtrls
的声明void AddToBottomOrRightCtrls(UINT nCtrlId, WORD nFlags = SPF_TOP|SPF_LEFT|SPF_RIGHT|SPF_BOTTOM); void AddToTopOrLeftCtrls(UINT nCtrlId, WORD nFlags = SPF_TOP|SPF_LEFT|SPF_BOTTOM|SPF_RIGHT);
[注意:] 这两种方法都有额外的标志参数,可用于指定当控件分隔条被拖动时同级控件的行为。可能的值可以是以下各项的组合
/* distance of the control to the top of the window will be constant */ #define SPF_TOP 0x0010 /* distance of the control to the bottom of the window will be constant */ #define SPF_BOTTOM 0x0020 /* distance of the control to the left of the window will be constant */ #define SPF_LEFT 0x0040 /* distance of the control to the right of the window will be constant */ #define SPF_RIGHT 0x0080
- 顶部控件列表(对于
类工作方法
CControlSplitter();
这是构造函数。
void SetType(UINT nType);
这设置了控件分隔条的类型,可以是 CS_VERT
或 CS_HORZ
。
void AddToTopOrLeftCtrls(UINT nCtrlId, WORD nFlags);
这用于将控件添加到顶部或左侧控件列表中。
void AddToBottomOrRightCtrls(UINT nCtrlId, WORD nFlags);
这用于将控件添加到底部或右侧控件列表中。
void OnLButtonDown(UINT nFlags, CPoint point);
当用户在控件上按下鼠标左键时,将触发此事件。
void OnLButtonUp(UINT nFlags, CPoint point);
当用户在控件上释放鼠标左键时,将触发此事件。
void OnMouseMove(UINT nFlags, CPoint point);
当用户在控件上移动鼠标时,将触发此事件。
void OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
当系统请求光标时,将触发此事件。光标使用 SetClassLong(m_hWnd,GCL_HCURSOR,(LONG)m_hCursor);
设置。
类工作成员变量
//Holds the Type of the control splitter
unsigned int m_nType;
//Holds the Top or Left Control Listing
std::vector<DWORD> m_vtTopLeftControls;
//Holds the Bottom or Right Control Listing
std::vector<DWORD> m_vtBottomRightControls;
//Holds the POINT position used to calculate the movement changes
CPoint m_ptStartDrag,m_ptStartPos;
//Used to determine if user Starts to Drag, Dragging, and Ends Draging
bool m_bDragging;
//Used to hold the loaded HCURSOR
HCURSOR m_hCursor;
//Holds the bounds the splitter is allowed to be moved.
CRect m_rectMax;
//Holds the old control that is previously holdes cursor capture.
CWnd * m_pOldDragCapture;
历史
- 2011 年 7 月 15 日:首次发布。
- 2011 年 7 月 25 日:翻译了演示下载中的 Readme.txt。