代码之家  ›  专栏  ›  技术社区  ›  1800 INFORMATION

相当于MFC Windows的OnFinalMessage?

  •  1
  • 1800 INFORMATION  · 技术社区  · 17 年前

    ATLCWindow类有一个有用的虚拟方法 OnFinalMessage 它在处理窗口的最后一条窗口消息之后调用——此时可以安全地销毁或删除与窗口关联的任何对象。从MFC派生的窗口是否有等效项 CWnd 班级?

    2 回复  |  直到 17 年前
        1
  •  4
  •   John Dibling    17 年前

    PostNcDestroy() 就是你要找的。

    顺便说一下,如果您正在实现一个无模式对话框,并且正在寻找“删除此;”的位置,那么postnDestroy()就是这个位置。

        2
  •  1
  •   1800 INFORMATION    17 年前

    这个答案描述了我如何最终解决我的问题。我会注意到,虽然约翰迪布林的回答很有帮助,但这并不是我问题的最终解决方案。这是因为wm_nc_destroy消息作为最终消息发送到窗口,但可以在处理完最后一条发送到窗口的消息之前进行处理。参见例如 http://support.microsoft.com/?kbid=202110 关于这个问题的解释。

    1. 使用wm_close调用dialogproc()。
    2. processWindowMessage()调用wm_关闭处理程序。
    3. 在wm_close处理程序中,调用DestroyWindow()。
    4. 最后用wm ncdestroy再次调用dialogproc。
    5. processWindowMessage()调用wm ncDestroy处理程序。
    6. 在wm ncdestroy处理程序中调用“delete this”。

    打过电话之后 delete this ,对象不再有效,但您仍在 WM_CLOSE 处理程序,所以当您最终回到那里时可能会崩溃。这意味着假设你能做到这一点并不真正安全。 删除此 在PostncDestroy中,因为对象可能仍然存在于其他堆栈帧中。

    /// 
    /// 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);
        }
    };
    

    我创建了上面的类,注意它是从ATLcWindow类派生的——这允许我为这个类使用onFinalMessage处理程序。OnFinalMessage处理程序不同于MFC窗口中的PostncDestroy,因为它保证只有在堆栈上的最终消息处理程序完成后才能调用。

    然后,我们使用窗口子类来插入这个窗口,作为我自己窗口的窗口过程:

    // roughly speaking
    FinalMessageWindow<MyWindow> _finalMessageWindow(this);
    finalMessageWindow.SubclassWindow(m_hWnd);
    

    然后,我们为窗口实现onFinalMessage处理程序:

    void MyWindow::OnFinalMessage(HWND hWnd)
    {
        delete this;
    }
    
    推荐文章