3

有一个 2000 年的应用程序。ANSI。来源不可用。有一个 DLL 可以挂钩它的 API。但即使 DLL 创建了自己的 Unicode 窗口或对话框。标题将始终是文字问号(如果代码点位于 ANSI 代码页之外。)

它的原因是 EXE 图像有一些东西导致了这种行为。虽然我不是 100% 确定我曾经尝试过用 Unicode 标题实例化一个窗口来公平。虽然我明白这是可以做到的。

这适用于所有窗口。可以肯定的是,一个窗口类注册了 W 系列函数,并且创建的窗口使用了 W 系列和该类。我自己在明确使用 A 和 W 函数时从来没有遇到过问题。我觉得它是更好的风格。特别是与在预处理器宏中包装字符串文字相比。因此,我从不设置 Visual Studio 字符集,无论它在哪里由我决定。

当通过 DLGTEMPLATEEX(或 DIALOGEX)结构创建精致的对话框时,对话框是 Unicode,但只有标题不是。任何设置或获取文本的尝试,包括 InternalGetWindowText 都会失败。它必须与运行时版本或“清单”或类似的东西有关(如果是这样,我们可以解决这个问题。)

不涉及中间代码。事实上,我习惯于挂钩 Windows API。无论发生什么,它都是内部的。而且它确实令人沮丧,因为自定义绘制标题是一项艰巨的任务,并且有太多工具窗口无法显示标题。我们希望向用户呈现真实世界的文本,而不是文本垃圾,即使 ANSI 代码页不匹配也是如此。

已编辑:新信息。同一套程序中的另一个应用程序没有表现出这种行为。一个使用 Windows,不受影响的是全屏视频游戏。因此,这似乎排除了(这些程序的)开发环境是一个因素的可能性。因此,它必须是程序本身以某种方式启动的行为。

我认识到的一件事是 IsWindowUnicode 对于这些程序似乎不是一成不变的。一个窗口怎么可能是Unicode,后来又不是。但这也可能是上下文的。虽然有时感觉更像是永久的,但通常窗口会失去其 Unicode 状态。这只是我必须继续前进的唯一线索。也许有某种特殊的东亚 IME 系统在起作用。我观察到一个简单的Edit控件一开始就可以出Unicode,后来就不行了。仍然 Spy++ 报告带有标题栏的主 Windows 是 Unicode。

雷米回答的评论中还有更多信息。遗憾的是,他的回答似乎是一条死胡同。虽然是崇高的努力。

包括(http://forums.codeguru.com/showthread.php?419079-window-title-unicode-problem)关于在似乎是一个更典型的开发项目中出现的相同问题的讨论。

4

2 回答 2

3

您的 DLL 可能正在创建 Unicode 窗口,但如果它没有运行自己的消息循环来为这些窗口提供服务,那么它们将由应用程序的现有消息循环提供服务,这些消息循环仍在使用 Ansi API(GetMessageA()、、DispatchMessageA()等),因此 Unicode 数据将被翻译成 Ansi,这将丢失无法翻译成 Ansi 的 Unicode 字符。这与 EXE 映像、清单、预处理器等无关。

于 2013-11-02T00:14:19.347 回答
3

美好的结局。

我注意到SetWindowsHookExA是进口的。似乎 EXE 使用了一个 3rd 方静态库,该库设置了一个后门使用WH_CBTWH_MSGFILTER钩子,基本上向 Windows 添加了一个附加层,用于设置对话框样式,并且可能为客户端代码提供了一种不处理常规 Win32 消息传递框架的方法。 .. 这可以推断,因为如果这些钩子被切断,应用程序基本上会死机。

我希望我能识别出安装这些钩子的产品。但到目前为止,我只能确认绕过它们会恢复 Unicode 字幕功能。

这似乎是一个晦涩难懂的问题。但我认为可能还有其他人会觉得这很有用,如果这个问题的评分不会低于 0,我将不胜感激(坦率地说,我不明白为什么 0 不是底线)

这是实际的解决方案。尽管另一个答案是值得深思的。此外,将 SetWindowLong[Ptr] 添加到需要使用 W 变体的 API 列表中。事实上,上面提到的其他 API 在这种特殊情况下似乎并不重要,但安全总比抱歉好。

于 2013-11-05T17:38:37.100 回答