首页 > 代码库 > win32汇编--第一个窗体程序

win32汇编--第一个窗体程序

窗口创建过程   
GetModuleHandle->RtlZeroMemory->LoadCursor->RegisterClassEx->CreateWindowsEx->ShowWindow->UpdateWindow
获得模块句柄->结构体初始化(填0)->加载光标->注册窗体类->创建窗体->显示窗体->更新客户区

win32API函数定义

GetModuleHandle,lpModuleName
参数:lpModuleName参数是一个指向含有模块名称字符串的指针
功能: 是返回指定模块名的句柄,如果为NULL,则返回本模块的句柄。

RtlZeroMemory,lpDestination,bLength
参数:
lpDestination指向一块准备用0来填充的内存区域的开始地址。
bLength准备用0来填充的内存区域的大小,按字节来计算。
RtlZeroMemory只是将指定的内存块清零。
功能:使用结构前清零,而不让结构的成员数值具有不确定性,是一个好的编程习惯。

LoadCursor,hlnstance,LpCursorName
参数:
hlnstance  标识一个模块事例,它的可执行文件包含要载入的光标。
LpCursorName
指向以NULL结束的字符串的指针,该字符串存有等载入的光标资源名。该参数低位字节和高位字节0组成资源标识器也可以由低位字为资源标识符和高位字为零组成。也可以用MAKEINTRESOURCE宏命令创建该值。要使用Win32预定义的一个光标,应用程序必须把hlnstance参数设为NULL。
功能:该函数从一个与应用事例相关的可执行文件(EXE文件)中载入指定的光标资源。该函数已被Loadlmage函数替代。

RegisterClassEx,Ipwcx
参数:
Ipwcx
指向一个WNDCLASSEX结构的指针。在传递给这个函数之前,必须在结构内填充适当的类的属性返回值:如果函数成功,返回这个窗口类型的标识号;如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。
功能:该函数为随后在调用Createwindow函数和CreatewindowEx函数中使用的窗口注册一个窗口类。


WNDCLASSEX      STRUCT
cbSize                   DWORD    ?               ;  结构的字节数
style                      DWORD    ?               ;  类风格
lpfnWndProc       DWORD    ?               ;  窗口过程的地址
cbClsExtra            DWORD    ?
cbWndExtra         DWORD    ?
hInstance             DWORD    ?              ;所属的实例句柄
hIcon                    DWORD    ?             ;窗口图标
hCursor                DWORD    ?             ; 窗口光标
hbrBackground   DWORD    ?             ;背景色
lpszMenuName   DWORD   ?             ;窗口菜单
lpszClassName     DWORD   ?             ;类名字符串的地址
hIconSm              DWORD   ?              ;小图标
WNDCLASSEX      ENDS   



CreateWindowsEx,DWORDdwExStyle,\     ;窗口的扩展风格
LPCTSTRlpClassName,\                               ;指向注册类名的指针
LPCTSTRlpWindowName,\                         ;指向窗口名称的指针
DWORDdwStyle,\                                        ;窗口风格
intx,\                                                             ;窗口的水平位置
inty,\                                                             ;窗口的垂直位置
intnWidth,\                                                  ;窗口的宽度
intnHeight,\                                                 ;窗口的高度
HWNDhWndParent,\                                  ;父窗口的句柄
HMENUhMenu,\                                         ;菜单的句柄或是子窗口的标识符
HINSTANCEhInstance,\                              ;应用程序实例的句柄
LPVOIDlpParam                                          ;指向窗口的创建数据

功能: 该函数创建一个具有扩展风格的层叠式窗口、弹出式窗口或子窗口,其他与CreateWindow函数相同。

ShowWindow,hWnd,nCmdShow
参数:
hWnd:指窗口句柄。
nCmdShow:指定窗口如何显示。如果发送应用程序的程序提供了STARTUPINFO结构,则应用程序第一次调用ShowWindow时该参数被忽略。否则,在第一次调用ShowWindow函数时,该值应为在函数WinMain中nCmdShow参数。
功能:该函数设置指定窗口的显示状态
如果窗口之前可见,则返回值为非零。如果窗口之前被隐藏,则返回值为零。

UpdateWindow,hWnd 
参数:
hwnd 要更新的窗口句柄
功能:如果窗口更新的区域不为空,UpdateWindow函数通过发送一个WM_PAINT消息来更新指定窗口的客户区。函数绕过应用程序的消息队列,直接发送WM_PAINT消息给指定窗口的窗口过程,如果更新区域为空,则不发送消息。
如果函数调用成功,返回值为非零值。如果函数调用不成功,返回值为零。

消息循环    GetMessage->TranslateMessage->DispatchMessage

