子窗口没有收到 WM_DESTROY?
Posted
技术标签:
【中文标题】子窗口没有收到 WM_DESTROY?【英文标题】:Child windows does not receive WM_DESTROY? 【发布时间】:2014-05-27 11:16:24 【问题描述】:我将winapi CreateWindowEx 打包成一个简单的类。由于每个窗口都共享同一个 wndProc(hwnd,msg,wparam,lparam),所以我将 CreateWindowEx 创建的每个窗口都放到一个 map 中来分发 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 中打印了所有味精,但我注意到了。
那么我怎样才能在正确的时间从地图中移除那些子窗口呢?或者在不创建 hwnd 映射的情况下分发 msg 的方法?
【问题讨论】:
【参考方案1】:他们肯定确实收到了这条信息。但他们的窗口过程在 Windows 内部,而不是在您的程序内部。所以你永远看不到它。您可以在MSDN documentation 中阅读一些内容,请注意 WM_DESTROY 没有得到任何特殊处理。也不会生成您的父窗口可以看到的通知。
当您看到父窗口被破坏时,不会自动删除所有子窗口,subclassing controls 是 C++ 类库包装器的一个非常标准的要求。顺便说一句,最好不要自己发明,这已经做过很多次了。
【讨论】:
【参考方案2】:那么我怎样才能在正确的时间从地图中移除那些子窗口呢?
您必须使用SetWindowLongPtr(GWL_WNDPROC)
或SetWindowSubClass()
对您创建的每个窗口进行子类化,然后您将收到所有WM_DESTROY
消息。
或者一种不创建 hwnd 映射的方式分发 msg?
像 ATL 和 VCL 这样的框架通过为每个窗口动态分配一个 thunk 并将对象指针放在 thunk 中,然后将 thunk 用作窗口过程来处理这个问题。这样,每当调用 thunk 时,它都会将消息直接传递给其关联对象。
【讨论】:
以上是关于子窗口没有收到 WM_DESTROY?的主要内容,如果未能解决你的问题,请参考以下文章