青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

旅途

如果想飛得高,就該把地平線忘掉

[翻譯]Win32中安全的子類化

關(guān)于子類化的話題雖然有些舊,但它至今仍然不失為一種開發(fā)Windows的強(qiáng)有力技術(shù),在MFC的內(nèi)核、甚至.NET的內(nèi)核中都離不開它,希望本連載能對Windows開發(fā)的愛好者有所幫助。


原文標(biāo)題:Safe Subclassing in Win32
作者:Kyle Marsh
MSDN技術(shù)組

點(diǎn)擊此處查看原文

摘要

本文描述了Win32環(huán)境下的子類化,描述了它是如何工作的以及實(shí)現(xiàn)安全的子類化必須要遵循的規(guī)則。本文涵蓋了實(shí)例子類化和全局子類化。而超類化則作為一個全局子類化的可選替代方案被介紹。
Win16Win32,子類化并沒有發(fā)生特別顯著的變化,但是,在Win32中,一個應(yīng)用程序還是要遵守幾個新的子類化規(guī)則。其中最重要(也是最明顯的)就是一個應(yīng)用程序不能子類化屬于另一個進(jìn)程的窗口或者類,除非有工作區(qū)提供給應(yīng)用程序使用,否則這條規(guī)則不能被打破。

子類化的定義

子 類化是這樣一種技術(shù),它允許一個應(yīng)用程序截獲發(fā)往另一個窗口的消息。一個應(yīng)用程序通過截獲屬于另一個窗口的消息,從而實(shí)現(xiàn)增加、監(jiān)視或者修改那個窗口的缺 省行為。子類化是用來改變或者擴(kuò)展一個已存在的窗口的行為、而不用重新開發(fā)的有效途徑。想要獲得那些預(yù)定義控件窗口類(按鈕控件、編輯控件、列表控件、下 拉列表控件、靜態(tài)控件和滾動條控件)的功能而又要修改它們的某些行為的一個便利的方法就是對它們進(jìn)行子類化。例如,對于一個在對話框中的多行編輯框來說, 當(dāng)用戶按下Enter鍵時,對話框會關(guān)閉。通過對編輯控件子類化,一個應(yīng)用程序就能擁有一個可以往文本中插入回車和換行,而同時又不會關(guān)閉對話框的編輯控件,應(yīng)用程序不用為這個特殊的需要而去專門開發(fā)一個編輯控件。

子類化基礎(chǔ)

創(chuàng)建一個窗口的第一步是填充一個WNDCLASS 結(jié)構(gòu),并調(diào)用RegisterClass 函數(shù)來注冊一個窗口類。WNDCLASS 結(jié)構(gòu)的其中一個成員是這個窗口類的窗口過程地址,當(dāng)一個窗口被建立,32位版本的Microsoft Windows操作系統(tǒng)會取出WNDCLASS 結(jié)構(gòu)中的窗口過程地址,并把它復(fù)制到一個新的窗口信息結(jié)構(gòu)中。當(dāng)一條消息被發(fā)往這個窗口時,Windows通過窗口信息結(jié)構(gòu)中的這個地址調(diào)用這個窗口的窗口過程。為了子類化一個窗口,你要用一個新的窗口過程地址取代原窗口過程地址,從而使新的窗口過程可以接收發(fā)往原窗口過程的所有消息。
當(dāng)一個應(yīng)用程序子類化一個窗口時,它可對消息采取三種操作:(1)把消息傳遞給原窗口過程;(2)修改消息然后再傳遞給原窗口過程;(3)不再往下傳遞消息。
應(yīng)用程序子類化一個窗口時,可以決定什么情況下對所接收的消息做出反應(yīng),應(yīng)用程序可以在將消息傳遞給原窗口過程之前或(和)之后處理這條消息。

子類化的類型

有兩種子類化的類型,它們是實(shí)例子類化全局子類化.

