我们将进一步学习对话框,探讨如何把对话框当成输入设备。如果您看了前一篇文章,那就会发现这次的例子只有少量的改动,就是把我们的对话框窗口附属到主窗口上。另外,我们还要学习通用对话框的用法。

理论:

把对话框当成一个输入设备来用确实是非常地简单,创建完主窗口后,您只要调用函数 DialogBoxParamCreateDialogParam 就可以了,前一个函数只要在对话框的过程处理函数中处理相关的消息就可以,而后者你必须在消息循环段中插入函数 IsDialogMessage 的调用让它来处理键盘的按键逻辑。因为这两个程序段相对来说比较容易,我们就不详解。您可以下载并仔细研究。

下面我们来讨论通用对话框。WINDOWS已经为您准备好了预定义的对话框类,您可以拿来就用,这些通用对话框提供给用户以统一的界面。它们包括:打开文件、打印、选择颜色、字体和搜索等。您应该尽可能地用它们。处理这些对话框的代码在comdlg32.dll中,为了在您的应用程序中使用它们,就必须在链接阶段链接库文件 comdlg32.lib。然后调用其中的相关函数即可。对于打开文件通用对话框,该函数名为 GetOpenFileName,"保存为..."对话框为 GetSaveFileName,打印通用对话框是 PrintDlg, 等等。每一个这样的函数都接收一个指向一个结构体的指针的参数,您可以参考WIN32 API手册得到详细的资料,本课中我将讲解创建和使用打开文件对话框。

下面是打开对话框函数 GetOpenFileName 的原型:

  1. GetOpenFileName proto lpofn:DWORD

您可以看到,该函数只有一个参数,即指向结构体OPENFILENAME的指针。当用户选择了一个文件并打开,该函数返回TRUE,否则返回FALSE。接下来我们看看结构体OPENFILENAME的定义:

  1. OPENFILENAME STRUCT
  2. lStructSize DWORD ?
  3. hwndOwner HWND ?
  4. hInstance HINSTANCE ?
  5. lpstrFilter LPCSTR ?
  6. lpstrCustomFilter LPSTR ?
  7. nMaxCustFilter DWORD ?
  8. nFilterIndex DWORD ?
  9. lpstrFile LPSTR ?
  10. nMaxFile DWORD ?
  11. lpstrFileTitle LPSTR ?
  12. nMaxFileTitle DWORD ?
  13. lpstrInitialDir LPCSTR ?
  14. lpstrTitle LPCSTR ?
  15. Flags DWORD ?
  16. nFileOffset WORD ?
  17. nFileExtension WORD ?
  18. lpstrDefExt LPCSTR ?
  19. lCustData LPARAM ?
  20. lpfnHook DWORD ?
  21. lpTemplateName LPCSTR ?
  22. OPENFILENAME ENDS

好,我们再来看看该结构体中常用的成员的意义:

  • lStructSize 结构体OPENFILENAME的大小。
  • hwndOwner 拥有打开对话框的窗口的句柄。
  • hInstance 拥有该打开文件对话框的应用程序的实例句柄 。
  • lpstrFilter 以NULL结尾的一个或多个通配符。通配符是成对出现的,前一部分是描述部分,后一部分则是通配符的格式,譬如:
  1. FilterString db "All Files (*.*)",0, "*.*",0
  2. db "Text Files (*.txt)",0,"*.txt",0,0

