拆分窗口类CSplitterWnd在对话框中的应用及拆分子窗口间的通信

分类: MFC
  当你在GOOGLE或者百度键入"如何在对话框中使用CSplitterWnd“时,搜索出来的帖子大多千篇一律,鲜有真正是基于对话框的CSplitterWnd应用,大多是基于单文档框架的说明。至于具有参考价值的一篇博文,请参见 Codeguru

本文将告诉你如何在对话框中使用CSplitterWnd将主窗口拆分成两个子窗口,并且只与视图类有关,不涉及文档类。重载OnSize(), 使得窗口的大小可随主窗口的变化而改变。

步骤如下:

1,在主窗口类(某对话框)头文件中分别声明一个框架类以及一个CSplitterWnd拆分窗口类的指针类型成员变量

  1. private:  
  2.     CFrameWnd*      m_pFrameSplit;    // 分隔窗口  
  3.     CSplitterWnd    m_wndSpliter;     // 左右分隔  
private:
	CFrameWnd*      m_pFrameSplit;    // 分隔窗口
	CSplitterWnd    m_wndSpliter;     // 左右分隔

2,在主窗口类实现文件中的OnInitDialog()方法或OnCreate()事件中进行初始化工作,注册框架类及初始CSplitterWnd

  1. // 取得主窗口区域   
  2. CRect rc;  
  3. GetDlgItem(IDC_CHILDWND)->GetWindowRect(rc);  //IDC_CHILDWND是一个PictureBox的ID,表示要拆分的区域  
  4. ScreenToClient(&rc);  
  5.   
  6. // 注册框架类   
  7. CString sClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,  
  8.     ::LoadCursor(NULL, IDC_ARROW), (HBRUSH)::GetStockObject(WHITE_BRUSH),  
  9.     ::LoadIcon(NULL, IDI_APPLICATION));  
  10.   
  11. // 创建分隔窗口框架   
  12. m_pFrameSplit = new CFrameWnd;  
  13. m_pFrameSplit->Create(sClass, _T(""), WS_CHILD, CRect(0,0,0,0), this);  
  14. m_pFrameSplit->MoveWindow(rc);  
  15. m_pFrameSplit->ShowWindow(SW_SHOW);  
  16.   
  17. // 创建分割窗口   
  18. m_wndSpliter.CreateStatic(m_pFrameSplit, 1, 2);  
  19. m_wndSpliter.CreateView(0, 0, RUNTIME_CLASS(CEditView), CSize((int)(rc.Width() * 0.265), 0), NULL);   // 左窗口所占比例26.5%  
  20. m_wndSpliter.CreateView(0, 1, RUNTIME_CLASS(CEditView), CSize(0,0), NULL);  
  21. m_wndSpliter.MoveWindow(0, 0, rc.Width(), rc.Height());  
  22. m_wndSpliter.ShowWindow(SW_SHOW);  
	// 取得主窗口区域
	CRect rc;
	GetDlgItem(IDC_CHILDWND)->GetWindowRect(rc);  //IDC_CHILDWND是一个PictureBox的ID,表示要拆分的区域
	ScreenToClient(&rc);

	// 注册框架类
	CString sClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,
		::LoadCursor(NULL, IDC_ARROW), (HBRUSH)::GetStockObject(WHITE_BRUSH),
		::LoadIcon(NULL, IDI_APPLICATION));

	// 创建分隔窗口框架
	m_pFrameSplit = new CFrameWnd;
	m_pFrameSplit->Create(sClass, _T(""), WS_CHILD, CRect(0,0,0,0), this);
	m_pFrameSplit->MoveWindow(rc);
	m_pFrameSplit->ShowWindow(SW_SHOW);

	// 创建分割窗口
	m_wndSpliter.CreateStatic(m_pFrameSplit, 1, 2);
	m_wndSpliter.CreateView(0, 0, RUNTIME_CLASS(CEditView), CSize((int)(rc.Width() * 0.265), 0), NULL);   // 左窗口所占比例26.5%
	m_wndSpliter.CreateView(0, 1, RUNTIME_CLASS(CEditView), CSize(0,0), NULL);
	m_wndSpliter.MoveWindow(0, 0, rc.Width(), rc.Height());
	m_wndSpliter.ShowWindow(SW_SHOW);