實(shí)例子類化是子類化一個獨(dú)立的窗口信息結(jié)構(gòu),在實(shí)例子類化后,只有屬于一個特定的窗口實(shí)例的消息會被發(fā)送到新窗口過程。
全局子類化是替換一個窗口類的WNDCLASS 結(jié) 構(gòu)中的窗口過程地址,所有在這之后使用該窗口類建立起來的窗口都具有這個被替換的窗口過程地址。全局子類化只對那些在子類化生效之后創(chuàng)建的窗口有效,在進(jìn) 行子類化之前,如果已經(jīng)存在任何用這個被全局子類化的窗口類創(chuàng)建的窗口,這些已經(jīng)存在的窗口不會被子類化。如果應(yīng)用程序想要使子類化對這些已經(jīng)存在的窗口 生效,應(yīng)用程序必須子類化每一個已經(jīng)存在的該窗口類的實(shí)例。

Win32子類化規(guī)則

有兩條規(guī)則應(yīng)用到Win32下的實(shí)例子類化和全局子類化。

子類化僅被允許用在進(jìn)程內(nèi),一個應(yīng)用程序不能子類化屬于另一個進(jìn)程的窗口或窗口類。

這條規(guī)則的起因很簡單:Win32進(jìn)程具有獨(dú)立的進(jìn)程地址空間。在一個特定的進(jìn)程里,一個窗口過程有一個地址,而在另一個不同的進(jìn)程里,這個地址值并未指向這個窗口過程,結(jié)果就是,在一個進(jìn)程中,使用從另一個進(jìn)程獲得的地址替換后的地址并不能獲得期望的結(jié)果,因此32位的Windows不允許這種地址替換發(fā)生。SetWindowLong 和SetClassLong 函數(shù)中防止了這種類型的子類化發(fā)生。你不能子類化屬于另一個進(jìn)程的窗口或窗口類,你能做的就到此為止。

不過,也還是有些途徑能讓你把子類化的功能用到每一個進(jìn)程上。只要能得到位于某個進(jìn)程地址空間里的某個函數(shù),你就能該進(jìn)程里的任何東西進(jìn)行子類化。有幾個方法可以達(dá)到這個目的,其中最容易(也是最不講理的)的一個方法就是在下面這個注冊表鍵中添加一個動態(tài)鏈接庫名稱:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\APPINIT_DLLS

這個鍵導(dǎo)致Windows把你的DLL附加到系統(tǒng)里的每一個進(jìn)程上。你的DLL需要一些能在它要子類化的事件發(fā)生時被喚醒的方法,通常一個WH_CBT鉤子可以實(shí)現(xiàn)。這個DLL可以監(jiān)視HCBT_CREATEWND 事件,然后子類化它想子類化的窗口。例子程序CTL3D就使用了WH_CBT鉤子去實(shí)現(xiàn)它的子類化,盡管它沒有使用注冊表鍵為每個進(jìn)程實(shí)現(xiàn)子類化,想要得到CTL3D功能的應(yīng)用程序可以把他鏈接到進(jìn)程里。

另一個把你的子類化代碼附加到每個進(jìn)程的方法是使用一個系統(tǒng)鉤子。當(dāng)一個系統(tǒng)鉤子在另一個進(jìn)程的上下文中被調(diào)用時,系統(tǒng)就把包含這個鉤子的DLL加載到這個進(jìn)程空間中。樣例CTL3D 的代碼按照使用當(dāng)前線程中本地WH_CBT 鉤子的方式使用系統(tǒng)WH_CBT 鉤子。

第三個把子類化代碼附加到另一個進(jìn)程方法更復(fù)雜:它使用OpenProcess WriteProcessMemory CreateRemoteThread 函數(shù)將代碼注入其它進(jìn)程。我并不推薦這個方法,并且不打算更詳細(xì)地介紹怎么實(shí)現(xiàn)這個方法。如果有人堅持要使用這個方法, Jeffrey Richter 曾說過他計劃在Microsoft Systems Journal 中他的一個即將開辟的Win32 Q&A專欄中描述這項(xiàng)技術(shù)。

現(xiàn)在很多Windows 3.1的應(yīng)用程序子類化其它進(jìn)程來擴(kuò)展操作和增加一些很酷的功能。當(dāng)Windows轉(zhuǎn)向一個面向?qū)ο蟮南到y(tǒng)時,對象鏈接和嵌入技術(shù)(OLE)提供了更好的辦法去實(shí)現(xiàn)這些功能。在Windows的未來版本中,子類化其它進(jìn)程可能會變得更加困難,而使用OLE也許會更容易。我推薦的是,只要可能,你應(yīng)該讓你的應(yīng)用程序轉(zhuǎn)向OLE,而不要子類化其它進(jìn)程。

