WIN32汇编语言教程:第05章 使用资源 · 5.4 对话框(1)

5.4.1 对话框简介

顾名思义,对话框完成的是“对话”功能,应用程序一般建立一个主窗口用做工作界面,大部分的工作会在主窗口的客户区完成,但程序往往需要和用户交互,如输入参数和输入文本等,这些界面不必要全部放在主窗口中,习惯的做法是通过选择菜单项弹出一个窗口,然后在这个窗口中完成对话,这个窗口就是“对话框”,对话框中的按钮、文本框和图标等称为“子窗口控件”。

为了提示用户,习惯于在会引出对话框的菜单项后面加上省略号。如“文件”菜单中的“另存为...”表示会引出一个选择文件名的对话框,所以“另存为”3个字后面加了个省略号。对话框最典型的例子就是写字板“查找”菜单弹出的窗口以及IE浏览器中选择“Internet选项”菜单项弹出的设置窗口。

1. 对话框的类型

对话框分两类:modal对话框和modeless对话框,翻译成中文就是“模态的”和“非模态的”(也有的地方翻译成“模式的”和“非模式的”,Visual FoxPro中文版就是这样),它们之间的区别在于是否允许用户在不同窗口间进行切换:当显示非模态对话框时,用户可以随意在这个对话框和其他窗口之间切换;而显示一个模态对话框时,用户在关闭对话框之前不允许切换到同一程序的其他窗口中,但可以切换到其他程序的窗口中;如果显示的是操作系统所属的模态对话框(即“系统模态的”),则切换到其他任何程序的窗口都是不允许的。

Windows在资源文件中定义对话框,然后在程序中利用这个模板创建对话框,模态对话框和非模态对话框的资源定义是相同的,只是创建时调用的函数不同而已。

2. 对话框的工作原理

很明显,对话框和普通窗口之间有很多相似之处,实际上对话框就是基于窗口的,对话框的窗口风格使用的就是普通窗口的风格定义,对话框也有一个类似于窗口过程的对话框过程,但对话框和普通窗口在实现上又有很多不同之处,模态对话框和非模态对话框的实现也是不同的,图5.4对比了它们之间的不同之处。普通的窗口在建立之前需要用RegisterClass注册一个窗口类,然后用CreateWindow建立窗口,建立窗口所需的参数如窗口风格、大小位置和窗口过程地址等由窗口类以及CreateWindow中的参数共同提供。

建立对话框的时候并不使用CreateWindow函数,取而代之,建立模态对话框的函数是DialogBoxParam,建立非模态对话框的函数是CreateDialogParam,调用这两个函数创建对话框窗口之前不需要注册对话框的窗口类。


图5.4  对话框和普通窗口工作方式的区别

Windows在这两个函数的内部调用CreateWindowEx来建立对话框,使用的风格、大小和位置等参数取自资源中定义的对话框模板,使用的窗口类则是Windows内部定义的类,如果读者用一些工具去查看,会发现类名是“#32770”之类的字符串,在这个名字奇特的窗口类中,窗口过程被定义到了Windows内部的“对话框管理器”代码中,Windows在这里处理对话框的大部分消息,如维护客户区的刷新,键盘接口(按Tab键在不同子窗口之间切换、按回车调用默认按钮等),对话框管理器在初始化对话框时会根据对话框模板中定义的子窗口控件建立对话框中所有的子窗口。

用户程序中的对话框过程是由对话框管理器调用的,在处理消息前,对话框管理器会先调用用户指定的对话框过程,再根据对话框过程的返回值决定是否处理它们。

Windows对模态对话框和非模态对话框的处理有些不同。在创建并显示模态对话框后,Windows会为它在内部建立一个消息循环,在这个消息循环中把消息发送给对话框管理器,对话框管理器在处理消息的过程中会调用用户定义的对话框过程,当对话框关闭的时候,Windows退出内建的消息循环,并从DialogBoxParam函数返回。而对于非模态对话框,CreateDialogParam函数在创建对话框后直接返回,对话框窗口的消息是通过用户程序中的消息循环派送的。

由于模态对话框的特征,使得用它来做小程序的主窗口非常方便,因为用一句DialogBoxParam函数就可以搞定了,既不用注册窗口类,也不用写消息循环,这对看到创建窗口的几十句代码就烦的读者来说可真是个福音,笔者也很喜欢用模态对话框做程序的主窗口。这种方法的缺点就是无法使用依赖消息循环来完成的功能,很明显,加速键就不能用了。

在接下来的内容中,以一个最简单的例子来讲解如何实现模态对话框,所有的源程序可以在所附光盘的Chapter05\Dialog目录中找到,包括资源脚本文件Dialog.rc,汇编源文件Dialog.asm以及makefile文件,Dialog.exe运行的结果如图5.5所示。

5.4.2 对话框的资源定义

1. 对话框资源定义的语法

在资源脚本中定义对话框的语法是:

对话框ID DIALOG [DISCARDABLE] x坐标, y坐标, 宽度, 高度
[可选属性]
BEGIN
   子窗口控件
   ...
END

对话框中的子窗口控件语句定义在BEGIN/END(当然也可以用花括号)之中,在这之前,可以定义对话框的一些可选属性,每种属性单独用一行定义,常用的可选属性如表5.3所示。

表5.3 对话框的可选属性

属   性定 义 语 法说明
标题文字CAPTION "文字"定义显示在窗口标题栏上的文字
窗口类CLASS "类名"定义对话框窗口使用的窗口类,如果不定义,则使用Windows内建的类
窗口风格STYLE 风格组合定义对话框的窗口风格,同CreateWindowEx中的dwStyle参数
扩展风格EXSTYLE 风格组合定义对话框的扩展窗口风格,同CreateWindowEx中的dwExStyle参数
字体FONT 大小,"字体名"定义对话框包括子窗口控件使用的字体
菜单MENU 菜单ID对话框中使用的菜单,菜单ID在同一个资源脚本文件中定义

在本节的例子中,资源脚本文件Dialog.rc是这样定义的:

//##################################################################
#include          <resource.h>
//##################################################################
#define   ICO_MAIN  0x1000   //图标
#define   DLG_MAIN  1
//##################################################################
ICO_MAIN  ICON      "Main.ico"
//##################################################################
DLG_MAIN DIALOG 50, 50, 113, 64
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "对话框模板"
FONT 9, "宋体"
{
 ICON ICO_MAIN, -1, 10, 11, 18, 21
 CTEXT "简单的对话框例子\n用Win32ASM编写", -1, 36, 14, 70, 19
 DEFPUSHBUTTON "退出(&X)", IDOK, 58, 46, 50, 14
 CONTROL "", -1, "Static", SS_ETCHEDHORZ | WS_CHILD | WS_VISIBLE, 6, 39, 103, 1
}

上页:第05章 使用资源 · 5.3 位图 下页:第05章 使用资源 · 5.4 对话框(2)

第05章 使用资源

版权所有 © 云南伯恩科技 证书:粤ICP备09170368号