MFC分割窗口的实现

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. 运行效果图如下所示

你可能感兴趣的:(mfc,分割窗口,切分窗口)