子類化操作不要直接使用原窗口過程地址。

Win16中,一個應(yīng)用程序會去使用從SetWindowLong SetClassLong函數(shù)返回的窗口過程地址來直接調(diào)用窗口過程,畢竟返回值只是一個簡單的指向函數(shù)的指針,為什么不使用它呢?在Win32中,這種做法卻是個禁忌。SetWindowLong SetClassLong函數(shù)的返回值可能根本不是原窗口過程的指針。Win32可能會返回指向一個數(shù)據(jù)結(jié)構(gòu)的指針,該數(shù)據(jù)結(jié)構(gòu)能被用來調(diào)用當(dāng)前的窗口過程。這種情況發(fā)生在Windows NT中,當(dāng)一個應(yīng)用程序用一個非Unicode的窗口過程子類化一個Unicode窗口時,或者用一個Unicode的窗口過程子類化一個非Unicode窗口時。在這兩種情況下, 操作系統(tǒng)必須為窗口收到的消息執(zhí)行一個UnicodeANSI之間的轉(zhuǎn)換。如果應(yīng)用程序直接使用指向這個結(jié)構(gòu)的指針調(diào)用窗口過程,應(yīng)用程序會立即導(dǎo)致一個異常。使用SetWindowLong SetClassLong函數(shù)返回的窗口地址的唯一做法是將返回值作為參數(shù)調(diào)用CallWindowProc 函數(shù)
實(shí)例子類化

SetWindowLong函數(shù)用來子類化一個窗口的一個實(shí)例。應(yīng)用程序必須知道子類化函數(shù)的地址,子類化函數(shù)是這樣一個函數(shù):它用來接收從Windows發(fā)來的消息,并把消息傳遞給原窗口過程。子類化函數(shù)必須在應(yīng)用程序中或DLL的模塊定義文件中導(dǎo)出。

應(yīng)用程序子類化窗口時,使用將要被子類化的窗口的句柄、GWL_WNDPROC標(biāo)志(WINDOWS.H中定義)以及新的子類化函數(shù)地址作為參數(shù)調(diào)用函數(shù) SetWindowLong 函數(shù)SetWindowLong返回一個DWORD類型的值,它是窗口的原窗口過程地址,應(yīng)用程序應(yīng)該保存該地址以用于將截獲的消息傳遞給原窗口過程,以及將來為窗口移除子類化之用。應(yīng)用程序使用原窗口過程的地址以及Windows消息所使用的hWnd, Message, wParamlParam 參數(shù)調(diào)用函數(shù)CallWindowProc 向原窗口過程傳遞消息。通常應(yīng)用程序只是簡單地把它從Windows接收來的數(shù)據(jù)傳遞給函數(shù)CallWindowProc

應(yīng)用程序同時需要原窗口過程地址來為窗口移除子類化。應(yīng)用程序通過再次調(diào)用函數(shù)SetWindowLong 來為窗口移除子類化,應(yīng)用程序向函數(shù)傳遞原窗口過程地址、GWL_WNDPROC 標(biāo)志以及已經(jīng)被子類化的窗口的句柄。

下面的代碼演示子類化一個編輯框控件以及為它移除子類化:

LONG FAR PASCAL SubClassFunc(HWND hWnd,UINT Message,WPARAM wParam,LONG lParam);

FARPROC lpfnOldWndProc;
HWND hEditWnd;

//
// Create an edit control and subclass it.
// The details of this particular edit control are not important.
//

hEditWnd 
= CreateWindow("EDIT""EDIT Test",
   WS_CHILD 
| WS_VISIBLE | WS_BORDER ,
   
005050,
   hWndMain,NULL,hInst,NULL);

//
// Now subclass the window that was just Created.
//

lpfnOldWndProc 
= (FARPROC)SetWindowLong(hEditWnd,GWL_WNDPROC, (DWORD) SubClassFunc);

.
.
.

//
// Remove the subclass for the edit control.
//

SetWindowLong(hEditWnd, GWL_WNDPROC, (DWORD) lpfnOldWndProc);

//
// Here is a sample subclass function.
//

