【问题标题】:CallWindowProc crash on exitCallWindowProc 在退出时崩溃
【发布时间】:2013-03-22 14:00:49
【问题描述】:

为了挂钩wndproc,我写了wndprochook并使用SetWindowLong

wndproc=(WNDPROC)GetWindowLong(hwnd_1,GWL_WNDPROC);
SetWindowLong(hwnd_1,GWL_WNDPROC,(LONG)wndprochook);

现在我必须在wndproc 中做一些事情,并在函数结束时调用原来的wndproc

return wndproc(hwnd, uMsg, wParam, lParam);

它失败了,但感谢上帝我找到了CallWindowProc

return CallWindowProc(wndproc, hwnd, uMsg, wParam, lParam);

现在它正在工作。所以问题1:为什么我们必须使用CallWindowProc?简单地调用wndproc 时缺少什么?

钩子运行良好,但是当我退出程序时,它崩溃了。当然,一切都已完成,崩溃实际上并没有影响任何事情。但是看到崩溃仍然很糟糕。 那么问题2:这里可能发生了什么以及如何解决?

很抱歉,我没有关于原始程序如何自行关闭的信息,因为我所做的只是挂钩 wndproc 以捕获一些消息。所以我只是希望以前遇到过类似情况的经验丰富的人可以提供帮助。

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    来自CallWindowProc的文档:

    “如果这个值是通过在nIndex参数设置为GWL_WNDPROCDWL_DLGPROC的情况下调用GetWindowLong函数得到的,它实际上要么是窗口或对话框过程的地址,要么是仅对 CallWindowProc 有意义的特殊内部值”

    您不能调用“特殊内部值”,除非与CallWindowProc 一样,最简单的方法是调用CalLWindowProc...

    对了,看看SetWindowSubclass,它可能会为您提供帮助。

    【讨论】:

    • 哇!这真的解释了......你能想出问题2的答案吗?
    • 问题2:尝试通过调试器运行它,看看它在哪里中断。在最坏的情况下,将所有内容都放在 try/catch 中。
    • @fritzone 好吧,问题是我无法通过调试器运行目标程序......我所做的只是在它开始时注入一个 dll。
    【解决方案2】:

    关于问题2:

    从另一个答案的 cmets 来看,听起来您的子类 wndprochook 位于注入进程的 DLL 中。如果是这种情况,那么在退出期间,您的 DLL 可能会在窗口仍有待处理的消息时被卸载。所以 Window 的类仍然指向你的 wndproc,但是那个代码被卸载了,所以它崩溃了。

    最安全的做法可能是在关闭之前恢复原始 wndproc。例如,当您的子类看到 WM_DESTROY 或 WM_NCDESTROY 时,您基本上颠倒了您在子类化窗口时所做的步骤:在使用该消息执行 CallWindowProc 之前恢复窗口类中的原始 wndproc 字段。您的代码将不再被调用,即使该窗口还有更多消息。

    【讨论】:

    • 我不确定。似乎在目标 exe 模块之后卸载了 dll。此外,windows 应该在实例之前卸载。我说的对吗?
    • 但我认为您的回答仍然值得,虽然有时 dll 可能会被分离,但最好保持一切尽可能干净。
    【解决方案3】:

    感谢阿德里安·麦卡锡。

    Private Function WndProc(ByVal hWnd As Long, ByVal MSG As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case MSG
        Case WM_CUT, WM_PASTE, WM_CLEAR
            WndProc= 1
        Case WM_DESTROY, WM_NCDESTROY
            Call UnHookRKey(hWnd)
        Case Else
            WndProc= CallWindowProc(lngPrevWndProc, hWnd, MSG, wParam, lParam)
    End Select
    

    结束函数

    【讨论】:

      猜你喜欢
      • 2011-09-03
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-21
      • 2020-02-18
      相关资源
      最近更新 更多