Win32彙編筆記——窗口創建API函數

1.模塊的概念

一個模塊代表的是一個運行中的exe文件或dll文件,用來代表這個文件中所有的代碼和資源,用來代表這個文件中所有的代碼和資源,磁盤上的文件不是模塊,裝入內存後運行時就叫做模塊。一個應用程序調用其他DLL中的API時,這些DLL文件被裝入內存,就產生了不同的模塊,爲了區分地址空間中的不同模塊,每個模塊都有惟一的模塊句柄來標識。

2.句柄

句柄只是一個數值,它的值對程序來說是沒有意義的,它只是Windows用來表示各種資源的編號而已。

由於很多API函數中都要用到程序的模塊句柄,以便利用程序中的各種資源,所以在程序的一開始就先取得模塊句柄並存放到一個全局變量中可以省去很多的麻煩,在Win32中,模塊句柄在數值上等於程序在內存中裝入的起始地址。

注意:模塊和句柄的概念。

3.API函數

取模塊句柄函數:GetMoudleHandle

使用方法:invoke GetMoudleHandle,pMoudleName

lpMoudleName參數是一個指向含有模塊名稱字符串的指針,可以用這個函數取得程序地址空間中各個模塊的句柄,如

szUserDll		db		'User32.dll',0
					...
					invoke	GetMoudleHandle,addr szUserDll
					.if			eax
								mov		hUserDllHandle,eax
					.endif
					...

如果使用參數NULL調用GetMoudleHandle,那麼得到的是調用者本模塊的句柄,如:
invoke GetMoudleHandle,NULL
mov hInstance,eax

在Win32中hInstance(實例句柄)就是hMoudle(模塊句柄)。

在C語言中,hInstance通過WinMain由系統傳入,WinMain的原型是:
WinMain (hInstance,hPrevInstance,lpzCmdPraram,nCmdShow),程序不用自己去獲得hInstance,這個過程由C的初始化代碼代勞。

註冊窗口類API:RegisterClassEx,“Ex”是擴展的意思。

一個窗口類定義了窗口的一些主要屬性,如:圖標、光標、背景色、菜單和負責處理該窗口所屬消息的函數。這些屬性定義在一個WNDCLASSEX結構中,把結構的地址當參數一次性傳遞給RegisterClassEx,WNDCLASSEX是WNDCLASS結構的擴展。

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

參數:
hIcon——圖標句柄,指定顯示在窗口標題欄左上角的圖標。Windows已經定義了一些圖標,同樣,程序也可以使用在資源文件中定義的圖標,這些圖標的句柄可以用LoadIcon函數獲得,如果程序中沒有用到圖標,那麼Windows給窗口顯示默認的圖標

hCursor——光標句柄,指定了鼠標在窗口中的光標形狀。同樣,Windows也預定義了一些光標,可以用LoadCursor獲取他們的句柄,IDC_ARROW是Windows預定義的箭頭光標,如果想使用自定義的光標,也可以自己在資源文件中定義。

lpszMenuName——指定窗口上顯示的默認菜單,它指向一個字符串,描述資源文件中菜單的名稱,如果資源文件中菜單是用數值定義的,那麼這裏使用菜單資源的數值。窗口中的菜單也可以在建立窗口函數CreateWindowEx的參數中指定。如果兩個地方都沒有指定,那麼建立的窗口上就沒有菜單。

hInstance——指定要註冊的窗口類屬於哪個模塊,模塊句柄在程序開始的地方已經用GetMoudleHandle函數獲得。

cbSize——指定WNDCLASSE結構的長度,用sizeof僞操作來獲取。很多Win32API參數中的結構都有cbSize字段,它主要是用來區分結構的版本,當以後新增了一個字段時,cbSize就相應增大,如果調用的時候cbSize還是舊的長度,表示運行的是基於舊結構的程序,這樣可以防止使用無效的字段。

style——窗口風格。CS_HREDRAW和CS_VREDRAW表示窗口的寬度或高度改變時是否重畫窗口。比較重要的是CS_DBLCLKS風格,指定了它,Windows纔會把在窗口中快速兩次單擊鼠標的行爲翻譯成雙擊消息WM_LBUTTONDBLCLK發給窗口過程。

一些窗口類的style預定義值:
一些窗口類的style預定義值
可以看到,這些預定義值實際上在使用不重複的數據位,所以可以組合起來使用,同時使用不同的預定義值並不會引起混淆。

對於不同二進制位組合的計算,“加”和“或”的結果是一樣的,但強烈建議使用or,因爲如果不小心指定了兩個同樣的風格時就有 BUG 產生了,因爲 1 or 1 = 1,而 1+1 = 2。

