当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 对话框模板,RegexTest

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 对话框模板,RegexTest


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 116 ::
收藏到网摘: n/a

C++ At Work 专栏...
对话框模板,RegexTest

原著:Paul DiLascia
翻译:NorthTibet

下载源代码:CAtWork0508.exe (279KB)
原文出处:Dialog Templates, RegexTest

  • 对话框模板
  • 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 对话框模板

  对话框模板有点像汇编语言编程手册中的内容,现在就让我们穿上蹩脚的工作制服,立即从 DLGTEMPLATE 开始吧。
  假设你分配了一块足够大的内存来存放整个对话框模板,首先要做的事情就填写 DLGTEMPLATE 结构域。这一部分不难:

WORD* pTempl = new WORD[1024];DLGTEMPLATE& dt = *((DLGTEMPLATE*)pTempl);dt.style = WS_POPUPWINDOW|DS_MODALFRAME|WS_DLGFRAME;dt.cdit = 3; // # dlg itemsdt.x = 100; // in dlg units// etc.

  DLGTEMPLATE 结构域是自扩展的,对此我不再做进一步说明。紧跟着该结构后面的域是变长域:菜单,对话框类和标题。每一项都不能超过一个 WORD。它可以是一个空结尾的 Unicode 字符串以标示某个 MENU 资源的名字,对话框类名或标题。此外,菜单和类名可以用特殊值 0xFFFF 后跟一个 16位 的 ID——即可以是菜单资源的 ID,也可以是预定义系统窗口类的序数。在大多数情况下,类名都应该使用 0x0000(空串),它告诉 Windows 操作系统使用默认的对话框类(#32770)。多数对话框都没有菜单,所以菜单也是 0x0000(空串)。在代码中是这样写的:

*pTempl++ = 0; // 菜单 (无)*pTempl++ = 0; // 对话框类 (使用标准的对话框类)

接下来是标题,一个空结尾的 Unicode 字符串:

USES_CONVERSION;LPCWS