Win32 SDK基礎(chǔ)(六)之詳解窗口類的查找過程和相關(guān)API

一、窗口類的查找過程

? ? 上一文中,我們介紹了windows系統(tǒng)三種窗口類——系統(tǒng)窗口類、全局窗口類和局部窗口類。每種窗口類在操作系統(tǒng)中的作用域不同,而且每個作用域內(nèi)注冊的窗口類名稱是不能重復(fù)的。而創(chuàng)建窗口時往往會在系統(tǒng)、全局、局部范圍按照窗口類名稱進(jìn)行尋找,尋找過程總結(jié)如下:

(1)操作系統(tǒng)根據(jù)傳入的窗口類名稱,現(xiàn)在局部窗口類中進(jìn)行查找,如果找到執(zhí)行第2步,如果未找到執(zhí)行第3步。

(2)比較局部窗口類和創(chuàng)建窗口時傳入的HINSTANCE變量。如果發(fā)現(xiàn)相等,說明創(chuàng)建和注冊的窗口在同一個模塊,創(chuàng)建窗口返回。如果不相等,繼續(xù)執(zhí)行第3步。

(3)在應(yīng)用程序全局窗口類中進(jìn)行查找,如果找到,執(zhí)行第4步,如果未找到執(zhí)行第5步。

(4)使用找到的窗口類的信息,創(chuàng)建窗口并返回。

(5)在系統(tǒng)窗口類中查找,如果找到就創(chuàng)建窗口,未找到就是創(chuàng)建窗口失敗。

二、注冊窗口類的變量 Register變量和RegisterClassEx

?????RegisterClass和RegisterClassEx都能用于注冊窗口類,他們兩個的原型分別如下:

ATOM?WINAPI?RegisterClass(  ??_In_?const?WNDCLASS?*lpWndClass  );  ATOM?WINAPI?RegisterClassEx(  ??_In_?const?WNDCLASSEX?*lpwcx  );

?????API原型上看可以看出,二者的區(qū)別主要在于接收的參數(shù)上,這個參數(shù)就是我們需要注冊的窗口類。這兩個窗口類聲明如下:

typedef?struct?tagWNDCLASS?{  ??UINT??????style;  ??WNDPROC???lpfnWndProc;  ??int???????cbClsExtra;  ??int???????cbWndExtra;  ??HINSTANCE?hInstance;  ??HICON?????hIcon;  ??HCURSOR???hCursor;  ??HBRUSH????hbrBackground;  ??LPCTSTR???lpszMenuName;  ??LPCTSTR???lpszClassName;  }?WNDCLASS,?*PWNDCLASS;
typedef?struct?tagWNDCLASSEX?{  ??UINT??????cbSize;  ??UINT??????style;  ??WNDPROC???lpfnWndProc;  ??int???????cbClsExtra;  ??int???????cbWndExtra;  ??HINSTANCE?hInstance;  ??HICON?????hIcon;  ??HCURSOR???hCursor;  ??HBRUSH????hbrBackground;  ??LPCTSTR???lpszMenuName;  ??LPCTSTR???lpszClassName;  ??HICON?????hIconSm;  }?WNDCLASSEX,?*PWNDCLASSEX;

? ? 從上面的代碼可以看到,兩個窗口類變量的主要區(qū)別在于WNDCLASSEX含有cbSize窗口的結(jié)構(gòu)體大小和hIconSm窗口的小圖標(biāo)句柄。其他參數(shù)的含義請自行參考MSDN

三、獲取已注冊的窗口信息GetClassInfo

GetClassInfo()??API可以獲取已經(jīng)注冊的窗口的信息,其變量原型如下:

BOOL?WINAPI?GetClassInfo(  ??_In_opt_?HINSTANCE??hInstance,  ??_In_?????LPCTSTR????lpClassName,  ??_Out_????LPWNDCLASS?lpWndClass  );

hInstance—— 是設(shè)置查找的作用域,如果設(shè)為變量,會從系統(tǒng)、全局和局部三個作用域查找。

lpClassName?—— 是要查找的窗口類名稱。

lpWndClass?—— 傳入的WndClass結(jié)構(gòu)體變量的地址,用于接收窗口類信息。

?????我們來查找上文創(chuàng)建的Button類的窗口信息:

WNDCLASS?wc;  if?(GetClassInfo(NULL,?"Button",?&wc)?==?false)  MessageBox(NULL,"GetClassInfo?Faile",NULL,NULL);

??????我們來通過設(shè)置斷點,查看獲取的Button窗口類的信息:

四、卸載窗口類UnregisterClass

? ? 我們可以通過UnregisterClass可以將已經(jīng)注冊的窗口類進(jìn)行卸載,其原型如下:

BOOL?WINAPI?UnregisterClass(  ??_In_?????LPCTSTR???lpClassName,  ??_In_opt_?HINSTANCE?hInstance  );

lpClassName?—— 是要卸載的窗口類名稱。

hInstance —— 是設(shè)置查找的作用域,如果設(shè)為NULL,會從系統(tǒng)、全局和局部三個作用域查找。

????以下代碼,將注冊的Button窗口類進(jìn)行卸載:

?if?(UnregisterClass("Button",NULL)?==?false)  MessageBox(NULL,?"UnregisterClass?Faile",?NULL,?NULL);

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點贊6 分享