hbrBackground——窗口客戶區的背景色。前面的hbr表示他是一個刷子(Brush)的句柄,“刷子”一詞形象地表示了填充一個區域的着色模式。Windows預定義了一些刷子,如BLACK_BRUSH和WHITE_BRUSH等,可以用下列語句來得到它們的句柄:
invoke GetStockObject,WHITE_BRUSH
這裏也可以使用顏色值,Windows已經預定義了一些顏色值,分別對應窗口各部分的顏色,如COLOR_BACKGROUND和COLOR_WINDOW等,使用顏色值的時候,Windows規定必須在顏色值上+1。

lpszClassName——指定程序員要建立的類命名,以便以後用這個名稱來引用它。這個字段是一個字符串指針。

cbWndExtra和cbClsExtra——分別是在Windows內部保存的窗口結構和類結構中給程序員預留的空間大小,用來存放自定義數據,他們的單位是字節。不使用自定義數據的話,這兩個字段就是0.

lpfnWndProc——最重要的參數,他指定了基於這個類建立的窗口的窗口過程地址。通過這個參數,Windows就知道了在DispatchMessage函數中把窗口消息發到哪裏去,一個窗口過程可以爲多個窗口服務,只要這些窗口是基於同一個窗口類建立的。

註冊窗口時是用一個結構傳遞參數,建立窗口時所有的屬性都是用單個參數的方式傳遞的。

建立窗口函數CreateWindowEx

它是Win16中CreateWindow函數的擴展,CreateWindowEx函數的使用方法是:

	invoke	CreateWindowEx,dwExStyle,lpClassName,\
	lpWindowName,dwStyle,x,y,nWidth,nHeight,\
	hWndParent,hMenu,hInstance,lpParam

lpClassName——建立窗口使用的類名字符串指針。

lpWindowName——指向表示窗口名稱的字符串,該名稱會顯示在標題欄上。如果該參數空白,則標題欄上什麼都沒有。

hMenu——窗口上要出現的菜單的句柄。在註冊窗口類的時候也定義了一個菜單,那是窗口的默認菜單,意思是如果這裏沒有定義菜單(用參數NULL)而註冊窗口類時定義了菜單,則使用窗口類中定義的菜單;如果這裏指定了菜單句柄,則不管窗口類中有沒有定義都將使用這裏定義的菜單;兩個地方都沒有定義菜單句柄,則窗口上沒有菜單。另外,當建立的窗口是子窗口時(dwStyle中指定了WS_CHILD),這個參數是另一個含義,這時hMenu參數指定的是子窗口的ID號(這樣可以節省一個參數的位置,因爲子窗口不會有菜單)。

lpParam——這是一個指針,指向一個欲傳給窗口的參數,這個參數在WM_CREATE消息中可以被獲取,一般情況下用不到這個字段。

hInstance——模塊句柄,和註冊窗口類時一樣,指定了窗口所屬的程序模塊。

hWndParent——窗口所屬的父窗口,這裏的“父子”關係只是從屬關係,主要用來在父窗口銷燬時一同將其“子”窗口銷燬,並不會把窗口位置限制在父窗口的客戶區範圍內,但如果要建立的是真正的子窗口(dwStyle中指定了WS_CHILD的時候),這時窗口位置會被限制在父窗口的客戶區範圍內,同時窗口的座標(x,y)也是以父窗口的左上角爲基準的。

x,y——指定窗口左上角位置,單位是像素(px)。默認時可指定爲 CW_USEDEFAULT,這樣Windows會自動爲窗口指定最合適的位置,當建立子窗口時,位置是以父窗口的左上角爲基準的,否則,以屏幕左上角爲基準。

nWidth,nHeight——窗口的寬度和高度,也就是窗口的大小,同樣是以像素爲單位的。默認時可指定爲 CW_USEDEFAULT,這樣Windows會自動爲窗口指定最合適的大小。

dwStyle——窗口的兩個參數dwStyle和dwExStyle決定了窗口的外形和行爲,dwStyle是從win16開始就有的屬性,下表列出了一些常見的dwStyle定義。
窗口風格的預定義值
等效的窗口風格預定義值
dwExStyle——dwExStyle是Win32中擴展的,它們是一些以WS_EX_開頭的預定義值,主要定義了一些特殊的風格,下表給出了一些最常用的特殊風格。
窗口擴展風格的預定義值

建立窗口後,eax中傳回來的是窗口句柄,要把它保存起來以後備用,然後要用ShowWindow把它顯示出來,ShowWindow用窗口句柄做第一個參數,第二個參數則是顯示方式。

invoke ShowWindow,hWinMain,SW_SHOWNORMAL
ShowWindow函數顯示方式的定義

窗口顯示以後,用UpdateWindow繪製客戶區,它實際就是向窗口發送了一條WM_PAINT消息。它繞過應用程序的消息隊列,直接發送WM_PAINT消息給窗口過程。到此爲止,一個頂層窗口就正常建立並顯示了。

invoke UpdateWindow,hWinMain

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章