天天看點

Poedu_Windows_Windows消息機制

__stdcall

由調用方完成壓棧操作,由被調用方自身在傳回前清空,Win32中使用的是這個

__cdecl

參數由調用方完成壓棧及平棧操作,每一個調用它的函數都包含有清空堆棧的代碼,C語言中使用的這個

__fdecl

不用棧進行參數傳遞,用的是寄存器,是以速度很快

HINSTANCE

執行個體對象,通過操作HINSTANCE操作程序

WinMain函數

作為win32程式的入口函數三種
tWinMain
可變版本,根據編碼自動轉換
WinMain
ANSI版本
wWinMain
Unicode版本
WinMain和wWinMain的差別在于,傳入的一個參數不一樣(LPSTR或LPWSTR)

wWinMain原型

int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)

參數

HINSTANCE hInstance
目前程序的句柄
需要由外部傳入的原因:程序是系統建立的,程式本身并不能建立程序,是以需要外部傳入
Main中沒有,是因為Main是C語言裡的一個系統,C語言出的時候,還沒有Instance這個參數,它還能運作,但是需要用GetInstance才能調用win32的東,WinMain在調用的時候跟Main函數的時候是一樣的
HINSTANCE hPrevInstance
hPrevInstance:是哪個程序啟動我的
LPWSTR lpCmdLine
和外部進行互動
這個參數在不同的WinMain版本下是不一樣的,在ANSI版本中是LPSTR
int nCmdShow
nCmdShow:和外部進行互動
第一、二個參數,是系統告訴我的,第三、四兩個參數是使用者告訴我的

RegisterClassExW

Ex:更新版本,不建議使用RegisterClass了
進行了一個内容更新:WINDCLASSEX*lpwcx
做了一個視窗填充,結構體原型

typedef struct tagWNDCLASSEXW { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; HICON hIconSm; } WNDCLASSEXW, *PWNDCLASSEXW, NEAR *NPWNDCLASSEXW, FAR *LPWNDCLASSEXW;

cbsize:是一個高危參數
但凡是出現了cbsize,都必須進行填充,不然互動的時候就會産生問題:因為使用者态和和心态傳遞參數的時候,是非常費勁的,隻能傳入一個從哪個地方開始的指針,而在共享區域讀多少空間,需要cbsize這個參數來告知,如果這個參數沒填,那麼理所當然的會出問題,cbsize承擔了一個“示寬”的作用
lpfnWndProc

lp:long point

fn:函數

Proc:過程,步驟

對視窗進行一些操作的時候會調用這個函數

cbClsExtra
需要附帶的資訊,一般很少用到
hInstance
屬于哪個執行個體
hIcon
圖示
hCrusor
光标
lpszClassName
目前視窗類的名稱,是使用這個類的唯一辨別符,是以這個視窗類名應該是唯一的

InitInstance

參數中的nCmdShow這個參數一定要進行判斷,不然隐藏視窗什麼的會沒法響應
在這個函數中,才正式CreateWindow了

Windows消息機制

硬體沒法直接操作軟體,因為有一堵牆,核心态沒法傳到使用者态

核心态接受到硬體的信号後,會把這個消息寫到記憶體共享區。使用者态會一直掃描共享區

消息響應機制是在Win32子系統中實作的,因為核心要求精簡,是以在核心中不會對消息進行翻譯(比如滑鼠右鍵的地方不

一樣,所響應的消息也不一樣,這就需要進行翻譯),會把這個消息寫到共享區

Win32會幫每個應用程式建立消息隊列,會對消息進行派發

通過焦點判斷是在哪個視窗,然後把消息派發給指定的視窗

通過GetMessage來擷取消息,搭配while達到一直擷取消息的目的

消息隊列不會出現滿的情況,因為前面一直在走,隻存在優先級的說法

MSG結構體

hwnd
視窗句柄
UINT message
消息值, UINT類型
消息數值化
lParam、wParam
附加消息
當通過message不能完全清楚的時候,就要依靠附加消息
time
時間, 消息發生時間
pt
目前消息建立時,滑鼠所在視窗的位置

通過 GetMessage API來取 目前應用程式的消息隊列的 消息

通過 DispatchMessage API來觸發 WndProc回調

WndProc(視窗過程)

在WndProc中處理視窗的各種消息
消息分類

視窗消息

指令消息

控件通知消息

裡面消息非常非常多,接近本質,但是開發難度大,是以微軟就寫了一套架構:MFC,MFC歸根結底就是對WIN32消息進行了封裝,封裝到了一個個的類裡面,再對消息進行路由,到需要響應的函數裡
MFC中,所調用的所有函數都是MFC的函數,與win32下的函數有點不一樣(比如MFC下的MessageBox和Win32下的MessageBox的參數有點不一樣),區分是Win32函數還是MFC中的函數的方法:

MessageBox() ->這個是類裡的,也就是MFC裡的 ::MessageBox() ->這個是全局的,也就是Win32的

繼續閱讀