MFC CSplitterWnd类分割窗口

本文详细介绍了MFC中CSplitterWnd类的使用方法,包括静态和动态分割窗口的创建过程,以及如何在分割窗口中创建窗格。通过具体的代码示例,展示了如何在CMainFrame类中嵌入CSplitterWnd成员变量,重载OnCreateClient成员函数,以及如何使用CreateStatic和Create函数来创建静态和动态的分割窗口。

1.了解功能

CSplitterWnd提供一个分隔器窗口的功能。窗格通常是应用程序特定的由CView派生的对象,但它也可以是具有适当子窗口ID的任何CWnd对象。一个CSplitterWnd对象通常被嵌入CFrameWnd或CMDIChildWnd父对象。一般创建CSplitterWnd对象流程

1.在父框架中嵌入一个CSplitterWnd成员变量。
2.重载父框架的CFrameWnd::OnCreateClient成员函数。
3.从重载的OnCreateClient函数中调用类CSplitterWnd的Create或CreateStatic成员函数。

分割有动静两种风格方式:

Create创建一个动态的分隔器窗口并将它与一个CSplitterWnd对象连接
CreateStatic创建一个静态的分隔器窗口并将它与一个CSplitterWnd对象连接
CreateView在一个分隔器窗口中创建一个窗格

2.静态分割

以单文档为例:

1)在CMainFrame类添加成员对象:CSplitterWnd m_wndSplitter;

2)找到OnCreateClient重载,OnCreateClient函数的调用在OnCreate函数之后,在构造视图对象和产生视图窗口之前。

这里讲下 virtual BOOL CreateView( int row, int col, CRuntimeClass* pViewClass, SIZE sizeInit, CCreateContext* pContext );函数,参数:

row指定用来放置新视的分隔器窗口行。
col指定用来放置新视的分隔器窗口列。
pViewClass指定新视的CRuntimeClass。
sizeInit指定新视的初始尺寸。
pContext指向用来创建此视的创建环境的指针(通常,该pContext被传递给在其中创建此分隔器窗口的父框架的重载的OnCreateClient成员函数)。

 pViewClass就是你分割窗口加入类

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)   
{   
    // TODO: Add your specialized code here and/or call the base class   
    CRect rc;   
  
    // 获取框架窗口客户区的CRect对象   
    GetClientRect(&rc);   
  
    // 创建静态分割窗口,两行一列   
    if (!m_wndSplitter.CreateStatic(this, 2, 1))   
        return FALSE;   
  
    // 创建上面窗格中的视图   
    if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CExample34View), CSize(rc.Width(), rc.Height()/2), pContext))   
        return FALSE;   
  
    // 创建下面窗格中的视图   
    if (!m_wndSplitter.CreateView(1, 0, RUNTIME_CLASS(CExample34View), CSize(rc.Width(), rc.Height()/2), pContext))   
        return FALSE;   
  
    return TRUE;   
  
    //return CFrameWndEx::OnCreateClient(lpcs, pContext);   
} 

3.动态切割窗口

1)同上

2)同上

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)   
{   
 // TODO: Add your specialized code here and/or call the base class   
 // 创建动态分割窗口,两行两列   
 return m_wndSplitter.Create(this,2, 2, CSize(10, 10), pContext);   
  
 //return CFrameWndEx::OnCreateClient(lpcs, pContext);   
}  

3). 在Resource View资源视图中,打开Menu下的IDR_MAINFRAME菜单,在View下添加一个菜单项,Caption设为Splitter Window,ID设为(一定要设为)ID_WINDOW_SPLIT。这样在运行结果界面中点击此菜单项时MFC会执行一些操作显示动态分割窗口。 

拓展:切割窗口后,对切割窗口1添加树控件一类操作(静态切割实例)

1.首先我们的哥窗口类的父类是CTreeView,这样的话就直接继承了父类特性,然后在OnInitialUpdate添加下面代码例子:

    HICON icon = AfxGetApp()->LoadIconW(IDI_ICON_RE);
	m_imageList.Create(30, 40, ILC_COLOR32, 1, 1);
	m_imageList.Add(icon);
	m_treeCtrl = &GetTreeCtrl();
	m_treeCtrl->SetImageList(&m_imageList, TVSIL_NORMAL);

	m_treeCtrl->InsertItem(_T("个人信息"), 0, 0, NULL);
	m_treeCtrl->InsertItem(_T("主页信息"), 0, 0, NULL);
	m_treeCtrl->InsertItem(_T("主详信息"), 0, 0, NULL);

就会出现树状结构图

2. 那切换树状图,切割窗口2跟着切换功能怎么弄?

思路:这么我们可以用PostMessage和ON_NOTIFY_REFLECT(用于反射消息的消息映射宏与用于常规通知的消息映射宏略有不同:它的常规名称后面附加了_REFLECT。例如,要在父级中处理WM_NOTIFY消息,可以在父级的消息映射中使用宏ON_NOTIFY。若要处理子控件中的反射消息,请在子控件的消息映射中使用ON_NOTIFY_REFLECT宏。在某些情况下,参数也不同。请注意,ClassWizard通常可以为您添加消息映射项,并为骨架函数实现提供正确的参数。)

获取树的节点然后PostMessage给主窗口,例如:

void CSelecView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
	LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;

	//获取当前节点
	HTREEITEM IT = m_treeCtrl->GetSelectedItem();

	CString str = m_treeCtrl->GetItemText(IT);

	if (str == TEXT("个人信息"))
	{
		::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WU_A, (WPARAM)WU_A, (LPARAM)0);
	}
	else if (str == TEXT("主页信息"))
	{
		::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), WU_B, (WPARAM)WU_B, (LPARAM)0);
	}

}

主窗口接受到消息 ,要自定义消息处理:

1)在.h添加自定义消息宏例如

#define WU_A	WM_USER+100	
#define WU_B	WM_USER+101	
#define WU_C	WM_USER+102	

.cpp添加自定义消息

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()

	//自定义消息
	ON_MESSAGE(WU_A, OnMyChange)
	ON_MESSAGE(WU_B, OnMyChange)
	ON_MESSAGE(WU_C, OnMyChange)
END_MESSAGE_MAP()

自定义消息处理:

LRESULT CMainFrame::OnMyChange(WPARAM wParam, LPARAM lParam)
{
	//CCreateContext没有基类。
	//在主程序创建框架窗口、以及文档相关的视图时,会使用CCreateContext结构。
	CCreateContext context;
	if (wParam== WU_B)
	{
		context.m_pNewViewClass = RUNTIME_CLASS(CTextDlg);
		context.m_pCurrentFrame = this;
		context.m_pLastView = (CFormView *)m_Spliter.GetPane(0, 1);
		m_Spliter.DeleteView(0, 1);
		m_Spliter.CreateView(0, 1, RUNTIME_CLASS(CTextDlg), CSize(600, 500), &context);
		CTextDlg *pNewView = (CTextDlg *)m_Spliter.GetPane(0, 1);
		m_Spliter.RecalcLayout();
		pNewView->OnInitialUpdate();
		m_Spliter.SetActivePane(0, 1);
	}
	return 0;
}

这里只是给一个思路。

CSDN无法上传资源,就不给实例了 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路奇怪

有钱出钱,没钱多出编程主意啊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值