WIN32汇编语言教程:第08章 通用对话框 · 8.2 使用通用对话框(3)
结构中关键的字段说明如下。
● Flags——标志,创建对话框的时候,函数根据标志中的数值初始化对话框中各控件的状态,返回的时候根据用户的选择来设置标志字段的内容,标志字段可以是以下取值的组合:
■ FR_FINDNEXT,FR_REPLACE,FR_REPLACEALL,FR_DIALOGTERM——分别表示用户单击了“查找下一个”、“替换”、“全部替换”和“取消”按钮。
■ FR_HIDEUPDOWN,FR_HIDEMATCHCASE与FR_HIDEWHOLEWORD——初始化时使用,表示对话框中不显示“方向”、“区分大小写”与“全字匹配”按钮。
■ FR_NOMATCHCASE,FR_NOUPDOWN与FR_NOWHOLEWORD——初始化时将 “区分大小写”、“方向”与“全字匹配”按钮灰化。
■ FR_MATCHCASE或FR_WHOLEWORD——表示用户选中了“区分大小写”或“全字匹配”复选框。
■ FR_DOWN——把“方向”单选钮设置为“向下”。
● lpstrFindWhat——指向包含查找字符串的指针,缓冲区的长度必须至少为80 B,这个字符串在初始化的时候出现在“查找内容”编辑框中,函数也在这里返回用户输入的内容。
● lpstrReplaceWith——指向包含替换字符串的指针,这个字符串在初始化的时候出现在“替换为”编辑框中,函数也在这里返回用户输入的内容。这个字段在使用FindText函数的时候可以为NULL,但在使用ReplaceText函数的时候必须设置,否则对话框不会显示。
● wFindWhatLen和wReplaceWithLen——lpstrFindWhat和lpstrReplaceWith指示缓存区的长度。
查找和替换通用对话框的使用有些特殊,因为这两种对话框是非模态对话框,也就是说,FindText和ReplaceText函数被调用后,系统显示对话框后马上返回,对话框保持显示状态,直到用户按下了“取消”按钮后对话框才关闭。如果用户按下了对话框中的某个按钮,对话框设置FINDREPLACE结构的相关字段并通过自定义的消息通知父窗口的窗口过程,程序中处理查找和替换的功能集中在这个自定义消息中完成。另外,由于对话框必须向父窗口发送消息,所以hwndOwner字段中必须指定父窗口的句柄,而不能像其他通用对话框一样可以把hwndOwner字段设置为NULL。
为了让对话框能够使用自定义消息,程序必须首先使用RegisterWindowMessage函数注册自定义消息,这个函数注册消息并返回消息ID,输入的参数是消息名称字符串,Microsoft的编程手册中说明要为查找和替换对话框注册FINDMSGSTRING消息,但没有任何资料说明FINDMSGSTRING究竟代表什么,是代表消息名称字符串为“FINDMSGSTRING”吗?不是,实际上它代表字符串“commdlg_FindReplace”,所以,在对话框的初始化消息中如下注册消息:
idFindMessage dd ? FINDMSGSTRING db 'commdlg_FindReplace',0 ... invoke RegisterWindowMessage,addr FINDMSGSTRING mov idFindMessage,eax
注意:要把RegisterWindowMessage函数返回的消息ID保存下来,并在主窗口的消息循环中通过判断uMsg是否等于这个消息ID来判断对话框是否发回消息:
mov eax,uMsg .if eax == WM_XXX ... .elseif eax == idFindMessage .if stFind.Flags & FR_DIALOGTERM ;用户按下了“取消”按钮,对话框关闭 .elseif stFind.Flags & FR_FINDNEXT ;用户按下了“查找下一个”按钮 .elseif stFind.Flags & FR_REPLACE ;用户按下了“替换”按钮 .elseif stFind.Flags & FR_REPLACEALL ;用户按下了“全部替换”按钮 .endif
由于用户按下了“查找下一个”、“替换”、“全部替换”和“取消”等按钮时,对话框都要发回消息,所以在处理时还要根据不同的标志进行不同的处理。
因为查找和替换对话框是非模态对话框,所以使用时要把FINDREPLACE结构和字符串变量放在全局变量中,如果放在局部变量中,对话框还没有关闭的情况下,这些局部变量就已经被释放,以后对话框存取的就会是无效的地址。
8.2.5 页面设置对话框
页面设置对话框用来设置打印机参数,用户可以在对话框中选择打印机、打印纸张大小、页边距和纸张方向,还可以引出一个打印机属性的设置对话框。用户可以在这里完成与打印有关的所有设置工作,页面设置对话框如图8.5所示。
显示页面设置对话框使用PageSetupDlg函数:
invoke PageSetupDlg,lppsd
图8.5 页面设置对话框
lppsd参数指向一个PAGESETUPDLG结构:
PAGESETUPDLGA STRUCT LStructSize DWORD ? ;结构长度 HwndOwner DWORD ? ;所属窗口 HDevMode DWORD ? ;指向DEVMODE结构 HDevNames DWORD ? ;指向DEVNAMES结构 Flags DWORD ? ;标志 PtPaperSize POINT <> ;返回纸张尺寸 RtMinMargin RECT <> ;返回最小允许的页边距 RtMargin RECT <> ;返回用户选择的页边距 HInstance DWORD ? LCustData DWORD ? LpfnPageSetupHook DWORD ? LpfnPagePaintHook DWORD ? LpPageSetupTemplateName DWORD ? HPageSetupTemplate DWORD ? PAGESETUPDLGA ENDS
结构中的有关字段说明如下。
● hDevMode—如果用户选择了打印机,那么这里返回一个指针,指向包含DEVMODE结构的内存块地址,DEVMODE结构中包含了打印机的名称。
● hDevNames—如果用户选择了打印机,那么这里返回一个指针,指向包含DEVNAMES结构的内存块的地址,DEVNAMES结构包含了打印机的各种属性。
● Flags—标志,可以是以下取值的组合:
● PSD_DEFAULTMINMARGINS—将页边距设置为打印机允许的最小页边距。
■ PSD_DISABLEMARGINS,PSD_DISABLEORIENTATION和PSD_DISABLEPAPER—灰化页边距设置输入框、纸张方向选择框和纸张选择框。
■ PSD_DISABLEPAGEPAINTING—不绘画最上方的打印示例图示。
■ PSD_DISABLEPRINTER—灰化“打印机”按钮。
■ PSD_MARGINS—函数用rtMargin字段的值初始化对话框中的数值。
■ PSD_RETURNDEFAULT—函数不显示对话框,马上返回并在hDevNames和hDevMode字段中返回默认打印机的设置情况。
■ PSD_INTHOUSANDTHSOFINCHES和PSD_INHUNDREDTHSOFMILLIMETERS—指明ptPagerSize,rtMinMargen与rtMargin等字段使用的单位是英寸还是毫米。
● ptPaperSize—一个POINT结构,返回纸张大小。
● rtMinMargin—打印机允许的最小页边距。
● rtMargin—用户选择的页边距数据。
当用户选择了打印机时,hDevMode中返回的是一个指向内存块的指针,所以需要用下面的代码获取DEVMODE结构的地址:
mov eax,@stPS.hDevMode mov eax,[eax] ;现在eax是DEVMODE结构的地址
总结通用对话框的使用方法可以发现,每种通用对话框函数都使用一个特定的结构来当做输入输出的缓冲区,初始化的时候函数根据结构中的数据和标志设置对话框中的子窗口控件,返回的时候在结构的相应位置返回用户的输入或选择。另外,所有结构都有几个类似的字段,如lStructSize字段必须设置为正确的结构长度;hwndOwner指定对话框的父窗口,模态对话框在关闭之前是不允许切换到这个父窗口中去的。
上页:第08章 通用对话框 · 8.2 使用通用对话框(2) 下页:第08章 通用对话框 · 8.3 浏览目录对话框(1)