ATL CWindow类有一个有用的虚拟方法OnFinalMessage
,它在处理窗口的最后一个窗口消息之后被调用 – 在这一点上,销毁或删除任何与窗口相关的对象是安全的。 是否有任何等同于从MFC CWnd
类派生的窗口?
PostNcDestroy()是你在找什么。
顺便说一句,如果你正在实现一个无模式的对话框,并正在寻找“删除这个”的位置,PostNcDestroy()就是这个地方。
这个答案描述了我最终如何解决了我的问题。 我会注意到,虽然约翰·迪布林的回答是有帮助的,但这不是我的问题的最终解决方案。 这是因为WM_NC_DESTROY消息作为最终消息发送到窗口,但可以在窗口的最后一个消息处理完成之前处理。 有关问题的解释,请参阅http://support.microsoft.com/?kbid=202110 。
在调用delete this
,该对象不再有效,但是您仍然在技术上位于WM_CLOSE
处理程序中,因此当您最终返回时可能会崩溃。 这意味着假设你可以在PostNcDestroy中delete this
,因为这个对象可能仍然存在于其他堆栈框架中, delete this
并不是很安全。
/// /// A window designed to allow any window to use the "OnFinalMessage" method from the ATL CWindow class /// You must call SubclassWindow for this instance so that the window procedure runs template<class T> class FinalMessageWindow : public CWindowImpl<FinalMessageWindow<T> > { T *_t; /// The object wanting to receive the final message notification public: BEGIN_MSG_MAP(FinalMessageWindow<T>) END_MSG_MAP() /// /// The constructor /// \param t The object that wants to get the OnFinalMessage notification FinalMessageWindow(T *t) : _t(t) { } /// /// Called when the final window message for the window has been processed - this is often a good time to delete the object /// \param hWnd The window handle virtual void OnFinalMessage(HWND hWnd) { _t->OnFinalMessage(hWnd); } };
我创建了上面的类,注意它是从ATL CWindow类派生的 – 这允许我为这个类使用OnFinalMessage处理程序。 OnFinalMessage处理程序与MFC窗口中的PostNcDestroy不同,因为只有在堆栈中的最终消息处理程序完成后,才能保证它被调用。
然后,我们使用窗口子类来插入这个窗口作为我自己的窗口的窗口过程:
// roughly speaking FinalMessageWindow<MyWindow> _finalMessageWindow(this); finalMessageWindow.SubclassWindow(m_hWnd);
然后我们为我们的窗口实现OnFinalMessage处理程序:
void MyWindow::OnFinalMessage(HWND hWnd) { delete this; }