【windows编程之对话框】对话框原理,对话框的创建

简介: 【windows编程之对话框】对话框原理,对话框的创建

引言

在本章节中我们来讲解Windows/Win32编程中对话框的原理和对话框的创建,我们在前几篇章节中讲解到了普通窗口中回调函数的处理,在普通窗口的窗口消息处理函数(回调函数)中,系统会首先调用我们自己写的回调函数,我们自己编写的回调函数没有处理的消息,才会交给系统的缺省函数处理,但是对话框中消息处理机制不同,系统会首先调用系统中的回调函数,在缺省函数中没有处理的消息,才会寻找我们自己写的回调函数去处理。简单来说,在普通窗口中是我们自己写的回调函数调用系统缺省回调函数,而在对话框中,是系统的缺省函数调用我们字节写的回调函数。

我们来编写一段伪代码来帮助大家理解:

普通窗口:

WndProc(...){
  ...    //我们自己写的回调函数过程
  DefWinsowsProc(...);     //之后调用系统缺省回调函数
}

而在对话框中,是系统的缺省函数调用我们写的回调函数:

缺省函数( ... ){
  ...     //系统写好的处理过程
  自定义回调函数;    //我们自己写的回调函数
}

一.对话框原理

1.对话框的分类

  • 模式对话框
    当对话框显示时,会禁止其他窗口和用户进行交互
  • 无模式对话框/非模式对话框
    当窗口显示后,其他窗口仍可以与用户进行交互

2.对话框的基本使用

  • 1.对话框消息处理函数
    我们在前面的章节中讲解过在系统内核中,局部窗口类,全局窗口类,系统窗口类的保存方式,这个对话框处理函数,就是保存于系统窗口类,我们给出一张图来帮助大家理解:

    我们来看看对话框窗口处理函数的过程:
    我们来通过一段伪代码来讲解:
缺省函数(。。。){
.....       //系统定义好的处理过程
if(DigProc){
我们自己写的窗口消息处理函数。
return 。。。;
}
......        //后续的缺省消息处理过程
};
  • 2.注册窗口类(程序员一般不适用)
  • 3.创建对话框
  • 4.对话框的关闭

2.自定义对话框窗口消息处理函数

既然我们可以自己定义回调函数,那么我们来看看在对话框中我们到底该怎么编写回调函数:

MSDN官方文档解释DigProc回调函数

  • 应用程序定义的回调函数与CreateDialoc函数和DialocBox函数系列一起使用(我们后文会讲到)。它处理发送到模式或无模式对话框的消息。DLGPROC类型定义指向此回调函数的指针。
  • 语法:
    INT_PTR DlgProc( HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){...}
    其中,hWnd指定对话框的句柄,uMsg是消息,wParam和lParam都是消息的附加信息。
    一般情况下,如果此回调函数(我们自定义的回调函数)处理了消息,则对话框过程应返回TURE,如果未处理,则返回FALSE。如果对话框过程返回FALSE,对话管理器将执行默认对话操作以响应消息。

二.模式对话框

- 1.创建对话框

通过DialogBox函数来创建,我们来看看这个函数:

MSDN官方文档解释DialogBox函数

  • 函数功能:从对话框模板资源创建模式对话框

语法:

void DialogBox(
  HINSTANCE hInstance,          //包含对话框模板的模块的句柄
  LPCTSTR lpTemplate,           //对话框模板
  HWND hWndparent,              //拥有对话框的窗口句柄
  DIGPROC lpDialogFunc          //指向对话框过程的指针
};

DialogBox函数是一个阻塞函数,只有当对话框关闭后,才会返回,执行后续代码

返回值通过EndDialog函数设置

- 2.对话框的关闭

关闭模式对话框,使用EndDialog函数,不能使用DwstroyWindow函数(原因我们后文会讲到)。

MSDN官方文档解释EndDialog函数

  • 函数功能:销毁模式对话框,导致系统结束对对话框的任何处理
  • 语法:
BOOL EndDialog(
  HWND hDlg,              //要销毁的对话框的句柄
  INT_PTR nResult         //要从创建对话框的函数返回到应用程序的值
);

注意这里的nResult参数,它是DialogBox函数退出时的返回值,我们前面讲到DialogBox是一个阻塞函数,我们可以通过EndDialog函数来设置DialogBox函数返回的值,通过不同的返回值,我们可以做不同的事。

- 3.对话框消息

WM_INITDIALOG–对话框创建之后,在对话框显示之前,通知对话框窗口处理函数的消息,我们可以在此消息中完成自己初始化相关的工作。

三.模式对话框创建过程实践

我们来带领大家一步一步创建模式对话框:

  • 1.我们需要模式对话框,首先我们肯定需要一个菜单资源,我这里用的是之前文章内容中的菜单资源,怎样添加资源,如果大家不会的话可以到Windows编程资源,菜单资源,图标资源,光标资源,上下文菜单,字符串资源,加速键资源
    文章中学习。
  • 2.创建了菜单资源后,我们还需要做出一个i对话框资源:
    添加->资源->Dialog资源
    这里我就使用程序初始化时的模式对话框了,至于模式对话框之后的创建按钮,我们后续会讲到
  • 3.做好前两步之后,我们来到普通窗口回调函数来处理消息,我们的需求是当点击菜单中的关于按钮后,出现这个模式对话框
    我们先来到普通窗口的回调函数来处理点击帮助按钮的消息:这里给出的是命令消息的全部处理,帮助按钮的消息处理在第三个分支
