MFC 主程序显示 模态对话框 两种创建模式完整可运行代码前置约定子对话框类CChildDlgChild 无边框样式用于嵌入 Static 容器容器控件 IDIDC_CONTAINER非默认 IDC_STATIC父窗口类CMainDlg模式 1栈对象成员变量推荐常驻嵌入1. 父窗口头文件 CMainDlg.hcpp运行#include ChildDlg.h class CMainDlg : public CDialogEx { // ... private: // 栈对象全局生命周期无需手动释放 CChildDlg m_childDlg; protected: virtual BOOL OnInitDialog(); afx_msg void OnSize(UINT nType, int cx, int cy); DECLARE_MESSAGE_MAP() };2. 父窗口 OnInitDialog 创建嵌入窗口cpp运行BOOL CMainDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // 获取容器控件坐标 CWnd* pContainer GetDlgItem(IDC_CONTAINER); CRect rcContainer; pContainer-GetWindowRect(rcContainer); ScreenToClient(rcContainer); // 创建子对话框仅执行一次 m_childDlg.Create(IDD_CHILD_DLG, this); // 绑定容器作为父窗口真正嵌入 m_childDlg.SetParent(pContainer); // 填满容器区域 m_childDlg.MoveWindow(0, 0, rcContainer.Width(), rcContainer.Height()); m_childDlg.ShowWindow(SW_SHOW); return TRUE; }3. 窗口缩放自适应 OnSizecpp运行void CMainDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); // 判断子窗口是否创建成功 if (!m_childDlg.GetSafeHwnd()) return; CWnd* pContainer GetDlgItem(IDC_CONTAINER); CRect rcClient; pContainer-GetClientRect(rcClient); m_childDlg.MoveWindow(rcClient); }4. 手动隐藏 / 销毁可选cpp运行// 仅隐藏保留句柄下次直接Show m_childDlg.ShowWindow(SW_HIDE); m_childDlg.ShowWindow(SW_SHOW); // 彻底销毁一般不需要析构自动释放 m_childDlg.DestroyWindow();优点栈对象随父窗口自动析构无内存泄漏代码极简适合常驻内嵌界面。模式 2堆指针动态创建 / 销毁按需切换界面1. 父窗口头文件 CMainDlg.hcpp运行#include ChildDlg.h class CMainDlg : public CDialogEx { // ... private: // 堆指针手动管理生命周期 CChildDlg* m_pChildDlg nullptr; protected: virtual BOOL OnInitDialog(); afx_msg void OnBtnCreateChild(); afx_msg void OnBtnDestroyChild(); virtual ~CMainDlg(); // 析构兜底释放 DECLARE_MESSAGE_MAP() };2. 动态创建子窗口按钮触发cpp运行void CMainDlg::OnBtnCreateChild() { // 防止重复创建 if (m_pChildDlg ! nullptr m_pChildDlg-GetSafeHwnd()) return; CWnd* pContainer GetDlgItem(IDC_CONTAINER); CRect rcContainer; pContainer-GetWindowRect(rcContainer); ScreenToClient(rcContainer); // new 堆分配 m_pChildDlg new CChildDlg(this); m_pChildDlg-Create(IDD_CHILD_DLG, this); m_pChildDlg-SetParent(pContainer); m_pChildDlg-MoveWindow(0, 0, rcContainer.Width(), rcContainer.Height()); m_pChildDlg-ShowWindow(SW_SHOW); }3. 手动销毁子窗口按钮触发cpp运行void CMainDlg::OnBtnDestroyChild() { if (m_pChildDlg nullptr) return; // 销毁窗口 释放堆内存 m_pChildDlg-DestroyWindow(); delete m_pChildDlg; m_pChildDlg nullptr; }4. 父窗口析构函数兜底防内存泄漏cpp运行CMainDlg::~CMainDlg() { // 窗口关闭时强制释放 if (m_pChildDlg ! nullptr) { m_pChildDlg-DestroyWindow(); delete m_pChildDlg; m_pChildDlg nullptr; } }5. 自适应缩放 OnSize同栈对象逻辑cpp运行void CMainDlg::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (m_pChildDlg nullptr || !m_pChildDlg-GetSafeHwnd()) return; CWnd* pContainer GetDlgItem(IDC_CONTAINER); CRect rcClient; pContainer-GetClientRect(rcClient); m_pChildDlg-MoveWindow(rcClient); }适用场景需要频繁切换、打开 / 关闭内嵌子界面多个不同子对话框动态切换容器。两种模式核心区别总结表格模式内存管理创建时机销毁方式适用场景栈成员变量自动释放无泄漏父窗口初始化一次性创建父窗口销毁自动释放长期固定内嵌界面堆指针 new必须手动 delete否则泄漏按钮 / 事件按需创建手动 DestroyWindowdelete动态切换、临时内嵌界面关键注意事项子对话框资源必须设置StyleChild、BorderNone否则无法嵌入容器控件 ID 不能是默认IDC_STATIC否则无法获取句柄模态对话框DoModal()不能嵌入控件仅支持Create()非模态子窗口。