LONG FAR PASCAL SubClassFunc(HWND hWnd,
   UINT Message,WPARAM wParam,LONG lParam)
{
   
//
   
// When the focus is in an edit control   inside a dialog box, the
   
//  default ENTER key action will not occur.
   
//
   if ( Message == WM_GETDLGCODE )
       
return DLGC_WANTALLKEYS;

   
return CallWindowProc(lpfnOldWndProc, hWnd, Message, wParam,lParam);
}


潛在的缺陷

只要留意下面的保障規(guī)則,實(shí)例子類化通常是安全的。

當(dāng)子類化一個窗口時,你必須了解誰在對窗口的行為負(fù)責(zé),例如,Windows負(fù) 責(zé)它所提供的所有控件的行為,而應(yīng)用程序則對它自己定義的所有窗口負(fù)責(zé)。子類化可以作用在同一進(jìn)程中的任何一個窗口上,但是,當(dāng)一個應(yīng)用程序子類化一個不 屬于它自己負(fù)責(zé)的窗口時,應(yīng)用程序必須確保子類化函數(shù)不會破壞那個窗口原有的行為。由于應(yīng)用程序并未控制那個窗口,它不應(yīng)該依賴任何在未來很有可能會被窗 口的擁有者改變的窗口信息。除非確切地知道窗口附加字節(jié)或窗口類附加字節(jié)的含義以及原窗口過程如何使用它們,否則一個子類化函數(shù)不應(yīng)該使用 它們。退一步說,即使應(yīng)用程序了解關(guān)于窗口附加字節(jié)或窗口類附加字節(jié)的每一件事,除非應(yīng)用程序負(fù)責(zé)這個窗口,否則也不要使用它們。如果一個應(yīng)用程序使用了 由另一個組件負(fù)責(zé)的窗口的窗口附加字節(jié),當(dāng)那個組件決定更新窗口并且改變附加字節(jié)的結(jié)構(gòu)時,子類化過程很有可能會失敗。正是因?yàn)檫@個原因,Microsoft 建議你不要子類化控件類,因?yàn)?/span>Windows負(fù)責(zé)著這些它所提供的控件,而且下一個版本的Windows可能會改變這些控件的外觀。如果你的應(yīng)用程序必須子類化一個Windows提供的控件,在新版本的Windows發(fā)布后,代碼很可能也需要更新。

由于實(shí)例子類化發(fā)生在一個窗口被創(chuàng)建之后,應(yīng)用程序子類化窗口無法向窗口添加任何附加字節(jié),應(yīng)用程序也許需要將被子類化的窗口的實(shí)例所需的所有數(shù)據(jù)保存在窗口的屬性列表中。

SetProp函數(shù)可以把屬性附加到一個窗口。應(yīng)用程序使用窗口的句柄、一個標(biāo)示屬性的字符串和屬性數(shù)據(jù)的句柄作為參數(shù)調(diào)用SetProp函數(shù)。數(shù)據(jù)的句柄通常從調(diào)用LocalAlloc GlobalAlloc 函數(shù)獲得。當(dāng)應(yīng)用程序要使用一個窗口的屬性列表中的這些數(shù)據(jù)時,可以使用窗口的句柄和標(biāo)示屬性的字符串作參數(shù)調(diào)用GetProp函數(shù),它返回用SetProp函數(shù)設(shè)置的數(shù)據(jù)的句柄。當(dāng)應(yīng)用程序不再需要這些數(shù)據(jù)或者當(dāng)窗口將要被銷毀時,應(yīng)用程序必須使用窗口的句柄和標(biāo)示屬性的字符串作參數(shù)調(diào)用RemoveProp函數(shù)從屬性列表中移除這些屬性數(shù)據(jù),該函數(shù)返回數(shù)據(jù)的句柄,然后應(yīng)用程序使用該句柄調(diào)用函數(shù)LocalFree 函數(shù)GlobalFree 關(guān)于函數(shù)SetProp, GetPropRemoveProp的更多信息,參見平臺SDK文檔。

當(dāng)一個應(yīng)用程序子類化一個已經(jīng)被子類化過的窗口時,所有的子類化會被按照們被設(shè)置時的相反順序移除。

全局子類化

