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

非模态对话框

书籍:《Visual C++ 2017从入门到精通》的2.3.8 Win32控件编程

环境:visual studio 2022

内容:【例2.39】非模态对话框

说明:以下内容大部分来自腾讯元宝。

手动创建文件子菜单

1.点击资源视图,找到项目对应的Menu目录,点击IDC_TEST230打开菜单,点击“请在此处键入”后,输入“非模态对话框”,创建一个子菜单,成功后,可以右击该子菜单->属性,然后可以修改子菜单名字及ID.(编辑好后必须要保存,否则程序中出现会找不到对应的ID等异常。)

手动创建对话框

同样在资源视图,找到项目对应的Dialog目录,右击->插入,插入一个新的对话框。

在父窗口创建对话框

1. IDM_MODLESS是点击非模态对话框菜单后产生的消息,点击该菜单后,创建对话框绑定自定义的对话框回调函数DialogProc(),然后显示。

case WM_COMMAND:
    {
        int wmId = LOWORD(wParam);
        // 分析菜单选择:
        switch (wmId)
        {
        //处理菜单项 IDM_MODLESS 的点击事件,实现非模态对话框的动态创建与销毁
        case IDM_MODLESS:
            /*销毁已存在的非模态对话框
                功能:确保每次点击菜单时,先关闭已打开的非模态对话框,避免多个实例重叠。
                ​技术要点:
                非模态对话框必须通过 DestroyWindow 关闭(模态对话框使用 EndDialog)。
                销毁后需将句柄设为 NULL(代码中未显式体现,需补充)以避免悬挂指针。*/
            if (hDlgModeless)
            {
                DestroyWindow(hDlgModeless);
                hDlgModeless = NULL;
            }

            /*创建新的非模态对话框
                参数解析:
                hInst:应用程序实例句柄,用于加载对话框资源。
                MAKEINTRESOURCE(IDD_DIALOG1):将对话框资源 ID 转换为系统可识别的格式。
                hWnd:父窗口句柄,非模态对话框需指定父窗口以支持 Z 顺序和消息路由。
                DialogProc:对话框过程函数,处理 WM_INITDIALOG、WM_COMMAND 等消息。
                ​返回值检查:若创建失败(如资源未加载),则直接退出菜单命令处理流程。*/
            hDlgModeless = CreateDialog(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DialogProc);
            if (!hDlgModeless)
            {
                break;
            }

            /*显示与更新对话框
                ** ShowWindow** :将对话框显示在屏幕上,SW_SHOW 表示正常显示。
                ​** UpdateWindow** :强制立即发送 WM_PAINT 消息,确保对话框内容立即更新(避免闪烁)。*/
            ShowWindow(hDlgModeless, SW_SHOW);
            UpdateWindow(hDlgModeless);

            break;
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
    }
    break;

对话框回调函数DialogProc

DialogProc()中处理当对话框被创建的时候的WM_INITDIALOG消息,简单设置了对话框的位置;同时如果用户点击了OK或CANCEL按钮后调用DestroyWindow()来销毁非模态对话框。

//DialogProc 是Windows对话框回调函数,用于处理对话框消息。
//​参数:
//hWnd:对话框窗口句柄。
//uMsg:当前处理的消息类型(如WM_INITDIALOG、WM_COMMAND等)。
//wParam和lParam:携带消息特定参数(如控件ID、按键代码等)。
INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        /*功能:对话框初始化时触发,将对话框窗口移动到屏幕坐标(200, 200)。
            ​关键点:
            SetWindowPos的SWP_NOSIZE标志表示不改变窗口尺寸。
            返回TRUE表示已处理初始化消息,但需注意:若需自定义控件焦点,应返回FALSE并手动调用SetFocus。*/
    case WM_INITDIALOG:
        SetWindowPos(hWnd, NULL, 200, 200, 0, 0, SWP_NOSIZE);
        return TRUE;


    case WM_COMMAND:
        /*功能:处理用户交互(如点击OK或取消按钮)。
            ​关键点:
            LOWORD(wParam)提取控件ID,判断是否为退出按钮。
            DestroyWindow用于关闭非模态对话框​(hDlgModeless需提前保存对话框句柄)。
            返回TRUE表示消息已处理,对话框管理器不再转发该消息。*/
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            DestroyWindow(hDlgModeless);
            hDlgModeless = NULL;

        }
        return TRUE;

        /*功能:对话框销毁时触发,清理资源。
            ​关键点:
            将hDlgModeless设为NULL,避免悬挂指针。
            返回TRUE表示消息已处理。*/
    case WM_DESTROY:
        hDlgModeless = NULL;
        return TRUE;
    
    }
    //功能:对于未显式处理的消息(如WM_CLOSE、WM_PAINT等),返回FALSE由对话框管理器(DefWindowProc)处理。
    return FALSE;
}

