有什么方法可以知道 window 过程是否被子类化?
Is there any way to know if a window procedure was subclassed?
我想检查 window 形式的 winproc 是否被子类化。有任何 winapi 或 spy++ 技巧可以做到这一点吗?
您可以使用下一个代码来确定 window 由另一个模块 class 编辑(不同于注册 window class 的模块)
BOOL IsSubclassed(HWND hwnd)
{
LPARAM pfn = (IsWindowUnicode(hwnd) ? GetWindowLongPtrW : GetWindowLongPtrA)
(hwnd, GWLP_WNDPROC);
HMODULE hmod;
//if (RtlPcToFileHeader(pfn, &hmod))
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (PCWSTR)pfn, &hmod))
{
DbgPrint("pfn=%p hmod=%p\n", pfn, hmod);
return hmod != (HMODULE)GetClassLongPtrW(hwnd, GCLP_HMODULE);
}
// pfn not in any module - guess subclassed
return TRUE;
}
注意:GetWindowLongPtrA(hwnd, GWLP_WNDPROC)
和 GetWindowLongPtrW(hwnd, GWLP_WNDPROC)
- 总是 return 不同的结果 - window 过程的一个地址和另一个 - 代表 [=40] 的地址的句柄=] 过程:特殊内部值仅对 CallWindowProc - for determine which version A or W retrieves the address of the window procedure - need call IsWindowUnicode 有意义。这是无证的,但合理的。如果 subclassed 过程具有与原始过程相同的 ANSI 或 UNICODE 本机,它可以直接调用原始过程。如果本机不同 - window 消息需要翻译 (Unicode <-> ANSI)。 windows 假设调用者或 GetWindowLongPtrA
是本机 ANSI window 并且 GetWindowLongPtrW
的调用者是本机 UNICODE window。和 return 指向 window 过程的指针,如果相同的本机(A 和 A 或 W 和 W) 否则 returned handle
从另一边 GetClassLongPtrW(hwnd, GCLP_HMODULE)
和 GetClassLongPtrA(hwnd, GCLP_HMODULE)
- 总是 return 相同的结果
我想检查 window 形式的 winproc 是否被子类化。有任何 winapi 或 spy++ 技巧可以做到这一点吗?
您可以使用下一个代码来确定 window 由另一个模块 class 编辑(不同于注册 window class 的模块)
BOOL IsSubclassed(HWND hwnd)
{
LPARAM pfn = (IsWindowUnicode(hwnd) ? GetWindowLongPtrW : GetWindowLongPtrA)
(hwnd, GWLP_WNDPROC);
HMODULE hmod;
//if (RtlPcToFileHeader(pfn, &hmod))
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (PCWSTR)pfn, &hmod))
{
DbgPrint("pfn=%p hmod=%p\n", pfn, hmod);
return hmod != (HMODULE)GetClassLongPtrW(hwnd, GCLP_HMODULE);
}
// pfn not in any module - guess subclassed
return TRUE;
}
注意:GetWindowLongPtrA(hwnd, GWLP_WNDPROC)
和 GetWindowLongPtrW(hwnd, GWLP_WNDPROC)
- 总是 return 不同的结果 - window 过程的一个地址和另一个 - 代表 [=40] 的地址的句柄=] 过程:特殊内部值仅对 CallWindowProc - for determine which version A or W retrieves the address of the window procedure - need call IsWindowUnicode 有意义。这是无证的,但合理的。如果 subclassed 过程具有与原始过程相同的 ANSI 或 UNICODE 本机,它可以直接调用原始过程。如果本机不同 - window 消息需要翻译 (Unicode <-> ANSI)。 windows 假设调用者或 GetWindowLongPtrA
是本机 ANSI window 并且 GetWindowLongPtrW
的调用者是本机 UNICODE window。和 return 指向 window 过程的指针,如果相同的本机(A 和 A 或 W 和 W) 否则 returned handle
从另一边 GetClassLongPtrW(hwnd, GCLP_HMODULE)
和 GetClassLongPtrA(hwnd, GCLP_HMODULE)
- 总是 return 相同的结果