windows界面編程最基本的元素就是“窗口”,一個窗口的產生一般要經過填寫窗口類結構,對窗口類注冊,和創建窗口,最終顯示出來給用戶見到。大概代碼如下:
//填寫窗口類結構
WNDCLASS wcWin;
wcWind.lpfnWndProc = (WNDPROC)WndProc; //窗口消息處理
...
wcWind.lpszClassName = "winClassName"; //窗口類的名字
//注冊窗口
RegisterClass(&wcWin);
//創建窗口
HWND hWnd = CreateWindow("winClassName", "my window",
...);
在WTL中,對windows的一套窗口機制提供了面向對象的封裝,有著完善的windows界面架構,對一些常用的API,控件等等都做了封裝,而且自己也可以繼承性的在此基礎上二次開發。所以在實際的編程中,可以省去不少的工作量。越扯越遠了,ft。
在WTL/ATL中,提供了DECLARE_WND_CLASS,
DECLARE_WND_CLASS_EX, or
DECLARE_WND_SUPERCLASS
這三個宏來實現窗口類結構的填寫,其中DECLARE_WND_SUP
ERCLASS 在msdn中的介紹是 :CWndClassInfo
registers information for a window class that is based on an
existing class but uses a different window procedure. This
technique is called
superclassing. 這段話大意就是講
“可以基于一個已經存在的窗口類,但是使用一個不同的消息處理函數,去生成一個新的窗口類——這種技術就稱為超類化” ,這個超類化的特點就是:
1,已經存在一個注冊的窗口類A。(注意,此窗口類有自己的消息處理函數)
2,創建一個新的窗口類B,但是是以上面的A為基礎(即窗口類的名字相同等)。
3,可以寫個新的消息處理模塊做為B的消息處理,此時窗口A的所有消息就被這個新的消息處理所截取了。
由上可知,在程序中使用超類,可以截取某個窗口創建之初的所有消息,從而可以達到一些目的,嘿嘿~
一個例子(設想):
API的MessageBox非常好用,調用很簡單,但是如果想要對它的彈出位置等進行修改的話,確不容易,因為這個調用不會返回句柄,也沒有消息可以獲取,如果真要修改它彈出的默認位置的話,大概有下面幾種辦法:
1,自己寫一個messagebox,要考慮到那么多的情況,寫出來也不是很方便啊。
2,可以在調用MessageBox之前設置一個timer,在timer中不斷FindWindow這個messagebox,找到后就可以得到句柄,從而就可以SetWindowPos改表位置了。
3,可以使用HOOK技術,截了messagebox的WN_INITDIALOG消息,在消息處理中就可以。。。
4,使用“超類化”!過程為:在本實例中找一個已知類名(可以用spy++先看MessageBox的類名)的MessageBox窗口類,找到后將此類
的信息賦給一個新的窗口類,將一個新的窗口消息處理過程賦給它,然后注冊新窗口類,注冊成功后,當這個MessageBox要被創建出來后發的消息就都自
己的新消息處理函數所截獲了,在消息處理函數中就可以想怎么樣就怎么樣了。