case WM_COMMAND: {
    switch(LOWORD(wParam)) {
      case MY_OPEN: {
        sprintf(output, "打开按钮被点击,请到回调函数中做具体处理。\n");
        WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
        break;
      }
      case MY_QUIT: {
        sprintf(output, "退出按钮被点击,请到回调函数中做具体处理。\n");
        WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
        break;
      }
      case IDM_ABOUT: {
        sprintf(output, "帮助按钮被点击,请到回调函数中做具体处理。\n");
        WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
        int nResult = DialogBox(hIns, (char*)IDD_ABOUTBOX, hwnd, DiaLogProc);
        if (nResult == 100) {
          MessageBox(hwnd, "Success", "Infor", MB_OK);
        }
      }
      case MY_NEWFILE: {
        sprintf(output, "打开新文件按钮被点击,请到回调函数中做具体处理。\n");
        WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
        break;
      }
      case MY_LASTTIMEFILE: {
        sprintf(output, "上次打开文件按钮被点击,请到回调函数中做具体处理。\n");
        WriteConsole(g_hOUTPUT, output, strlen(output), 0, 0);
        break;
      }
    }
    break;
  }

我们来看看处理效果:

我们在程序运行起来之后,我们发现一个问题:程序无法退出,这时候我们就需要来到模式对话框的回调函数来处理这个关闭模式对话框的消息了:

INT CALLBACK DiaLogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch (uMsg){
  case WM_SYSCOMMAND:{
    if (wParam = WM_CLOSE) {
      EndDialog(hwndDlg, 100);
    }
    break;
    }
  }
  return FALSE;
}

这时候我们发现就可以正常退出程序了。

四.无模式对话框

  • 创建对话框:
HWND CreateDialog(
  HINSTANCE hInstance,          //包含对话框模板的模块句柄
  LPCTSTR lpTemplate,           //对话框模板
  HWND hWndParent,              //拥有对话框的窗口句柄
  DLGPROC lpDialogFunc          //指向对话框过程的指针
);

MSDN官方文档解释CreateDialog函数

该函数为非阻塞函数,创建成功后返回窗口句柄,需要使用ShowWindow函数来显示对话框

  • 非模式对话框的关闭:
    关闭非模式对话框,需要使用DestroyWindow函数来销毁窗口,不能使用EndDialog函数来关闭对话框。

今天的分享就到这里,如果文章中有错误之处,还请大家指出来,我会非常虚心地学习,希望我们共同进步!!!

相关文章
|
19天前
|
安全 前端开发 Windows
Windows Electron 应用更新的原理是什么?揭秘 NsisUpdater
本文介绍了 Electron 应用在 Windows 中的更新原理,重点分析了 `NsisUpdater` 类的实现。该类利用 NSIS 脚本,通过初始化、检查更新、下载更新、验证签名和安装更新等步骤,确保应用的更新过程安全可靠。核心功能包括差异下载、签名验证和管理员权限处理,确保更新高效且安全。
27 4
Windows Electron 应用更新的原理是什么?揭秘 NsisUpdater
|
3月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
3月前
|
Windows
[原创]用MASM32编程获取windows类型
[原创]用MASM32编程获取windows类型
|
3月前
|
JavaScript 前端开发 API
MASM32编程通过WMI获取Windows计划任务
MASM32编程通过WMI获取Windows计划任务
|
2月前
|
API Windows
Windows之窗口原理
这篇文章主要介绍了Windows窗口原理和如何使用Windows API创建和管理窗口。
57 0
|
3月前
|
存储 安全 程序员
Windows任务管理器开发原理与实现
Windows任务管理器开发原理与实现
|
3月前
|
API Windows
MASM32编程获取Windows当前桌面主题名
MASM32编程获取Windows当前桌面主题名
|
4月前
|
编译器 开发工具 C语言
解锁QtCreator跨界神技!Windows下轻松驾驭OpenCV动态库,让你的跨平台开发如虎添翼,秒变视觉编程大师!
【8月更文挑战第4天】QtCreator是一款强大的跨平台IDE,便于创建多平台应用。本教程教你如何在Windows环境下集成OpenCV库至Qt项目。首先,下载匹配MinGW的OpenCV预编译版并解压。接着,在QtCreator中新建或打开项目,并在.pro文件中添加OpenCV的头文件和库文件路径。确保编译器设置正确。随后编写测试代码,例如加载和显示图片,并进行编译运行。完成这些步骤后,你就能在QtCreator中利用OpenCV进行图像处理开发了。
233 6
|
4月前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
289 0
|
6月前
|
Java C++
jni编程(windows+JDK11+clion)
jni编程(windows+JDK11+clion)