有什么方法可以知道 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 过程的指针,如果相同的本机(AAW W) 否则 returned handle

从另一边 GetClassLongPtrW(hwnd, GCLP_HMODULE)GetClassLongPtrA(hwnd, GCLP_HMODULE) - 总是 return 相同的结果