注意:只有每一对中的第二部分是WINDOWS用来过滤所需选择的文件的,另外您必须在该部分后放置一个0,以示字符串的结束。

  • nFilterIndex 用来指定打开文件对话框第一次打开时所用的过滤模式串,该索引是从1开始算的,即第一个通配符模式的索引是1,第二个是2,譬如上面的例子中,若指定该值为2,则缺省显示的模式串就是"*.txt"。
  • lpstrFile 需要打开的文件的名称的地址,该名称将会出现在打开文件对话框的编辑控件中,该缓冲区不能超过260个字符长,当用户打开文件后,该缓冲区中包含该文件的全路径名,您可以从该缓冲区中抽取您所需要的路径或文件名等信息。
  • nMaxFile lpstrFile的大小。
  • lpstrTitle 指向对话框标题的字符串。
  • Flags 该标志决定决定了对话框的风格和特点。
  • nFileOffset 在用户打开了一个文件后该值是全路径名称中指向文件名第一个字符的索引。譬如:若全路径名为"c:\windows\system\lz32.dll", 则该值为18。
  • nFileExtension 在用户打开了一个文件后该值是全路径名称中指向个文件扩展名第一个字符的索引。

例子:

下例中,我们演示了当用户选择"File->Open"时,将弹出一个打开文件对话框,当用户选择了某个文件打开时,会弹出一个对话框,告知要打开的文件的全路径名,文件名和文件扩展名。

  1. .386
  2. .model flat,stdcall
  3. option casemap:none
  4. WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
  5. include \masm32\include\windows.inc
  6. include \masm32\include\user32.inc
  7. include \masm32\include\kernel32.inc
  8. include \masm32\include\comdlg32.inc
  9. includelib \masm32\lib\user32.lib
  10. includelib \masm32\lib\kernel32.lib
  11. includelib \masm32\lib\comdlg32.lib
  12. .const
  13. IDM_OPEN equ 1
  14. IDM_EXIT equ 2
  15. MAXSIZE equ 260
  16. OUTPUTSIZE equ 512
  17. .data
  18. ClassName db "SimpleWinClass",0
  19. AppName db "Our Main Window",0
  20. MenuName db "FirstMenu",0
  21. ofn OPENFILENAME <>
  22. FilterString db "All Files",0,"*.*",0
  23. db "Text Files",0,"*.txt",0,0
  24. buffer db MAXSIZE dup(0)
  25. OurTitle db "-=Our First Open File Dialog Box=-: Choose the file to open",0
  26. FullPathName db "The Full Filename with Path is: ",0
  27. FullName db "The Filename is: ",0
  28. ExtensionName db "The Extension is: ",0
  29. OutputString db OUTPUTSIZE dup(0)
  30. CrLf db 0Dh,0Ah,0
  31. .data?
  32. hInstance HINSTANCE ?
  33. CommandLine LPSTR ?
  34. .code
  35. start:
  36. invoke GetModuleHandle, NULL
  37. mov hInstance,eax
  38. invoke GetCommandLine
  39. mov CommandLine,eax
  40. invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
  41. invoke ExitProcess,eax
  42. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
  43. LOCAL wc:WNDCLASSEX
  44. LOCAL msg:MSG
  45. LOCAL hwnd:HWND
  46. mov wc.cbSize,SIZEOF WNDCLASSEX
  47. mov wc.style, CS_HREDRAW or CS_VREDRAW
  48. mov wc.lpfnWndProc, OFFSET WndProc
  49. mov wc.cbClsExtra,NULL
  50. mov wc.cbWndExtra,NULL
  51. push hInst
  52. pop wc.hInstance
  53. mov wc.hbrBackground,COLOR_WINDOW+1
  54. mov wc.lpszMenuName,OFFSET MenuName
  55. mov wc.lpszClassName,OFFSET ClassName
  56. invoke LoadIcon,NULL,IDI_APPLICATION
  57. mov wc.hIcon,eax
  58. mov wc.hIconSm,eax
  59. invoke LoadCursor,NULL,IDC_ARROW
  60. mov wc.hCursor,eax
  61. invoke RegisterClassEx, addr wc
  62. invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
  63. WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
  64. CW_USEDEFAULT,300,200,NULL,NULL,\
  65. hInst,NULL
  66. mov hwnd,eax
  67. invoke ShowWindow, hwnd,SW_SHOWNORMAL
  68. invoke UpdateWindow, hwnd
  69. .WHILE TRUE
  70. invoke GetMessage, ADDR msg,NULL,0,0
  71. .BREAK .IF (!eax)
  72. invoke TranslateMessage, ADDR msg
  73. invoke DispatchMessage, ADDR msg
  74. .ENDW
  75. mov eax,msg.wParam
  76. ret
  77. WinMain endp
  78. WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  79. .IF uMsg==WM_DESTROY
  80. invoke PostQuitMessage,NULL
  81. .ELSEIF uMsg==WM_COMMAND
  82. mov eax,wParam
  83. .if ax==IDM_OPEN
  84. mov ofn.lStructSize,SIZEOF ofn
  85. push hWnd
  86. pop ofn.hwndOwner
  87. push hInstance
  88. pop ofn.hInstance
  89. mov ofn.lpstrFilter, OFFSET FilterString
  90. mov ofn.lpstrFile, OFFSET buffer
  91. mov ofn.nMaxFile,MAXSIZE
  92. mov ofn.Flags, OFN_FILEMUSTEXIST or \
  93. OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
  94. OFN_EXPLORER or OFN_HIDEREADONLY
  95. mov ofn.lpstrTitle, OFFSET OurTitle
  96. invoke GetOpenFileName, ADDR ofn
  97. .if eax==TRUE
  98. invoke lstrcat,offset OutputString,OFFSET FullPathName
  99. invoke lstrcat,offset OutputString,ofn.lpstrFile
  100. invoke lstrcat,offset OutputString,offset CrLf
  101. invoke lstrcat,offset OutputString,offset FullName
  102. mov eax,ofn.lpstrFile
  103. push ebx
  104. xor ebx,ebx
  105. mov bx,ofn.nFileOffset
  106. add eax,ebx
  107. pop ebx
  108. invoke lstrcat,offset OutputString,eax
  109. invoke lstrcat,offset OutputString,offset CrLf
  110. invoke lstrcat,offset OutputString,offset ExtensionName
  111. mov eax,ofn.lpstrFile
  112. push ebx
  113. xor ebx,ebx
  114. mov bx,ofn.nFileExtension
  115. add eax,ebx
  116. pop ebx
  117. invoke lstrcat,offset OutputString,eax
  118. invoke MessageBox,hWnd,OFFSET OutputString,ADDR AppName,MB_OK
  119. invoke RtlZeroMemory,offset OutputString,OUTPUTSIZE
  120. .endif
  121. .else
  122. invoke DestroyWindow, hWnd
  123. .endif
  124. .ELSE
  125. invoke DefWindowProc,hWnd,uMsg,wParam,lParam
  126. ret
  127. .ENDIF
  128. xor eax,eax
  129. ret
  130. WndProc endp
  131. end start
  1. ;--------------------------------------------------------------------------------
  2. ;menu.rc
  3. ;--------------------------------------------------------------------------------
  4. #define IDM_OPEN 1
  5. #define IDM_EXIT 2
  6. FirstMenu MENU
  7. {
  8. MENUITEM "&Open",IDM_OPEN
  9. MENUITEM "E&xit",IDM_EXIT
  10. }

