相当于MFC窗口的OnFinalMessage?

时间:2009-04-16 21:31:50

标签: c++ windows mfc atl

ATL CWindow类有一个有用的虚方法OnFinalMessage,在处理窗口的最后一个窗口消息后调用它 - 此时可以安全地销毁或删除与窗口关联的任何对象。从MFC CWnd类派生的窗口是否有任何等价物?

2 个答案:

答案 0 :(得分:4)

PostNcDestroy()正是您要找的。

顺便说一句,如果你正在实现一个无模式对话框并且正在寻找“删除它”的位置,那么就是PostNcDestroy()。

答案 1 :(得分:1)

这个答案描述了我最终如何解决了我的问题。我会注意到虽然John Dibling的答案很有帮助,但这不是我问题的最终解决方案。这是因为WM_NC_DESTROY消息作为最终消息发送到窗口,但是这可以在完成对窗口的最后一条消息处理之前处理。有关问题的解释,请参阅示例http://support.microsoft.com/?kbid=202110

  1. 使用WM_CLOSE调用DialogProc()。
  2. ProcessWindowMessage()调用您的WM_CLOSE处理程序。
  3. 在WM_CLOSE处理程序中,调用DestroyWindow()。
  4. 这最终会再次使用WM_NCDESTROY调用DialogProc。
  5. ProcessWindowMessage()调用您的WM_NCDESTROY处理程序。
  6. 您在WM_NCDESTROY处理程序中调用“delete this”。
  7. 在调用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;
    }