子窗口没有收到WM_DESTROY?

时间:2014-04-13 14:42:28

标签: windows winapi message

我将winapi CreateWindowEx打包成一个简单的类。由于每个窗口共享一个相同的wndProc(hwnd,msg,wparam,lparam),我将CreateWindowEx创建的每个窗口放入一个映射以分发msg,如下所示:

wndProc(hwnd, msg, wparam, lparam){
    if(map[hwnd]!=nil){
        switch(msg){
            map[hwnd].wndProc(...)
        }
    }
}

每次窗口或其父窗口被销毁时,请将其从地图中删除:

case WM_DESTROY: delete(map, hwnd)

但按钮之类的东西不会收到WM_DESTROY。我在WM_NOTIFY和WM_COMMAND中打印了所有的消息,但我注意到了。

那么如何在合适的时间从地图中删除这些子窗口?或者一种方式分发msg而不创建一个hwnd地图?

2 个答案:

答案 0 :(得分:6)

他们当然获取该消息。但是他们的窗口程序在Windows内部,而不在程序内部。所以你永远不会看到它。您可以在MSDN documentation中阅读的内容,请注意WM_DESTROY如何获得特殊待遇。也不会生成父窗口可以看到的通知。

当您看到父窗口被销毁时,自动删除所有子窗口时,subclassing controls是C ++类库包装器的一个非常标准的要求。最好不要发明自己的顺便说一下,这已经做过很多次了。

答案 1 :(得分:2)

  

那么如何在合适的时间从地图中删除这些子窗口?

您必须使用SetWindowLongPtr(GWL_WNDPROC)SetWindowSubClass()对您创建的每个窗口进行子类化,然后您将收到所有WM_DESTROY条消息。

  

或者在没有创建hwnd地图的情况下分发msg?

像ATL和VCL这样的框架通过为每个窗口动态分配thunk并将对象指针放在thunk中来处理它,然后使用think作为窗口过程。这样,无论何时调用thunk,它都会将消息直接传递给其关联的对象。