全局子類化類似于實(shí)例子類化。應(yīng)用程序通過調(diào)用函數(shù)SetClassLong一個窗口類進(jìn)行全局子類化,就象在實(shí)例子類化中一樣,應(yīng)用程序同樣需要子類化函數(shù)的地址,并且這個子類化函數(shù)必須在應(yīng)用程序中或DLL的模塊定義文件中導(dǎo)出。

要全局子類化一個窗口類,應(yīng)用程序必須擁有一個該類的窗口實(shí)例。想要獲得該類的窗口實(shí)例,大多數(shù)應(yīng)用程序采 取建立一個屬于將要被全局子類化的窗口類的窗口的方法,當(dāng)應(yīng)用程序要移除子類化,也必須有一個窗口句柄,該句柄應(yīng)該是屬于應(yīng)用程序要子類化的窗口類的,因 此,為此而專門創(chuàng)建并保存一個窗口是個不錯的辦法。如果應(yīng)用程序需要創(chuàng)建它所要子類化的窗口類的窗口實(shí)例,這個窗口實(shí)例通常應(yīng)該是不可見的。在擁有了一個 正確類型的窗口句柄之后,應(yīng)用程序可以使用該窗口句柄、GCL_WNDPROC 標(biāo)志(在WINDOWS.H 中有定義)和新子類化函數(shù)的地址作為參數(shù)調(diào)用函數(shù)SetClassLong ,該函數(shù)返回一個DWORD 值,該值是該窗口類的原窗口過程地址。原窗口過程地址在全局子類化中的用處和在實(shí)例子類化中一樣,窗口消息也象在實(shí)例子類化中一樣通過調(diào)用函數(shù)CallWindowProc傳遞給原窗口過程。應(yīng)用程序可以通過再次調(diào)用SetClassLong函數(shù)來從窗口類移除子類化,這時需通過傳遞參數(shù)是原窗口過程地址、GCL_WNDPROC 標(biāo)志和被子類化的窗口類的窗口實(shí)例句柄。全局子類化一個控件的應(yīng)用程序必須在應(yīng)用程序結(jié)束時移除所做的子類化。

下面的代碼演示了全局子類化一個編輯框控件以及為它移除子類化:

LONG FAR PASCAL SubClassFunc(HWND hWnd,UINT,Message,WORD wParam,LONG lParam);
FARPROC lpfnOldClassWndProc;
HWND hEditWnd;

//
// Create an edit control and subclass it.
// Notice that the edit control is not visible.
// Other details of this particular edit control are not important.
//
hEditWnd = CreateWindow("EDIT""EDIT Test",
                        WS_CHILD,
                        
005050,
                        hWndMain,
                        NULL,
                        hInst,
                        NULL);

lpfnOldClassWndProc 
= (FARPROC)SetClassLong(hEditWnd, GCL_WNDPROC, (DWORD)SubClassFunc);
.
.
.
//
// To remove the subclass:
//
SetClassLong(hEditWnd, GWL_WNDPROC, (DWORD) lpfnOldClassWndProc);
DestroyWindow(hEditWnd);

潛在的缺陷

全局子類化具有和實(shí)例子類化一樣的限制,除非明確知道原窗口過程如何使用窗口類和窗口實(shí)例的附加字節(jié),否則應(yīng)用程序不應(yīng)嘗試去使用它們。如果數(shù)據(jù)必須和一個窗口相關(guān)聯(lián),可以象實(shí)例子類化中介紹的一樣,使用窗口屬性列表。

Win32, 全局子類化不會對任何其它進(jìn)程中的窗口類或從這些類創(chuàng)建的窗口實(shí)例生效,這對于Win16環(huán)境是個重大的變化。在系統(tǒng)中,Windows分別為每個Win32進(jìn)程單獨(dú)保存窗口類的信息,可以參見MSDN中的技術(shù)文章Window Classes in Win32來了解Windows在這方面的細(xì)節(jié)。目前全局子類化不能對其它進(jìn)程生效,這對開發(fā)人員來講,是個有用的技術(shù)。在Win16中, 全局子類化對被子類化的窗口類的每一個窗口實(shí)例都生效:不僅僅是屬于執(zhí)行了子類化操作的應(yīng)用程序,還包括了屬于整個系統(tǒng)的,這點(diǎn)讓人感到失望。通常這是應(yīng) 用程序不想達(dá)到的效果,所以應(yīng)用程序不得不使用更不方便,不好用的方法來改變從系統(tǒng)窗口類創(chuàng)建的窗口實(shí)例行為。而現(xiàn)在,在Win32中,使用全局子類化卻是非常容易的。