分析:

  1. mov ofn.lStructSize,SIZEOF ofn
  2. push hWnd
  3. pop ofn.hwndOwner
  4. push hInstance
  5. pop ofn.hInstance

我们在此填充结构体OPENFILENAME变量ofn的有关成员。

  1. mov ofn.lpstrFilter, OFFSET FilterString

这里FilterString 是文件过滤模式的字符串地址,我们指定的过滤模式字符串如下:

  1. FilterString db "All Files",0,"*.*",0
  2. db "Text Files",0,"*.txt",0,0

注意:所有的模式串都是配对的,前一个是描述,后一个才是真正的模式,此处*.**.txt是WIONDOWS用来寻找匹配的欲打开的文件的。我们当能可以指定任何模式,但是不要忘记在结尾处加0以代表字符串已结束,否则您的对话框在操作时可能不稳定。

  1. mov ofn.lpstrFile, OFFSET buffer
  2. mov ofn.nMaxFile,MAXSIZE

这里是把缓冲区的地址放到结构体中,同时必须设定大小。以后我们可以随意编辑在该缓冲区中返回的信息。

  1. mov ofn.Flags, OFN_FILEMUSTEXIST or \
  2. OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
  3. OFN_EXPLORER or OFN_HIDEREADONLY

Flags 中放入的是对话框的风格和特性值。

