Programming 版 (精华区)

发信人: lofe ()感激生活(), 信区: Programming
标  题: 罗云彬的Win32汇编教程之三
发信站: 哈工大紫丁香 (Sun Sep  3 16:42:50 2000), 转信

Win32汇编教程三
一个简单的对话框 --- 兼谈资源文件的使用
----------------------------------------------------------------------------
----
在这儿下载本节的所有源程序。
Windows 的资源文件
    不管在Dos下编程还是在Windows下编程,我们总是要用到除了可执行文件外的很多
其他数据,如声音数据,图形数据,文本等等,在Dos下编程,我们可以自己定义这些文
件的格式,但这样一来就造成了很多资源共享的问题,大家可能还记的Dos下的很多游戏
,它们的图形都是按自己的格式存放的,你无法用标准的看图软件来看。也无法把它另
存为其他格式。虽然在Win32编程中,我们仍然可以这样做,但Win32编程给了我们一个
方案 ---- 就是格式统一的资源文件,把字符串、图形、对话框包括上面的按钮,文本
等定义到一个资源文件中,就可以方便的在不同的文件中使用它,最重要的是,如果我
们用自己的文件格式,使用时就要涉及到这些文件的读写操作,比较复杂,但使用资源
文件时,Windows提供了一系列的API来装入资源。非常方便。现在,让我们来看一个很
简单的资源文件的源文件,它的扩展名是 .rc,当它用资源编译器编译以后产生 .res 
文件就可以在 link的时候连入.exe 文件中:
#include        <Resource.h>
#define         DLG_MAIN        1
DLG_MAIN        DIALOGEX 0, 0, 236, 185
STYLE           DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION         "对话框模板"
FONT            9, "宋体"
BEGIN
        DEFPUSHBUTTON   "退出",IDOK,177,163,50,14
        CONTROL         "",-1,"Static",SS_ETCHEDHORZ,7,155,222,1
END
现在我简单解释一下 .rc文件的语法:
#include <resource.h> -- resource.h文件包括资源文件的一些常量定义,如下面的 
WS_POPUP,WS_VISIBLE 等窗口的风格等等
#define DLG_MAIN 1 -- 类似于 .asm 文件的 equ 语句,和汇编源程序一样,这些定义
是为了程序的可读性。
DLG_MAIN DIALOGEX 0,0,236,185
Windows的.rc文件可以定义 BITMAP(位图),CURSOR(光标),ICON(图标),ACCELERATORS(加
速键),DIALOG(对话框),MENU(菜单),STRINGTABLE(字符串表),RCDATA(自定义资源)等8种
资源,详细的描述可以参考有关MFC的书籍,在Win32ASM中的资源编译器的语法中,一般
格式是这些资源的定义方法是:
位图定义: nameID BITMAP [load-mem] filename
光标定义: nameID CURSOR [load-mem] filename
图标定义: nameID ICON [load-mem] filename
加速键定义:
acctablename ACCELERATORS [optional-statements]
BEGIN event, idvalue, [type] [options]
. . .
END
等等,具体的定义和参数可以参考 Masm32v5 中的 Rc.hlp 帮助文件。(可以在编程工具
中下载),我们可以用资源编辑器来所见即所得地编辑资源,也可以在文本编辑器中用上
面这些语句自己定义资源。
在程序中使用资源
    在程序中,要使用资源之前必须先装如内存,Windows定义了一系列的API来装入资
源,如 LoadMenu,LoadString,LoadBitmap 等等,如 LoadBitmap 的定义:
HBITMAP LoadBitmap(
HINSTANCE hInstance, // handle of application instance
LPCTSTR lpBitmapName // address of bitmap resource name
);
    这些Load函数的返回值是一个句柄,调用参数中一般至少为两项: hInstance 和 
ResouceName,这个 ResouceName(如BitmapName,MenuName)就是在资源文件中的 #defi
ne 指定的值,如果你用 #define MY_ICON 10/ MY_ICON ICON "Main.ico" 定义了一个
图标,那么在程序中要使用 Main.ico 图标就可以用 LoadIcon(hInstance,10) 来装入
已经定义为10号的图标文件。另一个参数 hInstance 是执行文件的句柄,它对应资源所
在的文件名,你可以在程序开始执行时用 invoke GetModuleHandle,NULL 获得 hInsta
nce。另外一些资源并不是显式地装入的,如对话框资源,它是在建立对话框的函数中由
Windows自己装入的,如下面例子中的 invoke DialogBoxParam,hInstance,DLG_MAIN,N
ULL,offset _ProcDlgMain,0 ,是在屏幕上显示一个资源文件中已经定义好了的对话框
,就并不存在 LoadDialogBox 之类的API来先装入对话框。
Win32ASM - 显示一个对话框
介绍了这么多相关的东西,现在让我们来看看如何显示一个对话框,源程序如下:
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;       Programmed by 罗云彬, bigluo@telekbird.com.cn
;       Website: http://asm.yeah.net
;       LuoYunBin's Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .386
                .model flat, stdcall
                option casemap :none   ; case sensitive
include         windows.inc
include         user32.inc
include         kernel32.inc
include         comctl32.inc
include         comdlg32.inc
includelib      user32.lib
includelib      kernel32.lib
includelib      comctl32.lib
includelib      comdlg32.lib
DLG_MAIN        equ             1
                .data?
