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

对话框的另一个分隔器控件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (64投票s)

2002年7月13日

2分钟阅读

viewsIcon

303219

downloadIcon

10810

一个非常简单的对话框分隔器控件。

Sample Image

引言

我是一名学生,对VC++非常感兴趣。我经常来这个网站获取免费的源代码。我需要一个对话框中的分割器。我下载了一个,但它非常复杂,我觉得这个控件很难使用(虽然它功能非常强大),所以我自己做了一个。也许它对你没用,但如果只有一个人觉得它有用,我会非常高兴的。有时候,你不需要高超的技能,只需要一个好的想法,用这种简单的方法,就能产生有用的代码。我的分割器控件就是这样。

如何使用CSplitterControl类

首先,将两个文件SplitterControl.hSplitterControl.cpp添加到项目中。记住在用到它的类的头文件中添加<tt> #include "splittercontrol.h"</tt>

在对话框类中添加成员变量

 protected: 
    CSplitterControl     m_wndSplitter1; 

现在,我们通过调用它的create函数来创建控件。这段代码将出现在OnInitDialogOnCreate函数中。

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

这里有一个技巧。与其计算分割器的矩形区域,不如在对话框中添加一个static控件(通过资源编辑器),给它一个ID(IDC_SPLITTER1)并使其不可见。在资源编辑器中调整其大小和位置,然后调用函数GetWindowRect(rc)m_wndSplitter1移动到该矩形区域。

以下是在用户移动分割器控件时调整对话框中控件大小的代码。

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

关于CSplitterControl类及其函数

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

// this struct is sent as lparam in WM_NOTIFY message 
typedef struct SPC_NMHDR
{
	NMHDR hdr;
	int delta;      // delta : the different position of the splitter before and 
                    // after being moved.
} SPC_NMHDR;

结论

好了,关于我的代码就到这里了。也许解释不够清楚,但我希望你会觉得它易于使用。你看,不需要什么特别的技能,非常简单。感谢阅读我的文章。请分享你对它的看法,喜欢还是不喜欢。

许可证

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

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

© . All rights reserved.