其中OFN_FILEMUSTEXISTOFN_PATHMUSTEXIST要求用户在打开对话框的编辑控件中输入的文件名或路径名必须存在。

OFN_LONGNAMES 告诉对话框显示长文件名。

OFN_EXPLORER 告诉WINDOWS对话框的外观必须类似资源管理器。

OFN_HIDEREADONLY 指定不要显示只读文件(既使它的扩展名符合过滤模式)。

除此之外,还有许多其它的标志位,您可以参考有关WIN32 API手册。

  1. mov ofn.lpstrTitle, OFFSET OurTitle

指定打开文件对话框的标题名。

  1. invoke GetOpenFileName, ADDR ofn

调用GetOpenFileName函数,并传入指向结构体ofn的指针。

这时候,打开文件对话框就显示出来了,GetOpenFileName函数要一直等到用户选择了一个文件后才会返回,或者当用户按下了CANCEL键或关闭对话框时。

当用户选择了打开一个文件时,该函数返回TRUE, 否则返回FALSE

  1. .if eax==TRUE
  2. invoke lstrcat,offset OutputString,OFFSET FullPathName
  3. invoke lstrcat,offset OutputString,ofn.lpstrFile
  4. invoke lstrcat,offset OutputString,offset CrLf
  5. invoke lstrcat,offset OutputString,offset FullName

当用户选择打开一个文件时,我们就在一个对话框中显示一个字符串,我们先给OutputString变量分配内存,然后调用PAI 函数lstrcat,把所有的字符串连到一起,为了让这些字符串分行显示,我们必须在每个字符串后面加一个换行符。

  1. mov eax,ofn.lpstrFile
  2. push ebx
  3. xor ebx,ebx
  4. mov bx,ofn.nFileOffset
  5. add eax,ebx
  6. pop ebx
  7. invoke lstrcat,offset OutputString,eax

上面这几行可能需要一些解释。nFileOffset的值等于被打开文件的全路径名中的文件名的第一个字符的索引,由于nFileOffset是一个WORD型变量,而lpstrFile是一个DWORD型的指针,所以我们就要作一转换把nFileOffset存入ebx寄存器的底字节,然后再加到eax寄存器中得到DWORD型的指针。

  1. invoke MessageBox,hWnd,OFFSET OutputString,ADDR AppName,MB_OK

我们在对话框中显示该字符串。

  1. invoke RtlZerolMemory,offset OutputString,OUTPUTSIZE

为了下一次能正确地显示,必须清除缓冲区,我们调用函数RtlZerolMemory来做这件事。

