当前位置: 首页 > news >正文

MFC 主程序显示 模态对话框

两种创建模式完整可运行代码

前置约定

  • 子对话框类:CChildDlg(Child 无边框样式,用于嵌入 Static 容器)
  • 容器控件 ID:IDC_CONTAINER(非默认 IDC_STATIC)
  • 父窗口类:CMainDlg

模式 1:栈对象成员变量(推荐,常驻嵌入)

1. 父窗口头文件 CMainDlg.h

cpp

运行

#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. 窗口缩放自适应 OnSize

cpp

运行

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.h

cpp

运行

#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,否则泄漏按钮 / 事件按需创建手动 DestroyWindow+delete动态切换、临时内嵌界面

关键注意事项

  1. 子对话框资源必须设置:Style=ChildBorder=None,否则无法嵌入;
  2. 容器控件 ID 不能是默认IDC_STATIC,否则无法获取句柄;
  3. 模态对话框DoModal()不能嵌入控件,仅支持Create()非模态子窗口。
http://www.gsyq.cn/news/1606341.html

相关文章:

  • Untrunc视频修复工具终极指南:三步拯救损坏的MP4视频文件
  • 基于图像验证的反钓鱼技术:从视觉特征到工程实践
  • 企业官网做 GEO 时,Schema JSON-LD 应该怎么配合?
  • 新衣洗几次就变旧
  • 计算机毕业设计之基于SSM框架的高校运动会管理系统的设计与实现
  • ChatGPT函数调用可靠性SLO达成率低于89%?用这6个可观测性埋点+Prometheus告警模板,1小时定位根因
  • MCMS v5.4.1文件上传漏洞深度剖析:从代码审计到RCE攻击链构建
  • 气体检测核心器件国产替代:从“卡脖子”到“全自主”还有多远?
  • ChatGPT Plus退订失败?92%用户踩中的5大隐形障碍,含Apple Family Sharing绑定冲突、Stripe支付网关冻结、OpenAI账户状态校验异常(附实时检测命令行工具)
  • YgoMaster终极指南:3种方式快速搭建本地游戏王PvP对战环境
  • Java 开发工具 IDEA 2025.2 社区版完整安装实操指南
  • SSRF漏洞深度解析:从原理到高级绕过与防御实战
  • Hermes Agent 项目深度解析与学习教程
  • 手把手搭建RAG+Agent智能问答Demo(LangChain+Chroma+BGE),附面试深挖清单
  • Grok系列大模型技术解析与实测指南
  • C语言指针详解4
  • 阿里云Linux云服务器部署Oracle数据库完全指南:从环境准备到生产级优化
  • c AI人工智能自发活动视频分析系统的起源 AI人工智能自发活动分析系统
  • 【中小学AI人工智能教育】文本分类任务和情感分析
  • 蓝光3D扫描技术如何打通模具“设计-制造-验证”闭环?
  • 4路24位高精度应变片专用采集卡 力学应变测试闭环解决方案。4路24位4.8Ksps ADC,支持全桥、半桥、1/4桥,4路16位DA,4路DO。
  • Apifox AI 赋能接口测试:从文档解析到自动化用例生成的智能实践
  • CasaOS深度体验:个人云服务器从零搭建到稳定运维全指南
  • Claude Code 安装使用完整教程(2026最新版)
  • Bradykinin (1-6) ;Arg-Pro-Pro-Gly-Phe-Ser
  • Agent 的下半场,该给它装个身体了
  • 企业级智能体如何解决传统自动化的“认知-执行断层”:2026年深度技术拆解与落地指南
  • 获千万级Pre-A轮融资,光速一构要把汽车流水线搬进弹性体3D打印工厂
  • Git 查 Bug 显微镜:如何精准追踪类、结构体与枚举定义的历史变动?
  • C++ ASCII 3D无尽跑酷游戏