超類化

子類化一個窗口類,導(dǎo)致原本屬于窗口過程的消息被發(fā)送至子類化函數(shù),然后該子類化函數(shù)再把消息傳遞給原窗口 過程,而超類化(也被稱作窗口類克隆)是創(chuàng)建一個新的窗口類。這個新窗口類使用一個已經(jīng)存在的窗口類的窗口過程,來為它自己添加和已經(jīng)存在的窗口類一樣的 功能,超類化是基于其它窗口類的――也被稱為基類。基類常常是Windows預(yù)定義的控件類,但它也可以是任何其它窗口類。

注意   不要超類化滾動條控件類,因?yàn)?/span>Windows 使用該類名來為滾動條提供標(biāo)準(zhǔn)的行為。

超類化擁有它自己的窗口過程――超類化過程,它能起和子類化函數(shù)一樣的作用。超類化過程可以對消息實(shí)施三種動作: (1)直接將消息傳遞給原窗口過程 (2)在傳遞給原窗口過程前修改消息。 (3)不在往下傳遞消息。超類化可以在把消息傳遞給原窗口過程之前、之后或兩者都有的情況下對消息進(jìn)行操作。

和子類化函數(shù)不一樣的是,一個超類化過程也可以從Windows接收創(chuàng)建消息(例如WM_NCCREATE, WM_CREATE 之類的),超類化可以處理這些消息,但它必須把這些消息傳遞給原基類窗口過程,這樣基類窗口過程才能進(jìn)行初始化操作

應(yīng)用程序調(diào)用函數(shù)GetClassInfo 來使一個超類化基于一個基類。函數(shù)GetClassInfo 使用從基類的WNDCLASS 結(jié)構(gòu)得來的值填充一個新WNDCLASS結(jié)構(gòu)。然后超類化基類的應(yīng)用程序把新WNDCLASS結(jié)構(gòu)的hInstance域的值設(shè)置成應(yīng)用程序自己的實(shí)例句柄,同時也必須把lpszClassName的值設(shè)置成它要給該超類化的新名稱。如果基類擁有一個菜單,超類化該基類的應(yīng)用程序必須提供一個新菜單,該新菜單必須和基類的菜單擁有相同的菜單標(biāo)識。如果該超類化打算處理WM_COMMAND消息的,并且不再把該消息傳遞給基類的窗口過程, 那么菜單的標(biāo)識可以不必和基類的一樣。函數(shù)GetClassInfo 不會返回WNDCLASS結(jié)構(gòu)中域 lpszMenuName, lpszClassName, hInstance 的值。

最后一個必須在超類化的WNDCLASS 結(jié)構(gòu)中設(shè)置的是域lpfnWndProc,函數(shù)GetClassInfo 用原窗口過程的地址填充它。應(yīng)用程序必須保存這個地址,以便能用函數(shù)CallWindowProc把消息傳遞給基類的窗口過程。應(yīng)用程序要在WNDCLASS 結(jié)構(gòu)中把該地址值設(shè)置成它的超類化過程的地址。這個地址并不是個過程實(shí)例地址,因?yàn)楹瘮?shù)RegisterClass 才能得到過程實(shí)例地址。應(yīng)用程序可以修改WNDCLASS 結(jié)構(gòu)中其它域的值,以便符合應(yīng)用程序的需要。

應(yīng)用程序可以往窗口類附加字節(jié)和窗口實(shí)例附加字節(jié)后添加內(nèi)容,這是因?yàn)樗粤艘粋€新窗口類。當(dāng)應(yīng)用程序做這件事時,必須遵從兩個規(guī)則: (1) 原類附加字節(jié)和窗口實(shí)例附加字節(jié)不能被子類化覆蓋,這和在實(shí)例子類化與全局子類化中的原因一樣。(2) 如果應(yīng)用程序因自身需要為窗口類或窗口實(shí)例添加了附加字節(jié),它在引用這些附加字節(jié)時,必須保持是相對于基類所使用的附加字節(jié)數(shù)來引用的。而且因?yàn)槟硞€版本的基類所使用的附加字節(jié)數(shù)可能會與下一個版本不同,所以超類化自己的附加字節(jié)的起始偏移也因基類版本不同而不同。

