ATL CWindow类有一个有用的虚方法OnFinalMessage
,在处理窗口的最后一个窗口消息后调用它 - 此时可以安全地销毁或删除与窗口关联的任何对象。从MFC CWnd
类派生的窗口是否有任何等价物?
答案 0 :(得分:4)
PostNcDestroy()正是您要找的。 p>
顺便说一句,如果你正在实现一个无模式对话框并且正在寻找“删除它”的位置,那么就是PostNcDestroy()。
答案 1 :(得分:1)
这个答案描述了我最终如何解决了我的问题。我会注意到虽然John Dibling的答案很有帮助,但这不是我问题的最终解决方案。这是因为WM_NC_DESTROY消息作为最终消息发送到窗口,但是这可以在完成对窗口的最后一条消息处理之前处理。有关问题的解释,请参阅示例http://support.microsoft.com/?kbid=202110。
在调用delete this
之后,该对象不再有效,但您仍然在技术上处于WM_CLOSE
处理程序中,因此当您最终返回时,您可能会崩溃。这意味着假设您可以在PostNcDestroy中执行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;
}