用汇编轻松地写基于对话框的程序


  • 设计程序界面
    • 和在VC中一样,界面(对话框已经各种控件)一般是以资源的方式存在的。编辑资源文件完全可以使用VC的资源编辑器。但是熟悉一下资源文件的写法及意义是编程所必须的。下面是一个资源文件的例子:

      #include "/masm32/include/resource.h"
      #define IDC_EDIT 3000
      #define IDC_BUTTON 3001
      #define IDC_EXIT 3002
      MyDialog DIALOG 10, 10, 205, 60
      STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
      WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
      CAPTION "我的对话框"
      {
      EDITTEXT IDC_EDIT, 15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
      DEFPUSHBUTTON "显示编辑框中的内容", IDC_BUTTON, 141,10,52,13
      PUSHBUTTON "退出程序", IDC_EXIT, 141,26,52,13
      }

      记住,在使用QE时为了使得编译成功,必须将它保存为rsrc.rc这个文件名(使用命令行就无所谓了)。选择Project->Compile Resource File。资源文件就编译成功了,就可以被连接使用了。建议你用VC的资源编辑器打开这个资源文件看看。

      第一行的#include "/masm32/include/resource.h"就和C一样,是包含一个头文件,这个文件中有各种常数的定义,如PUSHBUOTTON等,感兴趣的话,可以打开这个文件看看。

      接下来定义了一些常数,就和C中的用法一样,是为了增强程序的可读性。

      "MyDialog DIALOG 10, 10, 205, 60"这一句用DIALOG这个关键字定义一个名为MyDialog的对话框,名字当然可以随便取。后面的4个数字是对话框的位置大小,一般是在资源编辑器中调试。

      "STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK "是描述对话框的风格的。如WS_MINIMIZEBOX是说有最小化按钮。DS_3DLOOK是说对话框是3D外形的等等。这些一般在资源编辑器中改动,各种常数的意义,可以在MSDN中查找。

      CAPTION "我的对话框"就是指定对话框的标题是"我的对话框"

      再下面用{}框起来的就是对话框中的各个控件。这个例子中用到了EDITTEXT编辑框控件,PUSHBUTTON按钮控件,DEFPUSHBUTTON默认按钮控件(默认选中状态),IDC_EDIT,IDC_EXIT,IDC_BUTTON分别是他们3个的ID号,注意上面的定义,是不能相同的。不一定非要使用#define来预先定义,使用数字也可以,前者可以增强程序的可读性。其他的很多控件如单选框,复选框等等的使用可以在资源编辑器下编辑后查看源代码获得。

      程序的界面就设计完了,接下来是设计程序。

  • 程序的设计
    • 我们来做一个简单的程序,在按下“显示编辑框中的内容”这个按钮时,将弹出一个消息框显示现在编辑框中的内容。按“退出程序”按钮将退出程序。


      .386
      .model flat,stdcall
      option casemap:none

      DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD

      include /masm32/include/windows.inc
      include /masm32/include/user32.inc
      include /masm32/include/kernel32.inc
      includelib /masm32/lib/user32.lib
      includelib /masm32/lib/kernel32.lib

      .data
      DlgName db "MyDialog",0
      AppName db "My own dialog",0

      .data?
      hInstance HINSTANCE ?
      buffer db 512 dup(?)

      .const
      IDC_EDIT            equ 3000
      IDC_BUTTON     equ 3001
      IDC_EXIT            equ 3002

      .code
      start:
          invoke GetModuleHandle, NULL
          mov    hInstance,eax
          invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL
          invoke ExitProcess,eax

      DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
          .IF uMsg==WM_INITDIALOG
              invoke GetDlgItem, hWnd,IDC_EDIT
              invoke SetFocus,eax
          .ELSEIF uMsg==WM_CLOSE
              invoke EndDialog, hWnd,NULL
          .ELSEIF uMsg==WM_COMMAND
              mov eax,wParam
                  .IF eax==IDC_BUTTON
                      invoke GetDlgItemText,hWnd,IDC_EDIT,ADDR buffer,512
                      invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK
                 .ELSEIF ax==IDC_EXIT
                          invoke EndDialog, hWnd,NULL
                  .ENDIF
          .ELSE
              mov eax,FALSE
              ret
          .ENDIF
          mov eax,TRUE
          ret
      DlgProc endp
      end start

      猛一看,这个程序挺长的,如果用VB实现这个功能的话,大概只需要写5-6行。但是,这个程序中相当一部分代码是固定的,也就是说,写任何基于对话框的程序都需要这样写。VB中正是VB的编译器自动帮你做了这些工作。

      .386; 声明使用386指令系统
      .model flat,stdcall;声明内存的寻址方式
      option casemap:none;声明是否对大小写敏感

      ;上面3行可以认为是固定的,必须的

      DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD

      ;..........此处声明自己定义的函数,上面的这个是对话框的主函数(必须有),名字可以换成别的

      include /masm32/include/windows.inc
      include /masm32/include/user32.inc
      include /masm32/include/kernel32.inc
      includelib /masm32/lib/user32.lib
      includelib /masm32/lib/kernel32.lib

      ;...........此处包含需要的头文件,上面几个是最长用到的

      .data
      DlgName db "MyDialog",0
      AppName db "My own dialog",0
      ;............这里定义各个预先赋值的变量,db是定义一个字节长,dw是定义一个字长等等,还有很多类型的宏定义,包含在windows.h中。

      .data?
      hInstance HINSTANCE ?
      ;............这里定义各个变量,但是是没有预先赋值的

      .const
      ;..........如果需要预先定义一些常量,放在这段里面,用关键字equ定义

      .code ;以下就是代码段,注意函数也是放在代码段里面的!
      start:;不一定非要使用start,可以是任何的字符串如begin,entry等等。
          invoke GetModuleHandle, NULL
          mov    hInstance,eax
          invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL
          invoke ExitProcess,eax

      上面的几行也是比较固定的,invoke是用来调用函数的,用过VB的人都知道call,这就相当于那个命令

      DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
      ;..............这是你主要集中精力要写的地方

      DlgProc endp
      end start;主要和上面的start对应

      基本上,你可以把上面的绿色部分当作模版使用,只需要在.data和.data?以及.const段增加你所需要的变量和常量就可以了。剩下的任务就是写上面红色的部分,也就是处理各个消息。

      我们来分析几个消息,在调用DialogBoxPrarm创建对话框后,对话框会收到WM_INITDIALOG即对话框初始化消息,uMsgz这个参数接受到消息。在这个程序中,我们用GetDlgItem这个函数来取得编辑框控件的句柄,然后调用SetFocus来将焦点设置在它上面。注意这些函数都是API函数,这些函数的意义都可以在msdn中找到。

      当按下对话框右上角的关闭按钮时,会产生WM_CLOSE,必须处理这个函数,否则不能用×来关闭对话框(这是由于内置的函数没有设计处理这个消息),而对于最大化最小化等消息则有默认的处理。

      当按下对话框上的按钮时会产生WM_COMMAND消息,并且wParam中传递的是控件的ID。根据不同的ID完成不同的功能,在本例中如果是IDC_BUTTON这个ID说明是显示编辑框内容的控件按钮被按下,这样就执行GetDlgItemText函数得到编辑框的内容,然后用messagebox来显示。如果是IDC_EXIT说明按下了“退出程序”这个按钮,则执行EndDialog这个函数退出程序。

      程序就是通过处理各种消息完成的!在更大的程序里面也都是这种结结构,只不过处理的消息更多而已。


  • 用汇编写基于对话框的程序,可以和写VB程序一样清晰简单,并且相当多的程序都是这样的结构。用VB写的所以程序几乎都是这样的。

