对话框模板简史-16位经典模板

对话框模板简史-16位经典模板

作者:BlogUpdater |  时间:2021-04-14 |  浏览:1376 |  评论已关闭 条评论

在Windows的历史中,有四个版本的对话框模板。尽管进行了更改,但你会发现它们基本上都是相同的。

第一个版本是Windows 1.0中的经典的对话框模板,它的开始部分类似于下图:

请注意,在早期的16位的Windows中,有一个限制:每个对话框最多只能有255个控件,因为记录对话框控件数量的类型被定义为一个字节。

这个头部定义之后,接下来时一串字符串。在16位的对话框模板中,所有的字符串允许使用以空字符结尾的ANSI字符串。举个例子,如果你想存储字符串”Hello”,则你需要编写对应的6个字节:48 65 6C 6C 6F 00 ; “Hello”

(有个特例需要注意:如果你编写了一个单个的00字节,则表示是一个空字符串。如果你不希望保存一个字符串,但是对话框格式要求你必须这样做,则可以使用这种技法。)

有时候,你可以使用16位的序数值,而不是字符串。在这种情况下,你可以编写0xFF开头的序数值。举个例子,如果你希望指定序数42,则可以编写这样的3个字节:
FF 2A 00 ; FF followed by WORD (little-endian)

好了,让我们回到对话框模板。头部之后,有三种字符串:
> 菜单名称,可以是字符串,也可以是序数。如果你不想定义一个菜单,则通常可以将它设置为空。如果非空,则菜单会被LoadMenu进行加载,并使用指定的字符串或是程序实例中的字符串资源。

> 对话框类,必须是一个字符串(不可以使用序数)。通常这个字符串也设置为空,表示我们将使用一个默认的对话框类。如果对话框类非空,则类将会在程序实例中字符串资源中进行查找。

> 对话框标题,必须是一个字符串(不可以使用序数)。

如果DS_SETFONT风格被设置,则接下来时一个WORD类型的值,表明字体大小和字符串的字体名称,否则不指定特定的字体信息。

至此,头部格式介绍到这里。接下来时对话框控件模板,每个控件模板都像下图这样开头:

还记得吗,对话框的坐标被表示为对话框单元(DLU)。4个水平的DLU和8个竖直的DLU和一个平均字符等价。

接下啦,就是控件类名称了,它可以是一个以空字符结尾的ANSI字符串,或者一个0x80到0xFF之间的一个单个字节,这个单字节会编码为标准Windows控件类中的一个。

请注意,这种编码方式意味着,如果要在对话框模板中使用窗口类名称的首字符,则不能是扩展字符!

在类名之后是控制文本,可以是一个以零结尾的字符串或一个序数。如果使用序数,则CREATESTRUCT的lpszName成员是一个指向三字节序数序列的指针(0xFF后跟序数);否则,它是指向字符串的指针。我知道的唯一知道该顺序的控件是静态控件,如果你将其置于一种图像模式(SS_ICON或SS_BITMAP)中,则在这种情况下,顺序是静态显示的图像的资源标识符。

在控制文本以字节计数的形式出现最多256个字节的“额外数据”之后,接着是实际数据。如果没有“额外数据”,则使用零字节计数。

当对话框管理器创建控件时,它将指向“额外”数据的指针作为CreateWindowEx函数的最终LPVOID参数传递。 (据我所知,还没有办法告诉资源编译器插入这些额外的数据。这是目前还没有人利用的隐藏功能之一。)

好的,这一切都是理论上的。但是有时你只需要在你面前看到它即可理解它。因此,让我们分解一个实际的16位对话框资源。我从COMMCTRL.DLL中拿走了这个;它是“搜索/替换”对话框。

让我们从头部开始:

解释如下:

接下来时菜单名称,对话框类和对话框标题:

现在,因为设置了DS_SETFONT风格,所以接下来的部分是字体信息:

所以,这个对话框使用了8pt的Helv字体。

接下里是对话框控件模板:

解释如下:

我怎么知道样式值0x0000应该解释为SS_LEFT而不能解释为BS_PUSHBUTTON? 因为window类告诉我,我拥有的是静态控件。如下:
002C 82 // “static”

接下来,是控件标题:
002D 46 69 26 6E 64 20 57 68 61 74 3A 00 // “Fi&nd What:”

最后,是结尾。
0039 00 // no extra data

请注意,我们没有在对话框的STYLE指令中明确说“ DS_SETFONT”,因为这是“ FONT”指令所隐含的。 而且由于WS_VISIBLE默认情况下处于启用状态,因此我们无需赘述; 而是我们不得不在不需要的地方明确驳斥它。

现在,如果你看一下SDK头文件,您将找到dlgs.h和findtext.dlg,它们与上面的模板非常匹配,为诸如0x0400之类的魔术值命名,并将控件放置在上面。 不过,你会发现一些细微的差别,因为SDK中的头文件是针对32位“查找/替换”对话框的,而上面的文件是16位“查找/替换”对话框的,但你会发现它仍然匹配挺好。

总结
16位资源定义及结构解析至此结束,感谢脑细胞辛勤工作。

最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The evolution of dialog templates – 16-bit Classic Templates》

标签:

评论已关闭。