當(dāng)填充完WNDCLASS 結(jié)構(gòu)后,應(yīng)用程序應(yīng)該調(diào)用函數(shù)RegisterClass 來注冊新的窗口類,現(xiàn)在,就可以創(chuàng)建并使用屬于該新窗口類的窗口實(shí)例了。

應(yīng)用程序通常是在Win16環(huán)境下使用超類化,因?yàn)樵?/span>Win16環(huán)境下全局子類化是令人沮喪的。現(xiàn)在在Win32下, 全局子類化不再令人失望,所以超類化就不再那么具有吸引力了。但在你的應(yīng)用程序要改變一些窗口的行為,而這些窗口又只是從一個系統(tǒng)窗口類所創(chuàng)建的所有窗口 中的一部分時,你仍然可以發(fā)現(xiàn)使用超類化是很有用的,相反,對從一個系統(tǒng)窗口類所創(chuàng)建的所有窗口都有效,那是全局子類化的功能。

總結(jié)

子類化是個強(qiáng)大的技術(shù),而且在Win32中的使用也沒有發(fā)生什么特別重大的改變,唯一的比較主要的變化是你不能再屬于另一個進(jìn)程的窗口或窗口類,雖然有方法可以繞過這個限制,如果你確實(shí)需要這種能力,我還是建議你把你的應(yīng)用程序移植到OLE,這比仍然依賴子類化更好。

好了,至此整篇文章都翻譯完了(終于趕在放假前弄完了),在Win32中安全的子類化(1)中,提供了本文的英語原文的鏈接,由于本人時間、水平有限,所以歡迎大家指正文中的錯誤和疏漏之處,謝謝!


