如何建設(shè)一個(gè)普通網(wǎng)頁(yè)網(wǎng)站wordpress4.5.2文章采集
鶴壁市浩天電氣有限公司
2026/01/22 08:22:03
如何建設(shè)一個(gè)普通網(wǎng)頁(yè)網(wǎng)站,wordpress4.5.2文章采集,wordpress插件手動(dòng)安裝插件,怎么做阿里巴巴英文網(wǎng)站在這一講我們將學(xué)習(xí)什么是超類化以及它有什么作用#xff1b;同時(shí)你還會(huì)學(xué)到怎樣在自己的窗口中用Tab鍵在控件中切換這一技巧。理論#xff1a;在你的程序生涯中你肯定遇到過(guò)這樣的情況#xff0c;你需要一系列的控件#xff0c;但它們之間卻只有一點(diǎn)點(diǎn)的不同。例如#x…在這一講我們將學(xué)習(xí)什么是超類化以及它有什么作用同時(shí)你還會(huì)學(xué)到怎樣在自己的窗口中用Tab鍵在控件中切換這一技巧。理論在你的程序生涯中你肯定遇到過(guò)這樣的情況你需要一系列的控件但它們之間卻只有一點(diǎn)點(diǎn)的不同。例如你可能需要10個(gè)只接受數(shù)字的 Edit 控件當(dāng)然你可以通過(guò)多種方法來(lái)達(dá)到這個(gè)目的。創(chuàng)建自己的類并用它實(shí)例化為那些控件創(chuàng)建那些 Edit 控件并把它們?nèi)孔宇惢惢疎dit 控件第一種方法太乏味了因?yàn)槟惚仨氉约簩?shí)現(xiàn)Edit 控件的每個(gè)功能但這項(xiàng)工作不是輕松就能完成的。第二種方法好于第一種但仍然要做許多工作子類化幾個(gè)Edit 控件還可以接受但若要子類化十幾二十個(gè)這項(xiàng)工作簡(jiǎn)直就是一場(chǎng)惡夢(mèng)。在這種情況下就應(yīng)該使用超類化這個(gè)技巧它是用于控制某一個(gè)特定窗口類的特殊方法。通過(guò)這種控制就可以修改窗口類的特性使之符合你的要求然后再創(chuàng)建那一堆控件就可以了。超類化有如下幾個(gè)步驟通過(guò)調(diào)用 GetClassInfoEx 來(lái)獲得想要進(jìn)行超類化操作的窗口類的信息。函數(shù)GetClassInfoEx 需要一個(gè)指向 WNDCLASSEX 結(jié)構(gòu)的指針用于當(dāng)成功返回時(shí)填入窗口類的信息。按需要修改 WNDCLASSEX 結(jié)構(gòu)的成員其中有兩個(gè)成員必須修改hInstance 存放程序的實(shí)例句柄lpszClassName 指向一個(gè)新類名的指針不必修改成員 lpfnWndProc但大多數(shù)情況下還是需要的。但要記住如果要使用函數(shù) CallWindowProc 調(diào)用老窗口的過(guò)程那就必須保存成員 lpfnWndProc 的原值。注冊(cè)修改完的 WNDCLASSEX 結(jié)構(gòu)得到一個(gè)具有舊窗口類某些特性的新窗口類。用新窗口類創(chuàng)建窗口如果要?jiǎng)?chuàng)建具有相同特性的多個(gè)控件超類化就比子類化要好。舉例.386.model flat,stdcalloption casemap:noneinclude masm32includewindows.incinclude masm32includeuser32.incinclude masm32includekernel32.incincludelib masm32libuser32.libincludelib masm32libkernel32.libWM_SUPERCLASS equ WM_USER5WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORDEditWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD.dataClassName db SuperclassWinClass,0AppName db Superclassing Demo,0EditClass db EDIT,0OurClass db SUPEREDITCLASS,0Message db You pressed the Enter key in the text box!,0.data?hInstance dd ?hwndEdit dd 6 dup(?) 存放6個(gè)窗口句柄的數(shù)組OldWndProc dd ? 原來(lái)的窗口過(guò)程.codestart:invoke GetModuleHandle, NULLmov hInstance,eaxinvoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULTinvoke ExitProcess,eaxWinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORDLOCAL wc:WNDCLASSEXLOCAL msg:MSGLOCAL hwnd:HWNDmov wc.cbSize,SIZEOF WNDCLASSEXmov wc.style, CS_HREDRAW or CS_VREDRAWmov wc.lpfnWndProc, OFFSET WndProcmov wc.cbClsExtra,NULLmov wc.cbWndExtra,NULLpush hInstpop wc.hInstancemov wc.hbrBackground,COLOR_APPWORKSPACEmov wc.lpszMenuName,NULLmov wc.lpszClassName,OFFSET ClassNameinvoke LoadIcon,NULL,IDI_APPLICATIONmov wc.hIcon,eaxmov wc.hIconSm,eaxinvoke LoadCursor,NULL,IDC_ARROWmov wc.hCursor,eaxinvoke RegisterClassEx, addr wcinvoke CreateWindowEx,WS_EX_CLIENTEDGEWS_EX_CONTROLPARENT,ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWS_CAPTIONWS_SYSMENUWS_MINIMIZEBOXWS_MAXIMIZEBOXWS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,350,220,NULL,NULL,hInst,NULLmov hwnd,eax.while TRUEinvoke GetMessage, ADDR msg,NULL,0,0.BREAK .IF (!eax)invoke TranslateMessage, ADDR msginvoke DispatchMessage, ADDR msg.endwmov eax,msg.wParamretWinMain endpWndProc proc uses ebx edi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAMLOCAL wc:WNDCLASSEX.if uMsgWM_CREATEmov wc.cbSize,sizeof WNDCLASSEXinvoke GetClassInfoEx,NULL,addr EditClass,addr wcpush wc.lpfnWndProcpop OldWndProcmov wc.lpfnWndProc, OFFSET EditWndProcpush hInstancepop wc.hInstancemov wc.lpszClassName,OFFSET OurClassinvoke RegisterClassEx, addr wcxor ebx,ebxmov edi,20.while ebx6invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,WS_CHILDWS_VISIBLEWS_BORDER,20,edi,300,25,hWnd,ebx,hInstance,NULLmov dword ptr [hwndEdit4*ebx],eaxadd edi,25inc ebx.endwinvoke SetFocus,hwndEdit.elseif uMsgWM_DESTROYinvoke PostQuitMessage,NULL.elseinvoke DefWindowProc,hWnd,uMsg,wParam,lParamret.endifxor eax,eaxretWndProc endpEditWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD.if uMsgWM_CHARmov eax,wParam.if (al0 al9) || (alA alF) || (ala alf) || alVK_BACK處理字符0~9A~Fa~f這幾個(gè)十六進(jìn)制數(shù).if ala alfsub al,20h如果是字符a~f則把它們變?yōu)榇髮?xiě).endifinvoke CallWindowProc,OldWndProc,hEdit,uMsg,eax,lParamret.endif.elseif uMsgWM_KEYDOWNmov eax,wParam.if alVK_RETURNinvoke MessageBox,hEdit,addr Message,addr AppName,MB_OKMB_ICONINFORMATIONinvoke SetFocus,hEdit.elseif alVK_TABinvoke GetKeyState,VK_SHIFTtest eax,80000000.if ZERO?invoke GetWindow,hEdit,GW_HWNDNEXT.if eaxNULLinvoke GetWindow,hEdit,GW_HWNDFIRST.endif.elseinvoke GetWindow,hEdit,GW_HWNDPREV.if eaxNULLinvoke GetWindow,hEdit,GW_HWNDLAST.endif.endifinvoke SetFocus,eaxxor eax,eaxret.elseinvoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParamret.endif.elseinvoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParamret.endifxor eax,eaxretEditWndProc endpend start分析這個(gè)程序創(chuàng)建了一個(gè)在其客戶區(qū)有六個(gè)被修改的 Edit 控件的簡(jiǎn)單窗口這些 Edit控件只接受十六進(jìn)制的數(shù)字。實(shí)際上這個(gè)例子是通過(guò)修改窗口了類化的例子得來(lái)的。這個(gè)程序開(kāi)始和其它程序一樣有趣的部分出現(xiàn)在主窗口被創(chuàng)建的時(shí)候.if uMsgWM_CREATEmov wc.cbSize,sizeof WNDCLASSEXinvoke GetClassInfoEx,NULL,addr EditClass,addr wc必須用想進(jìn)行超類化操作的類數(shù)據(jù)填充 WNDCLASSEX 結(jié)構(gòu)在我們的例子中就是類 Edit 記住在調(diào)用函數(shù) GetClassInfoEx 之前必須填寫(xiě)成員 cbSize否則函數(shù)調(diào)用 GetClassInfoEx不會(huì)在 WNDCLASSEX 結(jié)構(gòu)中填入正確的返回值。成功返回后變量 wc中保存的就是想要?jiǎng)?chuàng)建一個(gè)新類所需要的所有信息。push wc.lpfnWndProcpop OldWndProcmov wc.lpfnWndProc, OFFSET EditWndProcpush hInstancepop wc.hInstancemov wc.lpszClassName,OFFSET OurClass現(xiàn)在必須修改變量 wc 的一些屬性第一個(gè)要修改的就是指向窗口過(guò)程的指針。因?yàn)樵谛麓翱谶^(guò)程中函數(shù) CallWindowProx 要用到老窗口過(guò)程因此得把它保存到一個(gè)變量中以便使用。這個(gè)技巧和在子類化中用到的一樣只不過(guò)不是調(diào)用 SetWindowLong 而是直接修改 WNDCLASSEX 結(jié)構(gòu)罷了。接下來(lái)必須得為這個(gè)新類取個(gè)名字。invoke RegisterClassEx, addr wc當(dāng)所有這些都完成時(shí)注冊(cè)這個(gè)新類就會(huì)得到一個(gè)具有舊類某些特征的新類了。xor ebx,ebxmov edi,20.while ebx6invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,WS_CHILDWS_VISIBLEWS_BORDER,20,edi,300,25,hWnd,ebx,hInstance,NULLmov dword ptr [hwndEdit4*ebx],eaxadd edi,25inc ebx.endwinvoke SetFocus,hwndEdit注冊(cè)完新類就可以創(chuàng)建基于它的窗口了在上面的程序片斷中用寄存器 ebx 來(lái)保存已創(chuàng)建的窗口數(shù)目用寄存器 edi 來(lái)保存窗口左上角的 y 坐標(biāo)。創(chuàng)建一個(gè)新窗口時(shí)把它的句柄保存在一個(gè)雙字的數(shù)組中當(dāng)創(chuàng)建完所有的窗口后設(shè)定輸入焦點(diǎn)為所創(chuàng)建的第一個(gè)窗口。這時(shí)已經(jīng)有6個(gè)只能接受十六進(jìn)制數(shù)字的 edit 窗口控件了替換的窗口過(guò)程處理了字符過(guò)濾這實(shí)際上和在子類化中的例子是一樣的。但不必做子類化那些窗口的額外工作了。在此程序中通過(guò)使用 Tabs 鍵來(lái)在各個(gè) Edit 控件中切換來(lái)使得這個(gè)程序更加有趣。一般來(lái)說(shuō)如果使用對(duì)話框?qū)υ捒蚬芾砥鲿?huì)處理好所有這些問(wèn)題即按下 Tabs 輸入焦點(diǎn)切換到下一個(gè)控件窗口中按下 Shift-Tabs 輸入焦點(diǎn)切換到上一個(gè)控件窗口中但一個(gè)簡(jiǎn)單的窗口不具有這個(gè)功能必須子類化它們以處理 Tabs 鍵。在這個(gè)例子中不必一個(gè)一個(gè)去子類化已經(jīng)進(jìn)行過(guò)超類化操作的這些控件可以使用一種集中控制切換策略。.elseif alVK_TABinvoke GetKeyState,VK_SHIFTtest eax,80000000.if ZERO?invoke GetWindow,hEdit,GW_HWNDNEXT.if eaxNULLinvoke GetWindow,hEdit,GW_HWNDFIRST.endif.elseinvoke GetWindow,hEdit,GW_HWNDPREV.if eaxNULLinvoke GetWindow,hEdit,GW_HWNDLAST.endif.endifinvoke SetFocus,eaxxor eax,eaxret上面是摘自于 EditWndClass 過(guò)程的程序片斷它檢查用戶是否按下了 Tabs 鍵若是就調(diào)用函數(shù) GetKeyState 來(lái)檢查 SHIFT 鍵是否也被同時(shí)按下了。函數(shù) GetKeyState 在寄存器 eax 中設(shè)立一個(gè)返回值用于判斷某個(gè)特定的鍵是否被按下了若按下了則把 eax 的的最高位置1否則把最高位清0。所以只要用 80000000h 來(lái)測(cè)試返回值就行了若最高位是1則說(shuō)明用戶按下了 SHIFT-Tabs這需要單獨(dú)處理否則說(shuō)明只按下 Tabs 鍵調(diào)用函數(shù) GetWindow 來(lái)獲得 hEdit 所指向窗口的下一個(gè)窗口句柄若該函數(shù)返回 NULL 說(shuō)明這是當(dāng)前窗口是窗口鏈中最后一個(gè)窗口了應(yīng)該通過(guò)以參數(shù) GW_HWNDFIRST 調(diào)用函數(shù) GetWindow 來(lái)卷回到窗口鏈中的第一個(gè)窗口控件。SHIFT-Tabs 的處理過(guò)程和這正好相反。