hInstance       dd      ?
szBuffer        db      256 dup (?)
_ProcDlgMain    PROTO   :DWORD,:DWORD,:DWORD,:DWORD
                .data
                .code
;********************************************************************
_ProcDlgMain    proc    uses ebx edi esi, \
                hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
                mov     eax,wMsg
                .if     eax == WM_CLOSE
                        invoke  EndDialog,hWnd,NULL
                .elseif eax == WM_INITDIALOG
                .elseif eax == WM_COMMAND
                        mov     eax,wParam
                        .if     eax == IDOK
                                invoke  EndDialog,hWnd,NULL
                        .elseif eax == IDCANCEL
                                invoke  EndDialog,hWnd,NULL
                        .endif
                .else
                        mov     eax,FALSE
                        ret
                .endif          
                mov     eax,TRUE
                ret
                
_ProcDlgMain    endp
;********************************************************************
start:
                invoke  InitCommonControls
                invoke  GetModuleHandle,NULL
                mov     hInstance,eax
                invoke  DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
                invoke  ExitProcess,NULL
                end     start
看了前面几篇文章以后,这儿的大部分语句应该是很熟悉了,我来讲解几句新的语句:

_ProcDlgMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
PROTO 语句类似于C语言中的函数定义,在Win32汇编中,如果子程序的定义在引用以后
,你就必须先定义,当然,这个定义是针对 invoke 语句和其他带参数的调用的,如果
你的子程序没有参数,你就可以用 call 指令去调用它而不是用宏指令 invoke,这时候
你就不必声明这个函数。
_ProcDlgMain proc uses ebx edi esi, \
hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
这个定义 proc 的语句应该是不陌生的,要重复讲解一下的是 uses 和 下面的参数,u
ses 下的寄存器表示要编译器自动插入保存及恢复这些寄存器的指令,\ 是在 Masm32 
中接下一行的符号,表示下一行是本行的继续内容,以避免一行中的内容过长。下面的
 hWnd:DWORD 等语句定义了调用这个子程序的参数,如果有以下定义 MyProc proc dwP
ara1:DWORD,dwPara2:DWORD,dwPara3:DWORD,然后你用 invoke MyProc 1,2,3 来调用它
,那么,1,2,3 将分别被赋值给 dwPara1,dwPara2,dwPara3,你可以在子程序中使用这
些传递过来的参数。如果参数的类型是双字,那么:DWORD 可以省略。
.if/.else/.elseif/.endif
这些语句是宏指令,实际上不说你也知道它们的意思,有了这些宏指令,我们就可以把
汇编编得象C一样结构清晰,而不必老是看到 jmp 指令了,当然,这只不过编译器帮你
做了这些事情而已,如果你去反汇编一下,你开始会看到一大堆 jmp 指令,.if 的格式
如下
.if eax == 1 如果eax等于1
.if eax != 1 如果eax不等于1
.if eax != 1 && ebx != 2 如果eax不等于1且ebx不等于2
.if eax == 1 || ebx == 2 如果eax等于1或者ebx等于2
其他的宏指令还有 .while/.endw .break 等等,可以参考 Masm32V5 的帮助文件 Masm
32.hlp
    最后要讲到的就是 DialogBoxParam 这个API了,在Windows中,所有的窗口都要指
定一个子程序,当Windows检测到鼠标、定时器等和这个窗口有关的动作时,它回调用这
个子程序,这就是Windows基于消息的体系的最基本的概念,换句话说,在Dos下,我们
通过INT指令调用系统,而在Windows 下,有很多时候是你指定子程序地址让Windows来
调用你。 invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
中的 offset _ProcDlgMain 就指定了如果有消息发生,Windows就来执行这个子程序,
参数中的 DLG_MAIN 就是在资源文件中定义的对话框模板编号。 hInstance 是对话框所
在的资源文件的句柄。
    另外,在_ProcDlgMain 子程序中,Windows传给我们4个参数hWnd,wMsg,wParam,lP
aram,其中,hWnd是对话框的窗口句柄,wMsg表示现在发生的消息事件,如这个对话框
初始化时Windows会以WM_INITDIALOG为消息调用,关闭时为WM_CLOSE,按下对话框上的
按钮时为WM_COMMAND等,wParam和lParam是附加的参数,对应不同的消息对应不同定义
,具体可以参考Win32 Programmer's reference。
----------------------------------------------------------------------------
----
 太极链- 8059
太极链改版了 易维评论  华清赚钱  光碟热讯  ★最酷中文网址  5分钟赚5美元
全新太极品网 43号客栈  ★精品软件秀★  金中华通讯公司  邪客行的家  ☆白菜乐园

----------------------------------------------------------------------------
----
(C) Copyright by LuoYunBin's Win32 ASM Page,http://asm.yeah.net
--
我没什麽特别
是杀猪的!
※ 修改:.haojs 于 Sep  3 16:39:55 修改本文.[FROM: bbs.hit.edu.cn]
--
※ 转寄:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: bbs.hit.edu.cn]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: haojs.bbs@bbs.whnet.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.687毫秒