CallWindowProc在退出时崩溃

时间:2013-03-22 14:00:50

标签: c++ winapi

为了挂钩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来捕获一些消息。所以我只是希望有经验的人能够遇到类似情况,然后才能提供帮助。

3 个答案:

答案 0 :(得分:2)

来自CallWindowProc的文档:

  

“如果通过调用GetWindowLong函数并将nIndex参数设置为GWL_WNDPROCDWL_DLGPROC来获取此值,则它实际上是窗口的地址或对话框过程,或仅对CallWindowProc

有意义的特殊内部值

您不能调用“特殊内部价值”,除非与CallWindowProc相同,最简单的方法是拨打CalLWindowProc ...

顺便说一句,看看SetWindowSubclass,它可能会为你缓解一切。

答案 1 :(得分:2)

关于问题2:

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

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

答案 2 :(得分:0)

对艾德里安麦卡锡来说。

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

结束功能