主循环

在主循环中,通过hDlgModeless和IsDialogMessage()筛选优先处理对话框的消息。

// 主消息循环:
while (GetMessage(&msg, nullptr, 0, 0))
{
    /*对话框消息过滤
        ​** hDlgModeless** :非模态对话框的句柄,需确保其有效性。
        ​** IsDialogMessage** :
        仅处理属于指定对话框的消息(如WM_KEYDOWN转换为控件选择)。
        若消息不属于对话框(如WM_CLOSE),返回FALSE,进入后续处理流程。
        ​逻辑意义:优先由对话框自身处理消息,避免父窗口拦截对话框专用消息。*/
    if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    
}

相关内容 

详细介绍MAKEINTRESOURCE-CSDN博客https://blog.csdn.net/qq_20725221/article/details/146275158?sharetype=blogdetail&sharerId=146275158&sharerefer=PC&sharesource=qq_20725221&spm=1011.2480.3001.8118

相关文章:

  • Linux内核IPoIB驱动中的RSS队列选择机制分析
  • Python算法竞赛实战解题策略与技巧
  • 011【fate/extra link】【概率论与数理统计】大数定律与中心极限定理 ,数理统计的基本概念,常用的统计三大分布,正态总体的抽样分布定理
  • 机器学习编译器(二)
  • TBOX+OTA+UDS
  • 《蓝耘容器全栈技术指南:企业级云原生与异构计算实战大全》
  • 深入理解C/C++堆数据结构:从原理到实战
  • R语言零基础系列教程-03-RStudio界面介绍与关键设置
  • Python----数据分析(Pandas二:一维数组Series,Series的创建,Series的属性,Series中元素的索引与访问)
  • STM32 —— 嵌入式系统、通用计算机系统、物联网三层架构
  • 大模型token和字符串的关系
  • 深入理解 GPU 渲染加速与合成层
  • c语言笔记 作用域
  • python脚本实现服务器内存和cpu使用监控,并记录日志,可以设置阈值和采样频率
  • MySQL复习(检查本地MySQL是否安装、DataGrip数据库可视化工具使用、增删改查基础语法、唯一索引、SQL简单函数)
  • 单片机自学指南
  • Apifox Helper 自动生成API接口文档
  • 基于“动手学强化学习”的知识点(六):第 19 章 目标导向的强化学习(gym版本 >= 0.26)
  • 强大的CSS变量
  • 华发股份:多元业务协同赋能 财务稳健护航高质量发展
  • 上海环球马术冠军赛开赛,一场体育与假日消费联动的狂欢
  • 巴菲特执掌60年,伯克希尔市值如何增长5.5万倍?详解五大经典投资案例
  • 韩国前国务总理韩德洙正式宣布参加总统选举
  • 武汉大学新闻与传播学院已由“80后”副院长吴世文主持工作
  • “译通天下·言立寰宇”:华东师大翻译家的精神传承
  • 马克思主义理论研究教学名师系列访谈|丁晓强:马克思主义学者要更关注社会现实的需要