我是不是必须销毁对话框上手动创建的组合框?

Posted

技术标签:

【中文标题】我是不是必须销毁对话框上手动创建的组合框?【英文标题】:Do I have to destroy manually created combo boxes on a dialog?我是否必须销毁对话框上手动创建的组合框? 【发布时间】:2017-10-15 08:45:11 【问题描述】:

OnInitDialog我调用这个方法来创建9个CComboBox下拉列表:

void CChristianLifeMinistryStudentsDlg::CreateSampleConversationVideoCombos()

    CChristianLifeMinistryStudentEdit* pArrayStudents[9] =
    
        &m_editMainStudent1,
        &m_editMainStudent2,
        &m_editMainStudent3,
        &m_editClass1Student1,
        &m_editClass1Student2,
        &m_editClass1Student3,
        &m_editClass2Student1,
        &m_editClass2Student2,
        &m_editClass2Student3
    ;

    CChristianLifeMinistryStudentEdit* pArrayAssistants[9] =
    
        &m_editMainStudent1Assist,
        &m_editMainStudent2Assist,
        &m_editMainStudent3Assist,
        &m_editClass1Student1Assist,
        &m_editClass1Student2Assist,
        &m_editClass1Student3Assist,
        &m_editClass2Student1Assist,
        &m_editClass2Student2Assist,
        &m_editClass2Student3Assist
    ;

    CString strChairman, strAuxClassCounsellor;

    strChairman.LoadString(IDS_STR_MWB_CHAIRMAN);
    strAuxClassCounsellor.LoadString(IDS_STR_AUX_CLASS_COUNSELLOR);

    for (int i = 0; i < 9; i++)
    
        CRect rctStudent, rctAssistant;

        pArrayStudents[i]->GetWindowRect(rctStudent);
        pArrayAssistants[i]->GetWindowRect(rctAssistant);

        ScreenToClient(&rctStudent);
        ScreenToClient(&rctAssistant);

        CRect rctSampleConversationVideo;

        rctSampleConversationVideo.SetRect(rctStudent.TopLeft(), rctAssistant.BottomRight());
        m_cbSampleConversationVideo[i].Create(CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP | WS_VISIBLE,
            rctSampleConversationVideo, this, IDC_COMBO_OCLM_AYFM_ASSIGN1_MH + i);

        m_cbSampleConversationVideo[i].SetFont(GetFont());
        m_cbSampleConversationVideo[i].AddString(strChairman);
        m_cbSampleConversationVideo[i].AddString(strAuxClassCounsellor);
    

我无法解决的是,当对话框关闭时,我是否需要在其中的每一个上调用 DestroyWindow?我似乎没有任何内存泄漏。

【问题讨论】:

您的代码不清楚。但一般不会。 DestroyWindow 不适用于对话框控件。对话框控件通常不需要特殊清理。 感谢您的澄清。 【参考方案1】:

当你有一个由 MFC 处理的窗口时,你有两个部分。第一个是窗口本身(由HWND 表示),第二个是MFC 中包装功能的对象,实现消息映射并通过包装windows 消息提供简单的成员函数访问。

窗口的生命周期在调用DestroyWindow 时结束。像对话框这样的父窗口会自动销毁它的所有子窗口。不管孩子是通过调用CreateDialog/DoModal 创建的,还是稍后使用任何其他Create 方法创建的。

最后,当进程结束时,所有窗口都被销毁。事实上,当线程结束时,线程内创建的所有窗口都会被销毁。但是窗口应该在线程结束之前由用户销毁。

MFC 内存块是另一回事。一些 MFC 窗口被设计为作为成员分配在堆栈上或窗口类内部。

通常作为子窗口(静态、列表视图、按钮等)创建的对话框和所有窗口都创建在堆栈上或作为另一个窗口类中的成员。

当调用类的析构函数并且窗口仍然存在时,所有这些窗口都被设计为存在于堆栈上或作为成员调用DestroyWindow。这也会导致调试输出出现消息,通常应该避免这种情况。

在堆上创建框架窗口和视图。在堆上创建的所有 MFC 窗口都有一个 PostNcDestroy 函数,当处理 WM_DESTROY 时,该函数最终删除 MFC 内存块。 PostNcDestroy 总是从 WM_NCDESTROY 处理程序调用。

您也可以在 MSDN 的 TN017 中找到有关此内容的详细信息

【讨论】:

以上是关于我是不是必须销毁对话框上手动创建的组合框?的主要内容,如果未能解决你的问题,请参考以下文章

列表控件中的 MFC 对话框组合框

从组合框中删除打字光标

如何根据从其他框中选择的文本更改动态创建的组合框的显示项

我可以创建单例 vaadin 组合框组件吗?

在使用ItemContainerGenerator进行自定义时,WPF ComboBox在第二次打开之前不会更新项目

wpf的组合框中显示新的选定项后如何显示对话框?