根据您的喜好调整对话框中的控件的大小/位置
- 下载demo project V1.2 (Modeless Dialog) - 58.93 KB
- 下载demo project V1.1 (Modal Dialog) - 33.36 KB
- 下载source code V1.2 - 7.23 KB
- 下载demo project and source code V2.4 - 61.24 KB
1. 原来的对话框
2. 后对话框的大小 介绍 一个对话框是一个简单的但也很重要的用户界面,可以用作SDI的互补性或MDI项目。在许多情况下,它也作为项目的主窗口。不幸的是MFC架构不提供调整对话框中的控件的方法。当你改变的大小可调整的对话框的大小,所有的控制仍然呆在左上角。 许多人提出几种解决方案,但他们几乎满足我的需求。一些解决方案使用非常复杂的技术,很难理解,所以很难提高和扩展。一些解决方案太简单,满足甚至稍微复杂的需要。一些不是很方便二次开发人员使用。和他们中的大多数控件移动到目标位置没有考虑控制的闪烁。 CSizingDialog下面的类,给你一些简单但强大的方法来改变现状的方式,可以让你的对话框更可用的和专业的。我感谢很多人的智能的工作给了我很多启发。 背景 的运动控制在一个对话框,可以简单地视为运动的四个边界的控制,使整个控制调整和重新定位在一个对话框。类CSizingDialog仅仅是基于这样一个简单的事实,是更好地利用封装。 使用的代码 让我们先从如何使用类。细节将在稍后讨论: 改变对话框类的基类(例如CYourDlg)从CDialog baseCYourDialog CDialog发生CYourDlg的基类。头文件YourDlg.h添加以下代码: 隐藏,复制代码# include & lt;跨类=“代码串”在“SizingDialog.h”& lt; / span> 的ifndef baseCYourDialog #定义baseCYourDialog CSizingDialog # endif 当然,您可以使用CSizingDialog直接代替CDialog。 文件SizingDialog.h和SizingDialog.cpp复制到您的项目目录,并将SizingDialog.cpp添加到您的项目。现在您可以指定你想移动或大小的控制函数CYourDlg:: OnInitDialog()和下面的例子一样。下面的功能解释。 隐藏,复制Codethis→AddResizableCtrl (IDC_EDIT1 _T (C (-0.5))); 这→AddResizableCtrl (IDC_STATIC1 _T(“X + CY ")); 这→AddResizableCtrlArray (IDC_CHECK1 IDC_CHECK3, 0.0, 1.0,假); 这些都是使用的代码。 函数定义的移动方式控制 添加一个单一的控制。指定的国家免疫日 隐藏,,复制Codevoid AddResizableCtrl(使用UINT国家免疫日LPCTSTR lpszString = NULL); ,空白AddResizableCtrl(使用UINT国家免疫日 双dRateLeft,双dRateRight, 双dRateTop,双dRateBottom); lpszString dRateLeft, dRateRight dRateTop, dRateBottom参数来描述移动的控制方式。他们将在下面详细讨论。 小贴士:= = NULL,如果国家免疫日将所有控件在对话框中添加使用相同的参数。 添加(或修改)一个id的控制范围从nIDStart nIDEnd或从nIDEnd nIDStart。 隐藏,复制Codevoid AddResizableCtrlRange(使用UINT nIDStart使用UINT nIDEnd, LPCTSTR lpszString = NULL); 空白ModifyResizableCtrlRange(使用UINT nIDStart使用UINT nIDEnd, LPCTSTR lpszString = NULL); 空白AddResizableCtrlRange(使用UINT nIDStart使用UINT nIDEnd, 双dRateLeft,双dRateRight, 双dRateTop,双dRateBottom); 添加一个控制范围,id从nIDStart nIDEnd或从nIDEnd nIDStart。 隐藏,复制Codevoid AddResizableCtrlArray(使用UINT nIDStart使用UINT nIDEnd, 双dSelfGain = 0.0,双dBorderIntervalRate = 1.0, BOOL bHori = TRUE); 这控制装置之间的区别的定义方法和前方法是,在前者情况下,所有控件都使用相同的运动参数,所以他们所有行为相同的在过去的情况下,移动参数没有给出直接从其他参数并计算。典型的结果是,控制的移动参数逐渐改变了从第一个控制到最后。 这个函数的参数将分别讨论如下。你也可以参考移动参数的解释。 dSelfGainThe增益的大小控制相对于对话框窗口大小获得bHori指定的尺寸。dBorderIntervalRateThe“边境”之间的比例大小,抵消之间第一个控件的左边界和原来的位置,以及两个控件之间的间隔尺寸在水平方向。垂直方向的情况是相似的。bHoriThe方向控制是重新安排。 小贴士: 设置dBorderIntervalRate = 0.0保持ctrl边境附近接近BorderSet dBorderIntervalRate = 1.0保持ctrl重新安排UniformlySet dBorderIntervalRate = 1.0 e20 ctrl常数之间的时间间隔 运动参数的解释 运动补偿的权利/对话框窗口的底部边缘相对于原来的位置被认为是1.0下的定义。 使用数字:定义 dRateLeftThe移动速度控制的左边界的rightdRateRightThe移动速度控制的权利边界 垂直的情况是相似的。 使用字符串定义: 正确定义的字符串可以分为不同的部分由字符“+”连接(也可以指定其他字符)。每个部分由一个系数和一个关键词,如0.5 x, C (-0.3), (-15.5 rxy)。如果没有指定的系数,它被设置为1.0。字符串不敏感的上/下字符。 你可以猜,一个关键字,X代表水平维度,而Y代表竖直维度。如果没有X或Y,定义应用于垂直水平维度和维度。 X, Y, XYThe整体控制移动后对话框的底部/右边界。C、残雪、CY, CXYOnly /右底部边界的控制措施后,对话框的底部/右边界。的左/上缘控制仍然保持对话框时调整。R, RX, RY RXYThe整个控制将保持固定比例的对话框的客户矩形对话框时调整。 现在,所有的调整和重新定位问题进行了讨论。注意,如果一个控制的移动方式在某些方向定义不止一次,只有最后一个定义可以工作。 猜猜下面的句子能够带来什么? 隐藏,复制Code
this->AddResizableCtrl(NULL);
或 隐藏,复制Code
this->AddResizableCtrl(NULL, _T("R"));
如果你不确定,将其中一个添加到CYourDlg: OnInitDialog句子前()返回TRUE;看到效果。当然,前两个步骤在正确使用需要编译的代码。 的兴趣点 现在我将讨论一些关于如何避免控制闪烁时尽可能的对话框。那些只是想使用类可以跳过本节。 第一个改进是重绘标志设置为FALSE之前控制后,恢复真正的移动控制如下: 隐藏,复制Code
pCtrl->SetRedraw(FALSE); pCtrl->MoveWindow(&rcCtrl); pCtrl->SetRedraw(TRUE);
(原始代码是不同的可见状态控制。) 第二个改进是清除旧的矩形(例如,rcCtrlOld)控制。而不是使用这个→InvalidateRect(及rcCtrlOld),我们只是更新区域属于rcCtrlOld同时不属于rcCtrl控制保持目前的地方。这是实现以下功能: 隐藏,复制Code
void CSizingDialog::InvalidateCtrlBorder( // XR: erase lpRectOld - lpRectNew LPCRECT lpRectOld, LPCRECT lpRectNew, BOOL bErase /*= TRUE*/)
还有当你移动groupbox控制问题。前两个步骤不能解决这些问题。有一些旧的痕迹留在新groupbox控制。但是如果你不运用这两个步骤,groupbox控制和其他控制groupbox控制将闪烁严重。 我的解决方案是把groupbox控制面积为9部分。每个部分都是一个单独的矩形。所做的工作是以下函数: 隐藏,复制Code
void GetGroupBoxRgn(const CWnd* pGBox, const CWnd* pParent, CRect* pRc)
中华人民共和国与9个元素指向一个绘图用的矩形类数组。中国元素的意义GroupBox说明如下,0表示整个矩形。 隐藏,复制Code
// ______________9____________ // | | // 7 8 // |_____5_____[ 4 ]_____6_____| // | | // | | // | | // | | // 2 3 // | | // | | // | | // | | // |_____________1_____________|
注意,7日,8日和9日的一部分groupbox控制不存在在groupbox默认风格。 所以可以视为Groupbox 9“控制”。每个人都可以应用前两个步骤,问题已经解决了。但我不认为这是一个好的解决方案。 的24种典型控制,以下类型的控制仍然闪烁或多或少地在移动即使应用两个步骤。它们是: ComboboxListboxSlider controlList controlTree controlTab控制 需要更多的努力来解决这个问题。 修订历史 2005年10月8日- V1.2:关键问题已经固定在类中使用一个非模态的对话框。2005年9月7日- V1.1:四个语句由机器不支持修改,所以类现在可以用在一个项目开发的机器。2005年9月5日- V1.0 本文转载于:http://www.diyabc.com/frontweb/news6862.html