在开发图形用户界面(GUI)时,分割器控件是一种常见的组件,它允许用户通过拖动来调整窗口的布局。尽管许多开发环境提供了内置的分割器控件,但有时可能需要一个更符合特定需求的自定义版本。本文将介绍如何在Visual C++ (VC++)中创建一个简单的自定义分割器控件,并展示如何将其集成到对话框中。
首先,需要添加两个文件到项目中:
然后,在将要使用分割器控件的类的头文件中包含以下指令:
#include "splittercontrol.h"
接下来,在对话框类中添加成员变量:
protected:
CSplitterControl m_wndSplitter1;
通过调用创建函数来创建控件,这段代码应该出现在OnInitDialog或OnCreate函数中:
BOOL CSPDemoDlg::OnInitDialog()
{
...
pWnd = GetDlgItem(IDC_SPLITTER1);
pWnd->GetWindowRect(rc);
ScreenToClient(rc);
m_wndSplitter1.Create(WS_CHILD | WS_VISIBLE, rc, this, IDC_SPLITTER1);
m_wndSplitter1.SetRange(50, 50, -1);
...
}
这里有一个小技巧:不需要计算分割器的矩形区域,而是在对话框上添加一个静态控件(通过资源编辑器),给它一个ID(IDC_SPLITTER1),并将其设置为不可见。在资源编辑器中调整其大小和位置,然后调用GetWindowRect(rc)函数来移动m_wndSplitter1到rect。
以下是当用户移动分割器控件时,对话框上的控件调整大小的代码:
LRESULT CSPDemoDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_NOTIFY)
{
if (wParam == IDC_SPLITTER1)
{
SPC_NMHDR* pHdr = (SPC_NMHDR*) lParam;
DoResize1(pHdr->delta);
}
}
return CDialog::DefWindowProc(message, wParam, lParam);
}
void CSPDemoDlg::DoResize1(int delta)
{
// Change the width for m_wndType, m_lstItem, m_txtContent
CSplitterControl::ChangeWidth(&m_wndType, delta);
CSplitterControl::ChangeWidth(&m_lstItem, -delta, CW_RIGHTALIGN);
CSplitterControl::ChangeWidth(&m_txtContent, -delta, CW_RIGHTALIGN);
Invalidate();
UpdateWindow();
}
这段代码监听WM_NOTIFY消息,当分割器控件被移动时,它会调用DoResize1函数来调整相关控件的宽度。
下面是CSplitterControl类的定义:
class CSplitterControl : public CStatic
{
// Construction
public:
CSplitterControl();
// Attributes
protected:
BOOL m_bIsPressed;
int m_nType;
int m_nX, m_nY;
int m_nMin, m_nMax;
int m_nSavePos;
// Save point on the lbutton down
public:
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSplitterControl)
//}}AFX_VIRTUAL
// Implementation
public:
static void ChangePos(CWnd* pWnd, int dx, int dy);
static void ChangeWidth(CWnd* pWnd, int dx, DWORD dwFlag = CW_LEFTALIGN);
static void ChangeHeight(CWnd* pWnd, int dy, DWORD dwFlag = CW_TOPALIGN);
public:
void SetRange(int nMin, int nMax);
void SetRange(int nSubtraction, int nAddition, int nRoot);
int GetStyle();
int SetStyle(int nStyle = SPS_VERTICAL);
void Create(DWORD dwStyle, const CRect& rect, CWnd* pParent, UINT nID);
virtual ~CSplitterControl();
// Generated message map functions
protected:
virtual void DrawLine(CDC* pDC, int x, int y);
void MoveWindowTo(CPoint pt);
//{{AFX_MSG(CSplitterControl)
afx_msg void OnPaint();
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
这个类提供了创建分割器控件所需的基本方法和属性。