从消息队列中获得一条消息->根据键盘按键的扫描码转换为ASCLL值->分发消息给USER.DLL,USER.DLL调用窗体过程处理消息


GetMessage,lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax
参数:
lpMsg:指向MSG结构的指针,该结构从线程消息队列里接收消息。
hWnd:取得其消息的窗口的句柄。当其值取NULL时,GetMessage为任何属于调用线程的窗口检索消息,线程消息通过PostThreadMessage寄送给调用线程。
wMsgFilterMin:指定被检索的最小消息值的整数。
wMsgFilterMax:指定被检索的最大消息值的整数。
功能: 函数GetMessage是从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。此函数接收一定范围的消息值。GetMessage不接收属于其他线程或应用程序的消息。获取消息成功后,线程将从消息队列中删除该消息。函数会一直等待直到有消息到来才有返回值。
返回值:如果函数取得WM_QUIT之外的其他消息,返回非零值。如果函数取得WM_QUIT消息,返回值是零。如果出现了错误,返回值是-1。例如,当hWnd是无效的窗口句柄或lpMsg是无效的指针时。若想获得更多的错误信息,请调用GetLastError函数。


TranslateMessage,lpMsg
参数:IpMsg   指向含有消息的MSG结构的指针,该结构里含有用函数GetMessage或PeekMessage从调用线程的消息队列里取得的消息信息。
函数功能:该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessagePeekMessage时被读出。
返回值:如果消息被转换(即,字符消息被寄送到调用线程的消息队列里),返回非零值。如果消息是WM_KEYDOWN,WM_KEYUP WM_SYSKEYDOWN或WM_SYSKEYUP,返回非零值,不考虑转换。如果消息没被转换(即,字符消息没被寄送到调用线程的消息队列里),返回值是零。


DispatchMessage,lpmsg
参数:lpmsg   指向含有消息的MSG结构的指针
功能:  该函数分发一个消息给窗口程序。通常消息从GetMessage函数获得。消息被分发到回调函数(过程函数),作用是消息传递给操作系统,然后操作系统去调用我们的回调函数,也就是说我们在窗体的过程函数中处理消息
返回值:返回值是窗口程序返回的值。尽管返回值的含义依赖于被调度的消息,但返回值通常被忽略。


窗口过程    BeginPaint->GetClientRect->DrawText->EndPaint

进行窗口绘制工作->获得窗体客户区->写入文本->结束绘制

BeginPaint,hwnd,lpPaint
hwnd:[输入]被重绘的窗口句柄
lpPaint:[输出]指向一个用来接收绘画信息的PAINTSTRUCT结构
功能:BeginPaint函数为指定窗口进行绘图工作的准备,并用将和绘图有关的信息填充到一个
PAINTSTRUCT结构中。
如果函数成功,返回值是指定窗口的“显示设备描述表”句柄。如果函数失败,返回值是NULL,表明没有得到显示设备的内容。

GetClientRect,hWnd,lpRect
参数:
hWnd:是程序窗口的句柄。
lpRect:是一个指针,指向一个RECT类型的rectangle结构。该结构有四个LONG字段,分别为left、top、right和bottom。
GetClientRect将这四个字段设定为窗口显示区域的尺寸。left和top字段通常设定为0。right和bottom字段设定为显示区域的宽度和高度(像素点数)。 也可以是一个CRect对象指针。CRect对象有多个参数,与RECT用法相同。
功能: 该函数获取窗口客户区的坐标。客户区坐标指定客户区的左上角和右下角。由于客户区坐标是相对窗口客户区的左上角而言的,因此左上角坐标为(0,0)。这里应该注意一下:坐标包含两种:屏幕坐标与客户区坐标。严格区分这两种坐标对于理解Windows编程是很重要的。
作用总的来说就是把客户区的大小写进第二个参数所指的Rect结构当中。

DrawText,hDC,lpString,nCount,lpRect,uFormat 
hdc:[输入]设备环境句柄。
lpString:[输入]指向将被写入的字符串的指针,如果参数nCount是-1,则字符串必须是以\0结束的。 如果uFormat包含DT_MODIFYSTRING,则函数可为此字符串增加4个字符,存放字符串的缓冲区必须足够大,能容纳附加的字符。
nCount:[输入]指向字符串中的字符数。如果nCount为-1,则lpString指向的字符串被认为是以\0结束的,DrawText会自动计算字符数。
lpRect:[输入/输出]指向结构RECT的指针,其中包含文本将被置于其中的矩形的信息(按逻辑坐标)。
uFormat:[输入]指定格式化文本的方法。
功能:该函数的功能是在指定的矩形里写入格式化文本,根据指定的方法对文本格式化(扩展的制表符,字符对齐、折行等)
要指定额外的格式化选项,请使用DrawTextEx函数。
返回: 如果函数调用成功,返回值是正文的高度(逻辑单位)。如果指定了DT_VCENTER或DT_BOTTOM,返回值是lpRect->top到绘制的正文的底部的偏移值。如果函数调用失败,返回值是0

