1. 新建一个单文档的MFC工程(不使用文档/视图结构), 删除自带的CChileView类及相关文件和代码。
2. 新建两个对话框,用于分割窗口,对话框的Style属性改为Child, Border属性改为None,最开始没有改这个,程序运行的时候报错了。然后将两个对话框生成从CFormView派生的类。
3. 新建C++类,类名CMySplitterWnd, 基类为CSplitterWndEx(使用新建MFC类不能设置基类为CSplitterWndEx)。
4. 在CMainFrame中添加三个成员变量,如下所示
CMySplitterWnd m_wndSplitter;
CLeftView * m_pLeftView; // IDD_DLG_LEFT
CRightView * m_pRightView; // IDD_DLG_RIGHT
添加虚函数virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);
程序代码修改部分如下:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类
CRect rect;
GetClientRect(&rect);
if (!m_wndSplitter.CreateStatic(this, 1, 2))
{
TRACE0("Failed to CreateStaticSplitter\n");
return FALSE;
}
// add the first splitter pane - the default view in column 0
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CLeftView),
CSize(240, rect.bottom), pContext))
{
TRACE0("Failed to create first pane\n");
return FALSE;
}
// add the second splitter pane - an input view in column 1
if (!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CRightView),
CSize(rect.right, rect.bottom - 350), pContext))
{
TRACE0("Failed to create second pane\n");
return FALSE;
}
m_pLeftView = (CLeftView *)m_wndSplitter.GetPane(0, 0);
m_pRightView = (CRightView *)m_wndSplitter.GetPane(0, 1);
return CFrameWnd::OnCreateClient(lpcs, pContext);
}
5. 有时候,需要保持分割窗口中每个小窗口的尺寸或者比例,不允许用户拖动分割条。我考虑了有两种方法可以实现。效果如下,鼠标在分割条上,没有出现可以改变大小的箭头。
方法1:
== == == == == == == == == == == == == == == == == == == == == == == ==
//CMySplitter.h
#pragma once
#include "stdafx.h"
class CMySplitter :public CSplitterWnd
{
DECLARE_DYNAMIC(CMySplitter)
public:
DECLARE_MESSAGE_MAP()
protected:
//重载进行非客户区鼠标测试函数
afx_msg UINT OnNcHitTest(CPoint point);
};
== == == == == == == == == == == == == == == == == == == == == == == ==
//CMySplitter.cpp
#include "Cmysplitter.h"
IMPLEMENT_DYNAMIC(CMySplitter, CSplitterWnd)
BEGIN_MESSAGE_MAP(CMySplitter, CSplitterWnd)
ON_WM_NCHITTEST()
END_MESSAGE_MAP()
UINT CMySplitter::OnNcHitTest(CPoint point)
{
//返回HTNOWHERE...
return HTNOWHERE;
}
== == == == == == == == == == == == == == == == == == == == == == == ==
方法2:
== == == == == == == == == == == == == == == == == == == == == == == ==
//CMySplitter.h
#pragma once
#include "stdafx.h"
class CMySplitter : public CSplitterWnd
{
DECLARE_DYNCREATE(CMySplitter)
protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
DECLARE_MESSAGE_MAP()
};
== == == == == == == == == == == == == == == == == == == == == == == ==
//CMySplitter.cpp
#include "CMySplitter.h"
IMPLEMENT_DYNCREATE(CMySplitter, CSplitterWnd)
BEGIN_MESSAGE_MAP(CMySplitter, CSplitterWnd)
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
void CMySplitter::OnLButtonDown(UINT nFlags, CPoint point)
{
// 直接返回
return;
}
BOOL CMySplitter::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// 当光标进入分割窗口时,不允许改变样子
return FALSE;
}
void CMySplitter::OnMouseMove(UINT nFlags, CPoint point)
{
//跳过调用CSplitterWnd::OnMouseMove,因为他会引起光标的改变
CWnd::OnMouseMove(nFlags, point);
}
6. 运行效果图如下所示