TONT 41673 GWLP_WNDPROC返回的这些奇怪的值是什么意思?

不知不觉间。

GetWindowLongPtr(hwnd, GWLP_WNDPROC) [or GetWindowLong(hwnd, GWL_WNDPROC) if you haven’t yet made your code 64-bit compatible] is supposed to return the current window procedure. Why do I sometimes get wacko values?

GetWindowLongPtr(hwnd, GWLP_WNDPROC)【或者是 GetWindowLong(hwnd, GWL_WNDPROC),如果你的代码还没有为64位兼容性优化的话】应当返回当前的窗体过程,那为什么有时返回值看上去怪怪的呢?

Because sometimes “you can’t handle the truth”.

因为,有时你是『接受不了事实』的。

If the current window procedure is incompatible with the caller of GetWindowLongPtr, then the real function pointer cannot be returned since you can’t call it. Instead, a “magic cookie” is returned. The sole purpose of this cookie is to be recognized by CallWindowProc so it can translate the message parameters into the format that the window procedure expects.

如果当前的窗体过程与GetWindowLongPtr的调用者不兼容,那么是不能返回实际的函数指针的,因为调用方无法调用它。作为替代方案,GetWindowLongPtr会返回一个『神奇小甜饼』,其意义在于可以被CallWindowProc识别,然后将窗体消息的参数转化为该窗体过程所期望的格式。

For example, suppose that you are running Windows XP and the window is a UNICODE window, but a component compiled as ANSI calls GetWindowLong(hwnd, GWL_WNDPROC). The raw window procedure can’t be returned, because the caller is using ANSI window messages, but the window procedure expects UNICODE window messages. So instead, a magic cookie is returned. When you pass this magic cookie to CallWindowProc, it recognizes it as a “Oh, I need to convert the message from ANSI to UNICODE and then give the UNICODE message to that window procedure over there.”

例如,假设你的环境是Windows XP,窗体是Unicode窗体,但某个用ANSI编码编译的组件调用了GetWindowLong(hwnd, GWL_WNDPROC)。(在这种情况下,)是不能返回原始的窗体过程的,因为调用方使用的是ANSI编码的窗体消息,但窗体过程期望的是Unicode窗体消息。作为替代,返回值就是那个『神奇小甜饼』。当你把这块小甜饼传递给CallWindowProc时,CallWindowProc就会意识到:『噢,我需要把传入的ANSI窗体消息转换为Unicode的,然后再把转换后的Unicode窗体消息传递给目标窗体过程。』

As another example, suppose that you are running Windows 95 and the window was created by a 32-bit component, but a 16-bit component calls GetWindowLong(hwnd, GWLP_WNDPROC). Again, the raw 32-bit window procedure can’t be returned since the message needs to be converted from 16-bit to 32-bit. (And besides, a 16-bit program can’t jump to a 32-bit flat address.) So instead, again, a magic cookie is returned which CallWindowProc recognizes as a “Oh, I need to convert the message from 16-bit to 32-bit and then give the converted message to that window procedure over there.”

再举个例子,假设你的环境是Windows 95,有个窗体是由某个32位组件创建的,但某个16位的组件调用了GetWindowLong(hwnd, GWLP_WNDPROC)。同样,原始的32位窗体过程不能直接返回,因为接下来的窗体消息需要由16位转换为32位。(此外,16位代码也不能直接跳转到32位的平面地址。)所以同样作为替代,返回的『神奇小甜饼』再度被CallWindowProc识别,使其意识到『噢,我得把传入的窗体消息从16位转换为32位,然后把转换后的消息传递给目标窗体过程。』

(These conversions are known as “thunks”.)

(这种转换通常被称作thunks。)(译注:thunk function即包装了传名调用方法的函数,似乎没有中文译名。)

So remember, the only things you can do with the values you get from GetWindowLongPtr(hwnd, GWLP_WNDPROC) are to (1) pass them to CallWindowProc, or (2) pass them back to SetWindowLongPtr(hwnd, GWLP_WNDPROC).

所以请记住,对于GetWindowLongPtr(hwnd, GWLP_WNDPROC)的返回值,你所能做的是只有:(1)将返回值转手发给CallWindowProc(2)将返回值回头交给SetWindowLongPtr(hwnd, GWLP_WNDPROC)。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

 剩余字数 ( Characters available )

注:请不要在评论中插入任何链接,否则将自动被识别为垃圾评论,博主将完全看不到。

Notice: please DO NOT add any links in your comment, otherwise it would be identified as SPAM automatically.

*