posted on 2007-07-18 00:01 旅途 閱讀(666) 評論(0)  編輯 收藏 引用 所屬分類: 深入windows

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲裸体在线观看| 午夜视频久久久| 久久亚洲私人国产精品va媚药| 在线观看国产精品网站| 亚洲国产导航| 欧美日韩国产在线| 欧美一区激情视频在线观看| 久久精品人人做人人爽| 日韩视频免费观看高清在线视频 | 欧美亚州韩日在线看免费版国语版| 欧美一区二区三区免费在线看| 久久综合九色综合欧美就去吻 | 午夜精品一区二区三区在线播放 | 久久久99精品免费观看不卡| 日韩一级免费观看| 欧美在线三区| 亚洲一级特黄| 麻豆成人小视频| 欧美一区二区三区免费观看| 欧美护士18xxxxhd| 久久免费视频网站| 国产精品电影网站| 最近中文字幕日韩精品| 韩国成人精品a∨在线观看| 日韩一级免费观看| 亚洲激情在线| 久久精品视频免费| 国产一区二区日韩| 一区二区三区欧美在线观看| 久久久久久久一区二区| 亚洲欧美日本伦理| 欧美精品videossex性护士| 久久亚洲视频| 国产免费一区二区三区香蕉精| 亚洲欧洲一区二区在线观看| 在线播放国产一区中文字幕剧情欧美| 亚洲一区二区三区高清| 中文成人激情娱乐网| 欧美高清在线播放| 欧美激情第4页| 亚洲高清在线| 久久久久亚洲综合| 久久视频在线视频| 国产亚洲午夜高清国产拍精品| 亚洲影院免费观看| 亚洲欧美三级伦理| 国产精品福利在线观看网址| 一区二区高清在线观看| 亚洲视频电影图片偷拍一区| 欧美日韩二区三区| 亚洲精品乱码久久久久| 亚洲裸体视频| 欧美日韩国产黄| 亚洲精品一区二区在线| 亚洲国产精品黑人久久久| 久久久久九九视频| 免费不卡在线观看| 亚洲国产成人在线视频| 麻豆国产精品777777在线| 欧美成人日韩| 亚洲巨乳在线| 欧美日韩视频在线一区二区观看视频| 亚洲理伦在线| 午夜久久99| 国产综合久久久久久| 久久精品二区| 欧美jjzz| 在线视频精品| 国产伦精品一区| 久久精品国产一区二区三区| 欧美激情一区二区| 亚洲视频高清| 国产一区二区三区成人欧美日韩在线观看 | 亚洲欧美成人网| 久久国产色av| 亚洲高清自拍| 欧美日韩岛国| 性色av一区二区三区在线观看 | 国产网站欧美日韩免费精品在线观看| 久久av红桃一区二区小说| 欧美aaaaaaaa牛牛影院| 亚洲美女电影在线| 国产精品呻吟| 免费看精品久久片| 亚洲私人影吧| 欧美粗暴jizz性欧美20| 亚洲午夜三级在线| 狠狠色综合播放一区二区| 欧美精品v日韩精品v国产精品| 久久婷婷国产综合精品青草| 欧美精品九九| 久久综合亚州| 国产综合精品一区| 欧美chengren| 中文在线不卡| 久久亚洲免费| 中文国产亚洲喷潮| 国内精品免费在线观看| 欧美精品一二三| 香蕉视频成人在线观看 | 欧美揉bbbbb揉bbbbb| 亚洲欧美中文日韩在线| 亚洲国产精品久久久久秋霞影院| 亚洲欧美韩国| 日韩系列欧美系列| 狠狠色综合网| 国产精品无码专区在线观看| 欧美高清在线精品一区| 香蕉尹人综合在线观看| 99精品国产在热久久| 欧美+亚洲+精品+三区| 香蕉久久夜色| 宅男精品视频| 亚洲黄色成人久久久| 国产亚洲欧美日韩一区二区| 欧美视频在线一区| 欧美不卡激情三级在线观看| 久久精品国产精品亚洲| 亚洲一区欧美| 日韩小视频在线观看| 欧美激情性爽国产精品17p| 欧美中文字幕精品| 亚洲欧美韩国| 亚洲午夜女主播在线直播| 亚洲精品午夜精品| 亚洲高清不卡一区| 韩国av一区二区三区四区| 国产欧美丝祙| 国产精品专区第二| 国产精品国内视频| 欧美日韩中文字幕精品| 欧美久久久久久久久久| 免费观看一区| 麻豆精品视频在线观看视频| 久久久91精品| 久久久久网址| 久久久亚洲精品一区二区三区| 久久av一区| 久久高清免费观看| 久久成人免费电影| 久久激情视频免费观看| 久久精品免费播放| 久久久久久久波多野高潮日日| 久久久久久久综合狠狠综合| 久久久国产精品一区二区三区| 久久精品日产第一区二区三区| 久久国产99| 麻豆视频一区二区| 欧美黄色aaaa| 国产精品成人av性教育| 国产精品青草久久| 国产日韩一区| 伊人成人开心激情综合网| 1000部精品久久久久久久久| 亚洲国产一区二区在线| 亚洲人体1000| 亚洲午夜激情网站| 欧美一级二区| 久久久久久97三级| 欧美粗暴jizz性欧美20| 亚洲精品免费看| 亚洲无亚洲人成网站77777| 香蕉久久一区二区不卡无毒影院| 久久久久久亚洲精品杨幂换脸 | 国产欧美日韩在线视频| 一区二区视频在线观看| 亚洲精品综合| 亚洲综合首页| 久久综合精品一区| 亚洲国产经典视频| 一区二区三区回区在观看免费视频| 亚洲一区二区三区三| 久久精品欧美日韩| 欧美久久成人| 国产婷婷一区二区| 亚洲欧洲日产国产网站| 亚洲一区在线观看视频| 久久久免费av| 亚洲精品免费一二三区| 午夜精品99久久免费| 欧美freesex8一10精品| 国产乱码精品| 亚洲精品中文字幕有码专区| 欧美一区二区精品| 欧美激情成人在线视频| 亚洲欧美日韩国产| 欧美二区在线播放| 国产老女人精品毛片久久| 亚洲精选成人| 久久久久久国产精品mv| 亚洲美女尤物影院| 久久av最新网址| 欧美日韩三级| 亚洲国产精品久久91精品| 午夜精品理论片| 亚洲欧洲日本专区| 久久久久久久激情视频| 国产精品伦理| 一区二区欧美精品| 欧美大片第1页|