【问题标题】:Why does GetWindowLong have ANSI and Unicode variants?为什么 GetWindowLong 有 ANSI 和 Unicode 变体?
【发布时间】:2012-02-20 15:22:23
【问题描述】:

我今天发现GetWindowLong(和GetWindowLongPtr)有'ANSI' (A) 和'Unicode' (W) 风格,尽管它们没有TSTR 参数。 MSDN page on GetWindowLong 仅表明存在这些变体,但未提及原因。

我可以想象它必须与CreateWindowEx(也有A/W 风格)或RegisterClass 的编码相匹配,但由于很多原因,我认为这没有意义。显然,这很重要,因为someone reported that the Unicode version may fail on XP(尽管 XP 是 NT 并且据我所知,所有 Unicode 都在幕后)。我还尝试反汇编了USER32.DLL 的32 位版本(包含GetWindowLong 的两种风格),并且基于一些明显的编码差异做了额外的工作*。

我应该选择哪个功能?


*GetWindowLong 的风格是相同的,除了它们传递给其他函数的布尔值。这个布尔值与内存结构中的标志位进行比较,我懒得使用静态代码分析来追踪。

【问题讨论】:

  • 愚蠢的问题 - 为什么要关心现在在 2012 年的 ANSI 版本?
  • 我可以想象两个重要的场景。一种是使用第三方提供的窗口类,他们将其注册为 ANSI 类。在幕后发生的任何A<->W 转换都可能会导致一些性能损失。另一个是您使用 ANSI 的地方,因为您根本不关心 i18n(例如,您正在编写游戏并且您的窗口无论如何都在全屏显示)。
  • 我明白了。好吧,无论如何,A 函数都会在内部进行转换(对于 ANSI 应用程序)。此外,UI 代码的字符串转换性能很少成为问题。

标签: winapi unicode win32gui


【解决方案1】:

相信原因在Raymond Chen的文章What are these strange values returned from GWLP_WNDPROC?中有解释

如果当前窗口过程与 GetWindowLongPtr 的调用者不兼容,则无法返回真正的函数指针,因为您无法调用它。相反,会返回一个“魔法 cookie”。此 cookie 的唯一目的是被 CallWindowProc 识别,以便它可以将消息参数转换为窗口过程期望的格式。

例如,假设您正在运行 Windows XP,并且窗口是 UNICODE 窗口,但编译为 ANSI 的组件调用 GetWindowLong(hwnd, GWL_WNDPROC)。无法返回原始窗口过程,因为调用者正在使用 ANSI 窗口消息,但窗口过程需要 UNICODE 窗口消息。因此,返回的是一个魔术 cookie。当你将这个神奇的 cookie 传递给 CallWindowProc 时,它会将其识别为“哦,我需要将消息从 ANSI 转换为 UNICODE,然后将 UNICODE 消息提供给那边的那个窗口过程。”

【讨论】:

  • 是什么使窗口成为 UNICODE 窗口? RegisterClassWCreateWindowExW?
  • RegisterClassEx 确定:“如果您使用 RegisterClassExA 注册窗口类,则应用程序告诉系统所创建类的窗口期望带有文本或字符参数的消息使用 ANSI 字符集; 如果您使用 RegisterClassExW 注册它,应用程序会请求系统将消息的文本参数作为 Unicode 传递。"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-06
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多