挂钩时覆盖窗口未正确绘制

Posted

技术标签:

【中文标题】挂钩时覆盖窗口未正确绘制【英文标题】:Overlay Window not drawing correctly when hooking 【发布时间】:2009-06-03 12:46:44 【问题描述】:

要求是在另一个应用程序窗口的一侧绘制我的信息。 处理 z 顺序等挂钩 WH_GETMESSAGE 和绘制 WM_PAINT 似乎不错。

但是,有些 WM_PAINT 用于我所关心的窗口区域,但其他 WM_PAINT 用于完全不同的东西,例如上下文菜单或按钮。

示例记事本与在记事本屏幕中写入“Hello”的覆盖物挂钩。这工作正常。但是,当右键单击记事本时,上下文菜单会被 Hello 覆盖。基本上上下文菜单被破坏了。

有确定 WM_PAINT 是上下文菜单的优雅方法吗?

LRESULT CALLBACK overlayHook(int code, WPARAM wParam, LPARAM lParam) 
    //Try and be the LAST responder to WM_PAINT messages;
    LRESULT retCode = CallNextHookEx(hhk, code, wParam, lParam);

    //Per GetMsgProc documentation, don't do anything fancy
    if(code < 0) 
        return retCode;
    

    //Assumes that target application only draws when WM_PAINT message is
    //removed from input queue.
    if(wParam == PM_NOREMOVE) 
        return retCode;
    

    MSG* message = (MSG*)lParam;
    if(message->message != WM_PAINT) 
        //Ignore everything that isn't a paint request
        return retCode;
    

    PAINTSTRUCT psPaint;    
    BeginPaint(message->hwnd, &psPaint);
    HDC hdc = psPaint.hdc;
    RECT r = psPaint.rcPaint;           
    TextOut(hdc, 10, 10, "Hello", 4);
    EndPaint(message->hwnd, &psPaint);
    return retCode;

仅测试绘图更新区域是不够的,因为上下文菜单可以在任何地方并包含我关注的区域。

【问题讨论】:

【参考方案1】:

我不知道有什么优雅的方法可以做到这一点,但是您可以使用 GetWindowLong() 来获取窗口的样式或 GetClassName() 来获取其类名,然后根据这些值做出过滤决策。

【讨论】:

GetClassName 很有用。欢迎提出其他建议。 在非子窗口上简单地绘制叠加层怎么样?

以上是关于挂钩时覆盖窗口未正确绘制的主要内容,如果未能解决你的问题,请参考以下文章

挂钩/覆盖 DirectX 游戏?

我的数据未正确覆盖在网格上

sf 对象未正确覆盖在 r 中的 ggmap 层上

调整窗口大小时,公共控件未正确绘制

覆盖winform窗口的调整大小行为

Wordpress 保存帖子操作会覆盖帖子元更新