有没有人听说过标准Windows消息框的这个奇怪的错误?

fla*_*006 5 windows winapi fonts messagebox

几年前,我正在搞乱Visual Basic,我发现了这个MsgBox函数的一个bug .我试着寻找它,但没有人曾经说过这件事.它不仅仅是Visual Basic; 它与任何使用标准Windows MessageBoxAPI调用的东西有关.

当标题文本有多个字符时触发错误,第一个字符是带有变音符号('ÿ')的小写"y".这个角色有什么特别之处?它几乎绝对不是角色本身,而是其特殊的ASCII值.'ÿ'是字符255(0xFF),意味着它是可以存储在无符号字节中的最高值,并且其所有位都设置为1.

这个bug有什么作用?嗯,有两种不同的可能性,这取决于标题文本中的字符数.如果标题文本中有偶数个字符(除非它是2),则不会出现任何消​​息框,您只是听到警报声.如果标题文本中有两个字符,或者除了1之外的任何奇数(在这种情况下不会触发错误)......那么会发生这种情况:

它是

而且这还不是全部 - 消息也将被截断为一行.考虑到使用此API调用的频率,这似乎是至少在一个半高调事件中会发生的那种错误.互联网上有没有这方面的报道,或者有什么可能导致它的原因?也许这是与Unicode相关的故障,就像记事本中的"布什隐藏事实"故障一样?

我做了一个程序,以防你想玩这个; 在这里下载.

或者,将以下内容复制到记事本中,使用.vbs扩展名保存,然后双击它以显示上面显示的对话框:

MsgBox "Windows 3.1 font, anyone?", 0, "ÿ ODD NUMBER!"
Run Code Online (Sandbox Code Playgroud)

或者换一种不同的字体:

MsgBox "I CAN HAS CHEEZBURGER?", 0, "ÿ HImpact"
Run Code Online (Sandbox Code Playgroud)

编辑:似乎如果前四个字符是ÿ,它不会显示消息,即使有奇数个字符.

arx*_*arx 5

这通常是对话框模板的错误.这不是消息框错误.

例如,在Visual Studio中创建默认的win32应用程序.在.rc文件中,更改about框的模板中的标题

CAPTION "About sampleapp"
Run Code Online (Sandbox Code Playgroud)

CAPTION "ÿT"
Run Code Online (Sandbox Code Playgroud)

当你显示about框时,bug会自动显示出来.

DLGTEMPLATEEX文档中注意,菜单和类名的类型sz_Or_Ord意味着以空字符结尾的字符串或0xFFFF后跟单个字资源标识符.

Windows错误地将相似的方案应用于对话框标题:如果第一个字符是,0xFF则它将标题视为两个WORD长,但仅在它尝试查找字体信息时.当它显示标题时,它正确地将标题视为字符串.

换句话说,Windows正在标题字符串中查找字体信息.在大多数情况下,这不会指定有效字体,因此Windows默认使用系统字体.

为了证明这一点,我在内存中构建了一个对话框模板(基于此).一旦这个工作,我删除了将字体信息写入模板的代码,并使用对话框标题"ÿa\ xd\x200\x21SimSun".这将以斜体SimSun显示对话框,因为Windows正在从标题字符串中读取字体信息.

这个错误可能是16位Windows的宿醉,其中(我猜)0xFF被用作资源ID标记.


Jon*_*ter 3

一个奇怪的错误。MessageBox()我怀疑这些症状是实际显示对话框的方式造成的。

在内部,MessageBox() 动态构建对话框模板。如果您查看DLGTEMPLATE结构的描述,您会发现以下信息:

在对话框的标准模板中,DLGTEMPLATE 结构后面始终紧跟三个可变长度数组,它们指定对话框的菜单、类和标题。当指定 DS_SETFONT 样式时,这些数组后面还跟着一个指定点大小的 16 位值和另一个指定字体名称的可变长度数组。

因此,对话框模板的内存布局具有紧跟在对话框标题后面的字体规范。

Visual Basic 不使用 Unicode,因此您调用的函数实际上是MessageBoxA(). 这只是一个 thunk,它将传入的字符串从多字节转换为 Unicode,然后调用MessageBoxW().

我相信,由于某种原因,该字符串从多字节到 Unicode 的转换要么出错,要么返回虚假的长度值。当对话框模板构建在内存中时,这会产生连锁反应,破坏紧随标题字符串之后的内存——正如我们所知,标题字符串是字体规范。

  • 不,这不是多字节到宽字符的问题。当您调用 MessageBoxW 时,也会发生相同的行为。 (2认同)