我的主页asm.91i.net
; *程序说明* ;=============================================================================================== ; ; ; 对话框是由线条和矩形组合而成,标准windows对话框一共使用了5种颜色,分别是: ; #D4D0C8,#0E296E,#FFFFFF,#808080,#404040.其中#D4D0C8是对话框主体颜色, ; #0E296E是标题栏颜色,其他三种颜色是对话框边框使用的颜色,对话框边框主要用于营 ; 造对话框立体效果. ; ; 本程序由于使用的是640*480*16色显示模式,无法取到标准windows程序所需要的5种 ; 颜色,所以使用相近的颜色进行替换. ; ; 我在网上找了好久关于640*480*16色模式的相关资料,最终还是没有找到详细的资料. ; 自己写了一个画点函数(程序中的DrawPointb),但是使用这个函数画矩形时有点问题,当颜色 ; 号是奇数时正常,如果颜色号是偶数时,矩形将不能正确显示.本程序中使用的画点函数是在网 ; 上找的,不过这个函数也有一点问题,就是速度非常慢,如果画点去添满整个屏幕,将使用好长的 ; 时间.所以程序中的大背景是用我理解的那种方法画的,其他的都使用DrawPoint函数.如果谁 ; 有比较详细的640*480*16色显示模式的相关资料,不要忘了告诉我. ; ; 汉字显示和用C语言显示的方式有点区别,因为在实模式下每个段最大容量是64K,而字库 ; 文件有一百多K,所以不能一次将字库文件读入,我使用的方法是把字库文件打开,然后每显示 ; 一个汉字,移动一次指针,将指针移动到响应的点阵然后读取一个字的点阵信息到内存,直到字符 ; 串显示完毕. ; ; 如果程序要在裸机下运行,则需要将要显示的汉字的点阵信息从字库中提取出来.显示汉字 ; 的子程序也要做相应的修改. ; ; 由于时间不是很宽裕,基本上没有写注释,各个函数的作用: ; ; 1.ConfirmTCan(按钮由确定状态变为取消状态) ; 2.CanTConfirm(按钮由取消状态变为确定状态) ; 3.ShowHanZi(显示汉字子程序) ; 4.DrawDialog(显示对话框程序) ; 5.DrawButtonNoSelected(画一个未选中状态的按钮) ; 6.DrawButtonOnSelected(画一个选中状态的按钮) ; 7.DrawRect(画矩形子程序) ; 8.DrawPoint(画点子程序) ; ; ************Tab键或者方向键控制按钮焦点变换****************************** ; ; e-mail:westdatas@163.com OICQ:19820914 ; Nirvana 2006.8.1 ;==============================================================================================
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值