自1803(C ++)起,带有GWLP_WNDPROC的SetWindowLongPtr不适用于全屏应用程序

时间:2018-06-20 10:40:38

标签: c++ windows

自1803年以来,SetWindowLongPtr似乎已进行了某些更改。该函数不返回错误代码和有效值。适用于x64和x86应用程序。仅在全屏应用程序(游戏)中发生。在窗口应用程序中,将返回相同(有效)的返回值,并且该钩子将按预期工作。

我的代码已经存在了很长一段时间,直到升级到1803后才出现此问题。

1 个答案:

答案 0 :(得分:0)

找到了解决方案,以前我只是用以下代码钩住了属于进程ID的第一个窗口:

    static HWND hwndTarget = NULL;
    auto CaptureWindow = [](HWND hwnd, LPARAM lParam) -> BOOL
    {
        DWORD lpdwProcessId;
        GetWindowThreadProcessId(hwnd, &lpdwProcessId);
        if (lpdwProcessId == lParam)
        {
            hwndTarget = hwnd;
            return FALSE;
        }
        return TRUE;
    };
    EnumWindows(CaptureWindow, static_cast<LPARAM>(pid));

    if (hwndTarget == NULL)
    {
        LOG("Unable to find target window handle");
        return false;
    }

    gWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(hwndTarget, GWLP_WNDPROC, (LONG_PTR)WindowProc));

但是以下代码对其进行了修复:

std::vector<HWND> hwnds;

    GetAllWindowsFromProcessID(GetCurrentProcessId(), hwnds);

    if (hwnds.size() == 0)
        return false;

    for (auto& h : hwnds)
    {
        WNDPROC oldProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(h, GWLP_WNDPROC));

        if (oldProc == 0)
            continue;

        gWndProcs[h] = oldProc;

        gWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtr(h, GWLP_WNDPROC, (LONG_PTR)WindowProc));
    }

    return true;