EndPaint,hWnd,lpPaint
hWnd:[输入]已经被重画的窗口的HANDLE
lpPaint:[输入]指向一个PAINTSTRUCT结构,该结构包含了绘画信息,是BeginPaint函数返回的返回值:
返回值:返回值始终是非0
功能:EndPaint函数标记指定窗口的绘画过程结束;这个函数在每次调用BeginPaint函数之后被请求,但仅仅在绘画完成以后。


PAINTSTRUCT 结构体包含了用于绘制窗口客户区的信息。
PAINTSTRUCT  STRUCT
hdc                    DWORD        ?                      ; 用于绘制的句柄
fErase                DWORD        ?                      ;如果为非零值则擦除背景,否则不擦除背景
rcPaint              DWORD        ?                       ;通过制定左上角和右下角的坐标确定一个要绘制的矩形范围,该矩形单位相对于客户区左上角。 
fRestore            DWORD        ?                       ;后面三个参数都是系统预留的,编程一般用不到。
fIncUpdate       DWORD        ?                      
rgbReserved     DWORD        ?                      
PAINTSTRUCT  ENDS    



完整的程序Fwindow.asm
				.386
                .model flat,stdcall
                option casemap:none

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

; Include 文件定义

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include         windows.inc
include         gdi32.inc
includelib      gdi32.lib
include         user32.inc
includelib      user32.lib
include         kernel32.inc
includelib      kernel32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .data?
hInstance       dd      ?
hWinMain        dd      ?

                .const
szClassName     db      'MyClass',0
szCaptionMain   db      'My first Window!',0
szText          db      'Win32 Assembly, Simple and powerful!',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                .code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain    proc uses ebx edi esi, hWnd, uMsg, wParam, lParam
                local @stPs:PAINTSTRUCT
                local @stRect:RECT
                local @hDc
                mov eax,uMsg
;*************************************************************************
                .if     eax == WM_PAINT
                        invoke     BeginPaint,hWnd,addr @stPs
                        mov     @hDc,eax
                        invoke GetClientRect,hWnd,addr @stRect
                        invoke    DrawText,@hDc,addr szText,-1,                                 addr @stRect,                                 DT_SINGLELINE or DT_CENTER or DT_VCENTER
                        invoke     EndPaint, hWnd, addr @stPs
;***************************************************************************
                .elseif eax == WM_CLOSE
                        invoke     DestroyWindow,hWinMain
                        invoke     PostQuitMessage,NULL
;***************************************************************************
                .else
                        invoke     DefWindowProc,hWnd,uMsg,wParam,lParam
                        ret
                .endif
;***************************************************************************
                xor     eax,eax
                ret
_ProcWinMain    endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_WinMain        proc
                local   @stWndClass:WNDCLASSEX
                local   @stMsg:MSG
                invoke     GetModuleHandle,NULL
                mov     hInstance,eax
                invoke     RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
;**************************************************************************
; 注册窗口类
;**************************************************************************
                invoke     LoadCursor,0,IDC_ARROW
                mov     @stWndClass.hCursor,eax
                push    hInstance
                pop     @stWndClass.hInstance
                mov     @stWndClass.cbSize, sizeof WNDCLASSEX
                mov     @stWndClass.style, CS_HREDRAW or CS_VREDRAW
                mov     @stWndClass.lpfnWndProc, offset _ProcWinMain
                mov     @stWndClass.hbrBackground,COLOR_WINDOW + 1
                mov     @stWndClass.lpszClassName, offset szClassName
                invoke     RegisterClassEx, addr @stWndClass
;***************************************************************************
; 建立并显示窗口
;***************************************************************************
                invoke     CreateWindowEx, WS_EX_CLIENTEDGE,                         offset szClassName, offset szCaptionMain,                         WS_OVERLAPPEDWINDOW,                         100, 100, 600, 400,                         NULL, NULL, hInstance, NULL
                mov     hWinMain,eax
                invoke     ShowWindow,hWinMain,SW_SHOWNORMAL
                invoke     UpdateWindow,hWinMain
;**************************************************************************
; 消息循环
;**************************************************************************
                .while TRUE
                        invoke     GetMessage, addr @stMsg, NULL, 0, 0
                        .break     .if eax == 0
                        invoke     TranslateMessage, addr @stMsg
                        invoke     DispatchMessage, addr @stMsg
                .endw
                ret
_WinMain        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
                call    _WinMain
                invoke ExitProcess, NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end start





win32汇编--第一个窗体程序