gpt4 book ai didi

c - 如何将返回的 WndProc/DlgProc 句柄转换为函数地址?

转载 作者:太空宇宙 更新时间:2023-11-04 01:48:30 25 4
gpt4 key购买 nike

在下面的调用中,WndProc 可以是 returned as a handle :

FARPROC pfn = (FARPROC)GetWindowLongPtr(hWnd, 
DWLP_DLGPROC); //same with GWLP_WNDPROC

有没有办法将其从用户模式代码转换为地址?

最佳答案

您需要下一个代码:

PVOID pfn = (IsWindowUnicode(hwnd) ? 
GetWindowLongPtrW : GetWindowLongPtrA)(hwnd, GWLP_WNDPROC);

因此您需要根据 IsWindowUnicode 的结果调用 GetWindowLongPtrWGetWindowLongPtrA


注意:GetWindowLongPtrA(hwnd, GWLP_WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC) - 总是返回不同的结果 - 一个窗口过程的地址和另一个 - 代表窗口过程的地址:仅对 CallWindowProc 有意义的特殊内部值 - 用于确定哪个版本 AW 检索窗口过程的地址 -需要调用 IsWindowUnicode。这是无证的,但合理的。如果子类过程具有与原始过程相同的 ANSI 或 UNICODE native ,则它可以直接调用原始过程。如果 native 不同 - 窗口消息需要转换 (Unicode <-> ANSI)(例如 WM_GETTEXTWM_SETTEXT..)。

事实上 GetWindowLongPtr(hwnd, GWLP_WNDPROC) 必须返回与 SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)NewWindowProc) 相同的值

但是 SetWindowLongPtrA 设置了 ansi 窗口过程(它说在 WM_SETTEXT 中得到了指向 CHAR 字符串的指针)和 SetWindowLongPtrW 设置 unicode 窗口过程(即在 WM_SETTEXT 中获取指向 WCHAR 字符串的指针)。因此,如果当前窗口过程和 SetWindowLongPtr 设置的新窗口过程具有相同的 AW - 新过程可以直接调用旧过程,无需翻译,并且绝对SetWindowLongPtr 返回旧 Windows 过程的直接地址是合理的。如果 native 不同——(我们将 A 设置为 W 或将 W 设置为 A)——新的窗口过程不能直接调用旧的。在此之前,需要翻译一些 Windows 消息(WM_GETTEXTWM_SETTEXT 等)。因为这和返回的句柄和 CallWindowProc 在调用原始过程之前转换消息。


显示 IsWindowUnicode 可以为同一窗口返回不同值的示例 - 基于当前窗口过程 - 是 ansi 还是 Unicode:

if (HWND hwnd = CreateWindowExA(0, WC_STATICA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) {

DbgPrint("IsWindowUnicode=%x\n", IsWindowUnicode(hwnd));

LONG_PTR l = GetWindowLongPtrW(hwnd, GWLP_WNDPROC);

SetWindowLongPtrA(hwnd, GWLP_WNDPROC, l);

DbgPrint("IsWindowUnicode=%x\n", IsWindowUnicode(hwnd));

SetWindowLongPtrW(hwnd, GWLP_WNDPROC, l);

DbgPrint("IsWindowUnicode=%x\n", IsWindowUnicode(hwnd));

DestroyWindow(hwnd);
}

和输出:

IsWindowUnicode=1
IsWindowUnicode=0
IsWindowUnicode=1

那么文档怎么说:

The character set of a window is determined by the use of the RegisterClass function. If the window class was registered with the ANSI version of RegisterClass (RegisterClassA), the character set of the window is ANSI. If the window class was registered with the Unicode version of RegisterClass (RegisterClassW), the character set of the window is Unicode.

不完全正确。它基于当前的窗口过程 Ansi 或 Unicode。最初这是基于 RegisterClass 但可以通过 SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)NewWindowProc)

更改

关于c - 如何将返回的 WndProc/DlgProc 句柄转换为函数地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48539015/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com