现在的位置: 首页 > 综合 > 正文

【初级MFC】大小可变的对话框

2013年10月28日 ⁄ 综合 ⁄ 共 2575字 ⁄ 字号 评论关闭

书到用时方恨少!
一直没有用VC做过什么开发,眼下遇上任何一件小事都得从头来过。下面就是一个例子,记下来留作参考。

【要求】
1.  窗体大小可调的特殊要求:不允许比原始窗体更小,而且宽度不允许拉伸,即只允许高度拉伸;
2.  窗体中有一个文本框还有两个按钮,高度变化后所属控件要进行相应的位置调整。

【实现手法】
1.  窗体设计。新建对话框的Border默认为Dialog Frame,需要修改为Resizing;
2.  在窗体类的头文件中增加两个私有变量;

	CSize m_OldSize;	//保存上一次窗体大小
	CRect m_rectOrigi;	//窗体的原始位置及大小

3.  变量初始化(构架函数中);

	//init
	m_rectOrigi = CRect(0, 0, 0, 0);

4.  获取窗体的初始大小(OnInitDialog中);

	GetWindowRect(&m_rectOrigi);

5.  指定窗体的WM_SIZE消息事件的处理属性为OnSize;

6.   OnSize方法代码;

void CTestDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);

	if(nType == SIZE_MINIMIZED) return;

	// 原本窗体大小尚没有初始化,则直接退出
	if (m_rectOrigi.Width()	!= 0 &&
		m_rectOrigi.Height()!= 0 ){
			CRect rectNew;
			GetWindowRect(&rectNew);
			// 如果新的窗体宽度与原本的窗体宽度不同或是高度小于原本宽度,则恢复原本的窗体大小;
			// 即:只允许用户拉伸窗体高度。
			if( (rectNew.Width() != m_rectOrigi.Width())) {
				MoveWindow(rectNew.left, rectNew.top, m_rectOrigi.Width(), rectNew.Height());
				return;
			}
			if(	(rectNew.Height() < m_rectOrigi.Height())) {
				MoveWindow(rectNew.left, rectNew.top, rectNew.Width(), m_rectOrigi.Height());
				return;
			}
	}

	// 与上一次窗体高度或是宽度的相差
	CSize SizeOff(cx - m_OldSize.cx, cy-m_OldSize.cy);
	// 改变窗体内控件的位置,参数即为offset值
	::EnumChildWindows(GetSafeHwnd(), EnumProc, (LPARAM)&SizeOff);

	if(GetDlgItem(IDD_TEST_DIALOG)->GetSafeHwnd())
	{
		if(nType == SIZE_MAXIMIZED)
			GetDlgItem(IDD_TEST_DIALOG)->ShowWindow(SW_HIDE);
		else
			GetDlgItem(IDD_TEST_DIALOG)->ShowWindow(SW_SHOW);
	}

	// 更新窗体旧大小,用于下一次做比较。
	m_OldSize =CSize(cx,cy);

	Invalidate();
}

7.  OnSize中用到一个回调函数EnumProc,定义如下:

//////////全局函数
BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lParam)
{
	CWnd* pWnd = CWnd::FromHandle(hwnd);
	CSize* pSizeOff =(CSize*)lParam;
	CTestDlg* pDlg = (CTestDlg*)pWnd->GetParent();

	if(!pDlg) return FALSE;

	CRect rect;
	pWnd->GetWindowRect(rect);
	pDlg->ScreenToClient(rect);

	if( hwnd == pDlg->m_btnCancel.GetSafeHwnd() ||
		hwnd == pDlg->m_btnOK.GetSafeHwnd()) {
		pWnd->MoveWindow(
			rect.left+pSizeOff->cx,	//改变左上坐标
			rect.top+pSizeOff->cy,	//改变左上坐标
			rect.Width(),		//宽度不变
			rect.Height(),		//高度不变
			FALSE);
	}
	if( hwnd == pDlg->m_edit.GetSafeHwnd()) {
		pWnd->MoveWindow(
			rect.left,			//左上坐标不变
			rect.top,			//左上坐标不变
			rect.Width()+pSizeOff->cx,	//改变宽度(由于别处的控制,此处也一定不会变更)
			rect.Height()+pSizeOff->cy,	//改变高度
			FALSE);
	}

	return TRUE;
}

【参考资料】(第二个资料由于原始链接已经失效,给出的是百度快照。具体参见“0345  限制窗体的大小”)

1. http://hi.baidu.com/sysnapmfc/blog/item/763ae617ae184c1e972b43c4.html

2. http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece76310468a3b404380146d96864968d4e414c42246111a3bbaef7c7c4745cec278601cac4b5eedf431713d0623b68cc8ff0b87fdcd763bcd7a742613913066c46fd8dc3021d651944de8df0e97bce74291b9a3a2c82354dd52756df0f79c2b0603cb1fe76437f4d2985f635d07c9ee&p=9f63e72990904eaa02bd9b7e0656&user=baidu&fm=sc&query=%CF%DE%D6%C6%B4%B0%CC%E5%B5%C4%B4%F3%D0%A1&qid=f0830d060be71e98&p1=2

【相关代码下载】

http://download.csdn.net/detail/mxclxp/4150112

抱歉!评论已关闭.