注意倒数第三、四行。这里是要拆分的两个窗口对应的视图类,为了方便演示CSplitterWnd类拆分的效果,可以先直接用CEditView代替。

运行结果,主窗口的PictureBox区域被拆分成两个EditBox,中间有可移动的分隔栏用以调节大小。


3.重载OnSize(),使得窗口及控件自适应大小。传控件指针或ID两种方式均可。

  1. void CMainWndDlg::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.     CDialog::OnSize(nType, cx, cy);  
  4.   
  5.     static int nLastCx = 0;  
  6.     static int nLastCy = 0;  
  7.     int nWidth  = cx - nLastCx;  
  8.     int nHeight = cy - nLastCy;  
  9.     AdjustDlgItem(m_pFrameSplit, 0, 0, nWidth, nHeight);  
  10.     nLastCx = cx;  
  11.     nLastCy = cy;  
  12. }  
  13.   
  14. // 移动控件 以实现窗口自适应   
  15. void CMainWndDlg::AdjustDlgItem(UINT nId, int nLeft, int nTop,int nRight, int nBottom)  
  16. {  
  17.     AdjustDlgItem(GetDlgItem(nId), nLeft, nTop, nRight, nBottom);  
  18. }  
  19.   
  20. // 移动控件 以实现窗口自适应   
  21. void CMainWndDlg::AdjustDlgItem(CWnd* pItem, int nLeft, int nTop,int nRight, int nBottom)  
  22. {  
  23.     if(NULL == pItem)  
  24.         return;  
  25.     if(!IsWindow(pItem->GetSafeHwnd()))  
  26.         return;  
  27.   
  28.     // 取得控件区域   
  29.     CRect rcWnd;  
  30.     pItem->GetWindowRect(&rcWnd);  
  31.     ScreenToClient(&rcWnd);  
  32.   
  33.     // 重新计算区域   
  34.     rcWnd.top += nTop;  
  35.     rcWnd.bottom += nBottom;  
  36.     rcWnd.left += nLeft;  
  37.     rcWnd.right += nRight;  
  38.   
  39.     // 移动控件   
  40.     pItem->MoveWindow(rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height());  
  41. }  
void CMainWndDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	static int nLastCx = 0;
	static int nLastCy = 0;
	int nWidth  = cx - nLastCx;
	int nHeight = cy - nLastCy;
	AdjustDlgItem(m_pFrameSplit, 0, 0, nWidth, nHeight);
	nLastCx = cx;
	nLastCy = cy;
}

// 移动控件 以实现窗口自适应
void CMainWndDlg::AdjustDlgItem(UINT nId, int nLeft, int nTop,int nRight, int nBottom)
{
	AdjustDlgItem(GetDlgItem(nId), nLeft, nTop, nRight, nBottom);
}

// 移动控件 以实现窗口自适应
void CMainWndDlg::AdjustDlgItem(CWnd* pItem, int nLeft, int nTop,int nRight, int nBottom)
{
	if(NULL == pItem)
		return;
	if(!IsWindow(pItem->GetSafeHwnd()))
		return;

	// 取得控件区域
	CRect rcWnd;
	pItem->GetWindowRect(&rcWnd);
	ScreenToClient(&rcWnd);

	// 重新计算区域
	rcWnd.top += nTop;
	rcWnd.bottom += nBottom;
	rcWnd.left += nLeft;
	rcWnd.right += nRight;

	// 移动控件
	pItem->MoveWindow(rcWnd.left, rcWnd.top, rcWnd.Width(), rcWnd.Height());
}


为分割窗添加一些自己需要的功能

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值