为什么GetWindowLong有ANSI和Unicode变体?

4 unicode winapi win32gui

我今天发现GetWindowLong(和GetWindowLongPtr)有'ANSI'(A)和'Unicode'(W)风格,即使它们没有TSTR参数.在MSDN上的页面GetWindowLong只是表明这些变体存在,但并没有提到为什么.

我可以想象它必须匹配CreateWindowEx(也有A/W口味)的编码,或者RegisterClass,但由于许多原因,我不认为这是有道理的.显然,这很重要,因为有人报告说Unicode版本可能在XP上失败(即使XP是NT,据我所知,所有的Unicode都在引擎盖下).我还试图反汇编32位版本USER32.DLL(包含两种风格GetWindowLong),并根据一些明显的编码差异*进行了额外的工作.

我应该选择哪种功能?


*它们的风格GetWindowLong是相同的,除了它们传递给其他函数的布尔值.这个布尔值与存储器结构中的标志位进行比较.我不能打扰使用静态代码分析进行跟踪.

Dav*_*nan 7

我相信原因在Raymond Chen的文章中解释过,GWLP_WNDPROC返回的这些奇怪的值是什么?

如果当前窗口过程与GetWindowLongPtr的调用者不兼容,则无法返回实际函数指针,因为您无法调用它.相反,返回"魔术cookie".此cookie的唯一目的是由CallWindowProc识别,因此它可以将消息参数转换为窗口过程所期望的格式.

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

  • [`RegisterClassEx`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms633587.aspx)确定:"如果使用RegisterClassExA注册窗口类,应用程序会告诉系统创建的类的窗口期望具有文本或字符参数的消息使用ANSI字符集;如果使用RegisterClassExW注册它,则应用程序请求系统将消息的文本参数作为Unicode传递. (2认同)