首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >挂钩WH_GETMESSAGE消息

挂钩WH_GETMESSAGE消息
EN

Stack Overflow用户
提问于 2019-04-08 18:37:19
回答 1查看 1.4K关注 0票数 0

我试图从我的类中连接WH_GETMESSAGE,以确定特定窗口调整大小的时刻。但是,看起来钩子并没有设置好。

类,我尝试从其中挂接:

代码语言:javascript
复制
class WindowDisplayHelper : // public ...
{    
public:
    // some other public methods here
    void SetMsgHook();
protected:
    LRESULT CALLBACK GetMsgProcHook(int code, WPARAM wParam, LPARAM lParam);
    static LRESULT CALLBACK MsgPoc(int code, WPARAM wParam, LPARAM lParam);
private:
    // some other private members there
    HWND m_windowHandle;
    bool m_isWindowResizing = false;
    static HHOOK m_msgHook;
    static WindowsDisplayHelperMasterWindow* m_pThis;
};

.cpp文件:

代码语言:javascript
复制
WindowDisplayHelper* WindowDisplayHelper ::m_pThis = nullptr;
HHOOK WindowDisplayHelper ::m_msgHook = NULL;

void WindowDisplayHelper ::SetMsgHook()
{
    m_pThis = this;
    m_msgHook = SetWindowsHookEx(WH_GETMESSAGE, MsgPoc, NULL, 0);
}

LRESULT CALLBACK WindowDisplayHelper::MsgPoc(int code, WPARAM wParam, LPARAM lParam)
{
    if (m_pThis != nullptr)
    {
        return m_pThis->GetMsgProcHook(code, wParam, lParam);
    }
    return CallNextHookEx(0, code, wParam, lParam);
}

LRESULT CALLBACK WindowDisplayHelper::GetMsgProcHook(int code, WPARAM wParam, LPARAM lParam)
{
    DUMPER_INFO("Hooked");
    if (code < 0)
    {
        return CallNextHookEx(0, code, wParam, lParam);
    }
    MSG* lpmsg = (MSG*)lParam;
    DUMPER_INFO("Hooked for HWND: %p. Current window %p", lpmsg->hwnd, m_windowHandle);
    if (lpmsg->hwnd != m_windowHandle)
    {
        return CallNextHookEx(0, code, wParam, lParam);
    }
    if (lpmsg->message == WM_ENTERSIZEMOVE && !m_isWindowResizing)
    {
        DUMPER_INFO("Start window resizing");
        m_isWindowResizing = true;
    }
    else if (lpmsg->message == WM_EXITSIZEMOVE && m_isWindowResizing)
    {
        DUMPER_INFO("Stop window resizing");
        m_isWindowResizing = false;
    }

    return CallNextHookEx(0, code, wParam, lParam);
}

下面是我创建WindowDisplayHelper对象的方法:

代码语言:javascript
复制
bool DisplayManager::CreateWindowDisplay(TDisplayId displayId, void * windowHandle)
{
    auto helper = boost::make_shared<WindowDisplayHelper>(windowHandle);
    helper->SetMsgHook();
    AddDisplayHelper(displayId, helper);

    return true;
}

尽管我在创建对象后调用了SetMsgHook(),但看起来没有设置钩子,因为我在日志文件中看不到任何调试输出,并且m_isWindowResizing变量总是== false。所以问题是为什么我的钩子不起作用?谢谢。

EN

回答 1

Stack Overflow用户

发布于 2019-04-09 10:59:59

代码语言:javascript
复制
m_msgHook = SetWindowsHookEx(WH_GETMESSAGE, MsgPoc, NULL, 0);

此行生成一个ERROR_HOOK_NEEDS_HMOD (1428) system error。这意味着不能在没有模块句柄的情况下设置非本地挂钩。如果将dwThreadId参数设置为零,则钩子过程与在与调用线程相同的桌面上运行的所有现有线程相关联。它是一个非加载挂钩,需要指定有效的hmod参数。正如@Remy Lebeau指出的那样,你需要将钩子代码放在DLL中。

或者使用GetCurrentThreadId()设置一个有效的dwThreadId参数,正如@rudolfninja指出的那样。

我使用以下代码基于Windows桌面应用程序模板进行测试。它起作用了。你可以试一试。

代码语言:javascript
复制
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    // ...

    HHOOK m_msgHook = SetWindowsHookEx(WH_GETMESSAGE, MsgPoc, NULL, GetCurrentThreadId());
    DWORD errCode = GetLastError();

    MSG msg;

    // Main message loop:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

LRESULT CALLBACK MsgPoc(int code, WPARAM wParam, LPARAM lParam)
{
    OutputDebugString(L"Hooked");
    if (code < 0)
    {
        return CallNextHookEx(0, code, wParam, lParam);
    }
    MSG* lpmsg = (MSG*)lParam;
    //OutputDebugString("Hooked for HWND: %p. Current window %p", lpmsg->hwnd, m_windowHandle);
    if (lpmsg->hwnd != m_windowHandle)
    {
        return CallNextHookEx(0, code, wParam, lParam);
    }
    if (lpmsg->message == WM_ENTERSIZEMOVE && !m_isWindowResizing)
    {
        OutputDebugString(L"Start window resizing");
        m_isWindowResizing = true;
    }
    else if (lpmsg->message == WM_EXITSIZEMOVE && m_isWindowResizing)
    {
        OutputDebugString(L"Stop window resizing");
        m_isWindowResizing = false;
    }

    return CallNextHookEx(0, code, wParam, lParam);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55571483

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档