win32 汇编学习(三)

三:模块和句柄

1 . 程序结构模式分为两种,过程驱动方式和事件驱动方式

2. PostMessage 是把一个消息放到其他程序的消息队列中,而SendMessage 则越过消息队列直接调用目标程序的窗口过程。

3.一个应用程序为了区分地址空间中的不同模块,每个模块都有一个唯一的模块句柄来标识。取模块句柄使用的API函数是

GetModuleHandler  具体用法是: 

invoke  GetMoudleHandler,lpModuleName

lpModuleName  参数是一个指向含有模块名称字符串的指针,可以用这个函数取得各个模块的句柄。如果lpModuleName 是NULL ,得到的是调用本模块的句柄。

4.句柄只是Windows 用来表示各种资源的编号而已。

四:创建窗口

1.注册窗口API函数是RegisterClassEx ,最后的Ex是扩展的意思。WNDCLASSEX 是 WNDCLASS结构的扩展。

2.在头文件中以WM_ 开头的预定义值(意为Windows Message)

3.创建窗口划分为:注册窗口类---->>>建立窗口类--->>>显示窗口

下面的例程是win32窗口的demo ,按照自己的理解注释了一部分代码:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 4th Edition>
; by 罗云彬, [email protected]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; FirstWindow.asm
; 窗口程序的模板代码
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.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

;szCaption1	db	'恭喜',0
;szText1		db	'当您看到这个信息的时候,您已经可以编译Win32汇编程序了!',0
;szClassName1	db	'MyClass1',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 窗口过程
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcWinMain	proc	uses ebx edi esi hWnd,uMsg,wParam,lParam
		local	@stPs:PAINTSTRUCT
		local	@stRect:RECT
		local	@hDc

		mov	eax,uMsg
	        ;invoke	MessageBox,NULL,offset szText1,offset szCaption1,MB_OK
;********************************************************************
		.if	eax ==	WM_PAINT
			invoke	BeginPaint,hWnd,addr @stPs                           ;hwnd 消息要发向的窗口句柄
			mov	@hDc,eax
                           
			invoke	GetClientRect,hWnd,addr @stRect                      ;GetClientRect 获取客户区的大小,
			invoke	DrawText,@hDc,addr szText,-1,\                       ;DrawText      函数将字符串按照取得的屏幕大小 居中写在窗口中
				addr @stRect,\
				DT_SINGLELINE or DT_CENTER or DT_VCENTER

			invoke	EndPaint,hWnd,addr @stPs                             ;beginpaint 和 endpaint 开始和结尾处是相同的
;********************************************************************
		.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  ;此处定义呢,WNDCLASSEX  的是属于类,@stWndClass 是类名
		local	@stMsg:MSG              ;此处同上
		invoke	GetModuleHandle,NULL    ;这个是本模块的句柄
		mov	hInstance,eax           ;制定要注册的窗口类属于那一个模块
		invoke	RtlZeroMemory,addr @stWndClass,sizeof @stWndClass ;目的是将利用RtlZeroMemory指令,将类stWndClass进行初始化 
;********************************************************************
; 注册窗口类
;********************************************************************
		invoke	LoadCursor,0,IDC_ARROW
		mov	@stWndClass.hCursor,eax
		push	hInstance
		pop	@stWndClass.hInstance                                 ;
		mov	@stWndClass.cbSize,sizeof WNDCLASSEX                  ;WNDCLASSEX   指定WNDCLASSEX长度
		mov	@stWndClass.style,CS_HREDRAW or CS_VREDRAW            ;style 窗口风格
		mov	@stWndClass.lpfnWndProc,offset _ProcWinMain           ;指定呢基于这个类建立的窗口的窗口过程地址 
		mov	@stWndClass.hbrBackground,COLOR_WINDOW + 1            ;windows 规定必须在颜色值上+1
		mov	@stWndClass.lpszClassName,offset szClassName          ;制定程序员建立的类命名,,以后用这个名称来引用他,在程序里,它指向'Myclass'字符串
		invoke	RegisterClassEx,addr @stWndClass     
;********************************************************************
; 建立并显示窗口
;********************************************************************
		invoke	CreateWindowEx,WS_EX_CLIENTEDGE,                                  ;WS_EX_ACCEPTFILES,\                   ; 
		        offset szClassName,offset szCaptionMain,\                         ;szCaptionMain表示窗口名称的字符串 ,szClassName 表示程序员建立的类名
			WS_OVERLAPPEDWINDOW,\                                             ;窗口风格定义
			100,100,800,400,\  ;(x,y,长度,宽度)
			NULL,NULL,hInstance,NULL
		mov	hWinMain,eax                                                      ;hWinMain 是代表已经定义但是没有赋值的 
		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窗口中建立子窗口:相比前一段代码主要是增加这部分代码:

;********************************************************************
; 建立一个按钮                    重点关注这块代码
;********************************************************************
        .elseif    eax ==    WM_CREATE                                         
            invoke    CreateWindowEx,NULL,\
                offset szButton,offset szButtonText,\
                WS_CHILD or WS_VISIBLE,\
                10,10,65,42,\
                hWnd,1,hInstance,NULL

具体的看所有的源代码:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Sample code for < Win32ASM Programming 4th Edition>
; by 罗云彬, [email protected]
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; FirstWindow.asm
; 在窗口模板程序上添加一个按钮
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 使用 nmake 或下列命令进行编译和链接:
; ml /c /coff FirstWindow.asm
; Link /subsystem:windows FirstWindow.obj
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		.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
szButton	db	'button',0
szButtonText	db	'&OK',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_CREATE                                         
			invoke	CreateWindowEx,NULL,\
				offset szButton,offset szButtonText,\
				WS_CHILD or WS_VISIBLE,\
				10,10,65,42,\
				hWnd,1,hInstance,NULL
;********************************************************************
		.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

 

你可能感兴趣的:(汇编)