我的第一个win32汇编程序

时间:2021-02-21 01:09:57
.386
.Model Flat,stdcall
option  casemap:none
;头文件包含
include windows.inc
include kernel32.inc
includelib kernel32.lib
include user32.inc
includelib user32.lib
include gdi32.inc
includelib gdi32.lib
;数据段定义
.data
hInstance dd ?
hWinMain  dd ?
;常量定义
.const
szClassName db "MyClass",0
szCaption   db "My FirstWindow",0
szText      db "这是我的第二个程序",0
szButton    db "Button",0;
szButtonText db "ButtonText",0
;代码段定义
.code
WinProc 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;
.elseif eax==WM_CREATE
     invoke CreateWindowEx,NULL,\
                       offset szButton,offset szButtonText,WS_CHILD or WS_VISIBLE,10,10,65,22,hWnd,1,hInstance,NULL;


.else
    invoke DefWindowProc,hWnd,uMsg,wParam,lParam;
ret;
.endif
    xor eax,eax
ret
WinProc 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 WinProc;
 mov   @stWndClass.hbrBackground,COLOR_WINDOW+1;
 mov   @stWndClass.lpszClassName,offset szClassName;
 invoke RegisterClassEx,addr @stWndClass;
;建立便显示窗口
     invoke CreateWindowEx,WS_EX_CLIENTEDGE,\
 offset szClassName,offset szCaption,\
 WS_OVERLAPPED,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,hWinMain;
.endw;
ret
_WinMain endp;
start:
   call _WinMain;
invoke ExitProcess,0;
end start

可以算是一个小小的Helo World程序,但是因为是第一个,所以总有些与众不同的意味,还请众大神不要笑哈,只是在这儿写下,写这个程序的几点心得,或者说在这过程中犯

下的几个错误:

第一个就是hInstance的定义,有时不太会注意但是hInstance一定要是dd类型的,因为是句柄,所以一定是32位的,因而一定要是32位的,嗯

第二个就是.if eax==WM_CLOSE,对于消息的过滤,在这儿说的不是技术,只是,eax一定要和eax==WM_CLOSE在一行,虽然不用空格,但是也要在一行!!!我在这儿犯

了错误,查了好久,才发现是这个错误,惭愧惭愧.

另外我们知道在创建并显示窗口的时候,在之前会有一个注册窗口类的过程,该过程定义了窗口的类型,样式,或者说,该类是窗口的一个模板,另外,创建并显示窗口的时候

窗口类和显示窗口之间的关系就是通过窗口类的名称进行绑定的!

还有就是父窗口和子窗口的一个关系就是,当父窗口在销毁时,子窗口也会自动销毁,这就是父窗口和子窗口的关系,

在创建Button按钮的时候,或者其他系统中已有的控件的时候,注意两点,一是类的名称,比如button就是"Button",在WS,也就是窗口风格的时候,就是WS_CHILD 还有就是

WS_VISIBLE,好了,就到这里了