在上一篇文章中,我们解析了16位的对话框模板的构成,今天的这篇文章中,我们再来讲讲它的兄弟:32位对话框模板。
32位对话框模块和16位相比,十分类似。有一些8位的数据字段被扩展到了16位,另外一些16位的字段被扩展为32位版本,同时,添加了扩展风格,最后,所有的字符串都由ANSI变成了Unicode。
32位模块的开头如下图所示:
这和16位版本的对话框模板一致,除了其中有一个新的dwExStyle字段,并且cItems从BYTE类型变成了WORD类型。这样一来,一个32位的对话框所能容纳的控件的最大数量为65535个,这对于普通应用来说,也应该足够了。
接下来是字符串,就像16位版本一样。但是请注意,现在字符串变成了Unicode格式。举个例子,如果你想存储字符串”Hello”,则你需要这样声明:
48 00 65 00 6C 00 6C 00 6F 00 00 00 ; “Hello”
和16位版本一样,32位版本的对话框模板也可以指定一个序数,而不是字符串。具体的声明方式为,首先是两个字节[FF 00],然后接一个16位的序数(小端格式)。举个例子,如果你想声明序数42,则你应该这样声明:
FF 00 2A 00 ; 00FF followed by WORD (little-endian)
字符串的类型也是三种,和16位版本一样:
> 菜单名称,可以是字符串或者序数
> 类名称,必须为字符串(不可以为序数)
> 对话框标题,必须为字符串(不可以为序数)
如果DS_SETFONT风格被设置,则接下来时一个WORD值,用来指明应用的字体大小和一个用来指定字体名称的字符串。否则,表示不指定字体信息。这个规则和16位版本一样。
目前为止,所有的字段都是WORD对齐的。
接来下是定义对话框里的控件。每个控件模板都以一个DWORD边界开头,如果需要,可以插入填充字符,如下图所示:
和之前一样,对话框的坐标表示为对话框单元(DLU)。
接下来时类名称,可以是以空字符结尾的Unicode字符串,或者是序数。下面是一些标准的窗口类:
类名称之后是控件文本,可以是字符串也可以是序数。另外需要注意的是:如果要指定一个序数,则需要使用FFFF,而不是00FF,原因我也不太清楚。
接下来是65535字节的额外字节。如果没有额外字节,则使用数字0。
下面我们来看一个实例:
首先是头部:
解析如下:
接下来是菜单名称,类名称和对话框标题:
请注意,这里因为指定了DS_SETFONT风格,所以,接下来的信息里包含了字体描述:
从上面我们可以看出,对话框使用了8个像素的”MS Shell Dlg”字体。
接下来时11个控件模板。请不要忘记每个模板必须是DWORD对齐,所以我们需要添加合适的填充字节来使它们在4个字节的边界上。
0042 00 00 // Padding for alignment
接下来时第一个对话框控件模板:
请注意上面的”static”类名称被编码为序数了。所以对此控件模板的解释如下:
其他控件模板以此类推。
下面是资源编译器反编译得到的源代码:
和之前一样,我们没有指定”DS_SETFONT”风格,因为它已经隐含在”FONT”声明中了。
你可能已经猜到了,这个就是文本替换对话框。
总结
冗长,无趣,但也值得了解。
感谢阅读。
最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The evolution of dialog templates – 32-bit Classic Templates》
领取专属 10元无门槛券
私享最新 技术干货