对话框模板RegexTest
2010-07-11 20:44:51 来源:WEB开发网对话框模板
RegexTest
我想用MFC和C++ 创建一个基于对话框的程序(主窗口本身是个对话框)。我不想使用资源(.rc)文件,而是想在内存中动态创建对话框。我在 MSDN 中找到一些线索,但没有发现代码例子。我了解到 DLGTEMPLATE和DLGITEMTEMPLATE 结构以及 InitModalIndirect 函数或许可以用来创建模式对话框,但我不知道从何入手。请问如何不依赖资源文件动态创建对话框?
Thomas Zeitlberger
从理论上讲,动态创建对话框很简单,但实际上那样做很危险。就是内存中创建正确的结构并调用一系列 Indirect 对话框创建函数之一:用CDialog::CreateIndirect 创建非模式对话框,或者用CDialog::InitModalIndirect 创建模式对话框(然后调用DoModal 运行)。它们分别对应着 Win32 API 函数 ::CreateDialogIndirect和::DialogBoxIndirect。不管用什么方法,你都得在内存中传递一个指向对话框模板的指针。
从概念上讲,创建对话框模板很简单,就是在内存中建立并初始化相关结构。其具体细节是有讲究的,因为这些结构有点奇奇怪怪,很诡诈,你不得有一点差错,只要有一个字节的偏差,那么你的程序便会莫名其妙地垮掉。控件的位置和大小计算也会出现混乱,原因是对话框不使用像素,而是用对话框单位(units),它依赖对话框的字体。
要完整地讨论包含所有类型控件的对话框模板不是本专栏所能胜任的。但我可以提供一个简单的例子,它至少包含一个控件。我写了一个类:CStringDialog,它显示一个对话框,请求用户输入一个字符串,如图 Figure 1 所示。
Figure 1 String Dialog
为了使用这个类,你只需实例化然后调用Init和DoModal 即可:
CStringDialog dlg;
dlg.Init(_T("Hi"), _T("Please enter your name:"));
if (dlg.DoModal()==IDOK) {
CString name = dlg.m_str;
// do something with it...
}
CStringDialog 的样子和行为类似于所有基于对话框资源的CDialog 派生类,所不同的是该对话框用其自身模板在内存中动态生成。
那么对话框模板到底是个什么东西呢?对话框模板其实就是一个描述对话框的内存结构。这个模板之所以复杂并容易出错,是因为它并非像 CREATESTRUCT和WNDCLASS 一样是个定长结构。它是一个变长结构,其中包含有定长结构元素 DLGTEMPLATE 以及 DLGITEMTEMPLATE 结构数组,其每个数组元素对应着一个对话框控件项。DLGTEMPLATE和DLGITEMTEMPLATE 两者都包含一些跟在 C 结构后面非常很特别的变长域。这些结构如 Figure 2 所示,Figure 3 是整个结构的布局。
Figure 3 对话框模板
更多精彩
赞助商链接