Win32汇编学习(11):对话框(2)的更多相关文章

  1. Win32汇编学习(4):绘制文本

    这次,我们将学习如何在窗口的客户区"绘制"字符串.我们还将学习关于"设备环境"的概念. 理论: "绘制"字符串 Windows 中的文本是一 ...

  2. Win32汇编学习(5):绘制文本2

    这次我们将学习有关文本的诸多属性如字体和颜色等. 理论: Windows 的颜色系统是用RGB值来表示的,R 代表红色,G 代表绿色,B 代表蓝色.如果您想指定一种颜色就必须给该颜色赋相关的 RGB ...

  3. Win32汇编学习(1):基本概念

    背景知识 Windows 把每一个 Win32 应用程序放到分开的虚拟地址空间中去运行,也就是说每一个应用程序都拥有其相互独立的 4GB 地址空间,当然这倒不是说它们都拥有 4GB 的物理地址空间,而 ...

  4. Win32汇编学习(10):对话框(1)

    现在我们开始学习一些有关GUI编程的有趣的部分:以对话框为主要界面的应用程序. 理论: 如果您仔细关注过前一个程序就会发现:您无法按TAB键从一个子窗口控件跳到另一个子窗口控件,要想转移的话只有 用鼠 ...

  5. Win32汇编学习(3):简单的窗口

    这次我们将写一个 Windows 程序,它会在桌面显示一个标准的窗口,以此根据代码来学习如何创建一个简单的窗口. 理论: Windows 程序中,在写图形用户界面时需要调用大量的标准 Windows ...

  6. win32 汇编学习(2):消息框

    这一次,我们将用汇编语言写一个 Windows 程序,程序运行时将弹出一个消息框并显示"你好,我的第一个Win32汇编程序". 理论知识 Windows 为编写应用程序提供了大量的 ...

  7. Win32汇编学习(9):窗口控件

    这次我们将探讨控件,这些控件是我们程序主要的输入输出设备. 理论: WINDOWS 提供了几个预定义的窗口类以方便我们的使用.大多数时间内,我们把它们用在对话框中,所以我们一般就它们叫做子窗口控件.子 ...

  8. Win32汇编学习(8):菜单

    这次我们将在我们的应用程序中加入一个菜单. 理论: 菜单可以说是WINDOWS最重要的元素之一.有了它,用户可以方便地选择操作命令.用户只要细读一下所有的菜单项就可以明了应用程序所提供的大概功能,而且 ...

  9. Win32汇编学习(7):鼠标输入消息

    这次我们将学习如何在我们的窗口过程函数中处理鼠标按键消息.例子演示了如何等待鼠标左键按下消息,我们将在按下的位置显示一个字符串. 理论: 和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到 ...

随机推荐

  1. IsWindowVisible

    IsWindowVisible通过该函数可以获得指定窗口的可视状态,即显示或者隐藏. BOOL IsWindowVisible( HWND hWnd ); hWnd:被测试窗口的句柄. 返回值:如果指 ...

  2. js 判断js,css是否引入,确保不重复引入

      基本原理:function loadjscssfile(filename, filetype){if (filetype=="js"){ //if filename is a ...

  3. 根据某个字段去重 根据另一个字段排序的一个SQL

    背景:一张表 有 name , crt_time , work_sts 三个字段 这张表里存在这样的数据 'a', '2018-12-18 21:37:24', '未''a', '2018-12-19 ...

  4. 网络爬虫基础知识(Python实现)

    浏览器的请求 url=请求协议(http/https)+网站域名+资源路径+参数 http:超文本传输协议(以明文的形式进行传输),传输效率高,但不安全. https:由http+ssl(安全套接子层 ...

  5. mui 弹窗提醒,form表单基本信息

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  6. Linux命令vi/vim 使用方法讲解

    vi/vim 基本使用方法 vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的 ...

  7. python基础,if语句,while循环

    if语句: ①2选一                                              ④多选一 if:     条件                              ...

  8. [ssh] 通过ssh私钥生成公钥的方法

    ssh-keygen -y -f .ssh/id_rsa.key id_rsa.key是私钥.

  9. Grafana 安装及 Windows 应用程序服务配置工具 NSSM使用

    网址:https://blog.csdn.net/kk185800961/article/details/83515382 1.进入conf文件,将 defaults.ini 复制一份,命名为cust ...

  10. TableExport导出失败问题

    本周有一个需求,将一个网页上一个js导出成csv文件,供数据分析使用 找到一个插件,TableExport,可以很方便的将table导出(默认设置的话,仅需一行代码) 但是,这导出文件较大(6.2M) ...