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

旅途

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

超類化

 在這一講我們將學習什么是超類化以及它有什么作用;同時你還會學到怎樣在自己的窗口中用Tab鍵在控件中切換這一技巧。

理論:

在你的程序生涯中你肯定遇到過這樣的情況,你需要一系列的控件,但它們之間卻只有一點點的不同。例如,你可能需要10個只接受數字的 Edit 控件,當然你可以通過多種方法來達到這個目的。

創(chuàng)建自己的類并用它實例化為那些控件
創(chuàng)建那些 Edit 控件并把它們全部子類化
超類化Edit 控件
第一種方法太 乏味了,因為你必須自己實現Edit 控件的每個功能,但這項工作不是輕松就能完成的。第二種方法好于第一種,但仍然要做許多工作,子類化幾個Edit 控件還可以接受,但若要子類化十幾二十個,這項工作簡直就是一場惡夢。在這種情況下就應該使用超類化這個技巧,它是用于控制某一個特定窗口類的特殊方法。 通過這種控制就可以修改窗口類的特性使之符合你的要求,然后再創(chuàng)建那一堆控件就可以了。

超類化有如下幾個步驟:

通過調用 GetClassInfoEx 來獲得想要進行超類化操作的窗口類的信息。函數GetClassInfoEx 需要一個指向 WNDCLASSEX 結構的指針,用于當成功返回時填入窗口類的信息。
按需要修改 WNDCLASSEX 結構的成員,其中有兩個成員必須修改:
hInstance 存放程序的實例句柄
lpszClassName 指向一個新類名的指針
不必修改成員 lpfnWndProc,但大多數情況下還是需要的。但要記住如果要使用函數 CallWindowProc 調用老窗口的過程,那就必須保存成員 lpfnWndProc 的原值。
注冊修改完的 WNDCLASSEX 結構,得到一個具有舊窗口類某些特性的新窗口類。
用新窗口類創(chuàng)建窗口
如果要創(chuàng)建具有相同特性的多個控件,超類化就比子類化要好。

舉例:

.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
WM_SUPERCLASS equ WM_USER+5
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
EditWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data
ClassName db "SuperclassWinClass",0
AppName db "Superclassing Demo",0
EditClass db "EDIT",0
OurClass db "SUPEREDITCLASS",0
Message db "You pressed the Enter key in the text box!",0

.data?
hInstance dd ?
hwndEdit dd 6 dup(?) ;存放6個窗口句柄的數組
OldWndProc dd ? ;原來的窗口過程

.code
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT
invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND

mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_APPWORKSPACE
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,WS_EX_CLIENTEDGE+WS_EX_CONTROLPARENT,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,\
CW_USEDEFAULT,350,220,NULL,NULL,\
hInst,NULL
mov hwnd,eax

.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp

WndProc proc uses ebx edi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL wc:WNDCLASSEX
.if uMsg==WM_CREATE
mov wc.cbSize,sizeof WNDCLASSEX
invoke GetClassInfoEx,NULL,addr EditClass,addr wc
push wc.lpfnWndProc
pop OldWndProc
mov wc.lpfnWndProc, OFFSET EditWndProc
push hInstance
pop wc.hInstance
mov wc.lpszClassName,OFFSET OurClass
invoke RegisterClassEx, addr wc
xor ebx,ebx
mov edi,20
.while ebx<6
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,\
WS_CHILD+WS_VISIBLE+WS_BORDER,20,\
edi,300,25,hWnd,ebx,\
hInstance,NULL
mov dword ptr [hwndEdit+4*ebx],eax
add edi,25
inc ebx
.endw
invoke SetFocus,hwndEdit
.elseif uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp

EditWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
.if uMsg==WM_CHAR
mov eax,wParam
.if (al>="0" && al<="9") || (al>="A" && al<="F") || (al>="a" && al<="f") || al==VK_BACK
;處理字符0~9,A~F,a~f,這幾個十六進制數
.if al>="a" && al<="f"
sub al,20h
如果是字符a~f,則把它們變?yōu)榇髮?br>.endif
invoke CallWindowProc,OldWndProc,hEdit,uMsg,eax,lParam
ret
.endif
.elseif uMsg==WM_KEYDOWN
mov eax,wParam
.if al==VK_RETURN
invoke MessageBox,hEdit,addr Message,addr AppName,MB_OK+MB_ICONINFORMATION
invoke SetFocus,hEdit
.elseif al==VK_TAB
invoke GetKeyState,VK_SHIFT
test eax,80000000
.if ZERO?
invoke GetWindow,hEdit,GW_HWNDNEXT
.if eax==NULL
invoke GetWindow,hEdit,GW_HWNDFIRST
.endif
.else
invoke GetWindow,hEdit,GW_HWNDPREV
.if eax==NULL
invoke GetWindow,hEdit,GW_HWNDLAST
.endif
.endif
invoke SetFocus,eax
xor eax,eax
ret
.else
invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam
ret
.endif
.else
invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
EditWndProc endp
end start


分析

這個程序創(chuàng)建了一個在其客戶區(qū)有六個被修改的 Edit 控件的簡單窗口,這些 Edit控件只接受十六進制的數字。實際上,這個例子是通過修改窗口了類化的例子得來的。這個程序開始和其它程序一樣,有趣的部分出現在主窗口被創(chuàng)建的時候:

.if uMsg==WM_CREATE
mov wc.cbSize,sizeof WNDCLASSEX
invoke GetClassInfoEx,NULL,addr EditClass,addr wc

必須用想進行超類化操作的類數據填充 WNDCLASSEX 結構,在我們的例子中就是類 Edit ,記住在調用函數 GetClassInfoEx 之前必須填寫成員 cbSize,否則函數調用 GetClassInfoEx不會在 WNDCLASSEX 結構中填入正確的返回值。成功返回后,變量 wc中保存的就是想要創(chuàng)建一個新類所需要的所有信息。

push wc.lpfnWndProc
pop OldWndProc
mov wc.lpfnWndProc, OFFSET EditWndProc
push hInstance
pop wc.hInstance
mov wc.lpszClassName,OFFSET OurClass

現在必須修改變量 wc 的一些屬性:第一個要修改的就是指向窗口過程的指針。因為在新窗口過程中函數 CallWindowProx 要用到老窗口過程,因此得把它保存到一個變量中以便使用。這個技巧和在子類化中用到的一樣,只不過不是調用 SetWindowLong 而是直接修改 WNDCLASSEX 結構罷了。接下來必須得為這個新類取個名字。

invoke RegisterClassEx, addr wc

當所有這些都完成時,注冊這個新類就會得到一個具有舊類某些特征的新類了。

xor ebx,ebx
mov edi,20
.while ebx<6
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,\
WS_CHILD+WS_VISIBLE+WS_BORDER,20,\
edi,300,25,hWnd,ebx,\
hInstance,NULL
mov dword ptr [hwndEdit+4*ebx],eax
add edi,25
inc ebx
.endw
invoke SetFocus,hwndEdit

注冊完新類就可以創(chuàng)建基于它的窗口了:
在上面的程序片斷中,用寄存器 ebx 來保存已創(chuàng)建的窗口數目,用寄存器 edi 來保存窗口左上角的 y 坐標。創(chuàng)建一個新窗口時,把它的句柄保存在一個雙字的數組中,當創(chuàng)建完所有的窗口后,設定輸入焦點為所創(chuàng)建的第一個窗口。

這時已經有6個只能接受十六進制數字的 edit 窗口控件了,替換的窗口過程處理了字符過濾,這實際上和在子類化中的例子是一樣的。但不必做子類化那些窗口的額外工作了。

在此程序中,通過使用 Tabs 鍵來在各個 Edit 控件中切換來使得這個程序更加有趣。一般來說,如果使用對話框,對話框管理器會處理好所有這些問題,即:
按 下 Tabs 輸入焦點切換到下一個控件窗口中,按下 Shift-Tabs 輸入焦點切換到上一個控件窗口中;但一個簡單的窗口不具有這個功能,必須子類化它們以處理 Tabs 鍵。在這個例子中,不必一個一個去子類化已經進行過超類化操作的這些控件,可以使用一種集中控制切換策略。

.elseif al==VK_TAB
invoke GetKeyState,VK_SHIFT
test eax,80000000
.if ZERO?
invoke GetWindow,hEdit,GW_HWNDNEXT
.if eax==NULL
invoke GetWindow,hEdit,GW_HWNDFIRST
.endif
.else
invoke GetWindow,hEdit,GW_HWNDPREV
.if eax==NULL
invoke GetWindow,hEdit,GW_HWNDLAST
.endif
.endif
invoke SetFocus,eax
xor eax,eax
ret

上面是摘自于 EditWndClass 過程的程序片斷,它檢查用戶是否按下了 Tabs 鍵,若是就調用函數 GetKeyState 來檢查 SHIFT 鍵是否也被同時按下了。函數 GetKeyState 在寄存器 eax 中設立一個返回值,用于判斷某個特定的鍵是否被按下了,若按下了,則把 eax 的的最高位置1,否則把最高位清0。所以只要用 80000000h 來測試返回值就行了,若最高位是1則說明用戶按下了 SHIFT-Tabs,這需要單獨處理;否則說明只按下 Tabs 鍵,調用函數 GetWindow 來獲得 hEdit 所指向窗口的下一個窗口句柄,若該函數返回 NULL ,說明這是當前窗口是窗口鏈中最后一個窗口了,應該通過以參數 GW_HWNDFIRST 調用函數 GetWindow 來卷回到窗口鏈中的第一個窗口控件。SHIFT-Tabs 的處理過程和這正好相反。

posted on 2007-07-18 00:08 旅途 閱讀(288) 評論(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>
            免费看精品久久片| 一区二区三区欧美在线| 国产亚洲成av人片在线观看桃| 欧美激情一区二区在线 | 欧美综合国产| 亚洲精品久久久久久久久久久| 国产婷婷97碰碰久久人人蜜臀| 欧美高清在线| 欧美日韩精品欧美日韩精品一| 久久久亚洲综合| 久久久久九九九九| 欧美a级一区| 久久综合福利| 久久久九九九九| av72成人在线| 欧美三级免费| 欧美高清在线一区| 欧美成人精品高清在线播放| 性欧美xxxx大乳国产app| 亚洲视频二区| 中文亚洲视频在线| 一级成人国产| 午夜精品久久久久久久久久久久久| 亚洲茄子视频| 欧美国产在线视频| 久久综合狠狠综合久久综合88 | 欧美日韩国语| 欧美精品激情在线| 欧美韩国日本一区| 欧美日韩中文在线观看| 欧美网站在线| 国产欧美日本一区视频| 国产精品婷婷| 黄色在线一区| 一区二区激情| 日韩午夜激情电影| 午夜在线一区二区| 老牛嫩草一区二区三区日本| 欧美黄污视频| 亚洲国产乱码最新视频| 亚洲精品一区二区三区蜜桃久| 亚洲九九精品| 午夜视频在线观看一区二区三区 | 一本色道久久综合亚洲精品不 | 亚洲人成人99网站| 亚洲男女毛片无遮挡| 久久在线视频| 亚洲婷婷综合色高清在线| 久久er99精品| 日韩亚洲视频| 欧美激情免费观看| 极品少妇一区二区三区| 亚洲欧美影院| 女女同性精品视频| 久久久久久久久久看片| 国产精品日韩在线播放| 中日韩在线视频| 亚洲精品资源| 亚洲精品欧美激情| 欧美日韩福利在线观看| 在线中文字幕不卡| 91久久精品www人人做人人爽| 欧美资源在线观看| 韩日成人在线| 午夜精品久久久久久久久| 亚洲视频视频在线| 国产欧美日韩精品a在线观看| 亚洲欧美日韩系列| 久久大香伊蕉在人线观看热2| 亚洲大片一区二区三区| 国产人成一区二区三区影院| 国产一区二区三区黄| 亚洲影音先锋| 久久久久久久久一区二区| 欧美一区二区三区免费大片| 国产精品美女久久久| 久久久噜噜噜| 久久成人国产| 在线亚洲精品| 久久久久五月天| 亚洲欧美日韩国产综合在线 | 亚洲一区自拍| 国产精品视频成人| 久久人人爽人人爽爽久久| 六月天综合网| 性伦欧美刺激片在线观看| 久久精品论坛| 亚洲影视综合| 久久综合伊人77777| 欧美亚洲午夜视频在线观看| 久久久久**毛片大全| 午夜精品久久久久久久99黑人| 久久精品亚洲精品| 一区二区三区毛片| 欧美有码在线观看视频| 久久超碰97人人做人人爱| 欧美性大战久久久久久久| 欧美激情一区二区久久久| 在线不卡亚洲| 久久久水蜜桃| 亚洲国产高清在线| 亚洲视频碰碰| 久久aⅴ乱码一区二区三区| 亚洲美女福利视频网站| 亚洲精品视频一区| 欧美日韩一二区| 午夜精品美女久久久久av福利| 亚洲一区在线免费观看| 亚洲国产成人精品久久| 亚洲精品在线电影| 欧美理论电影在线观看| 99精品热视频只有精品10| 亚洲自拍偷拍福利| 国产综合网站| 欧美另类高清视频在线| 亚洲免费视频一区二区| 久久婷婷影院| 亚洲一区欧美一区| 亚洲第一福利视频| 国产日韩欧美在线播放| 久久这里有精品视频| 亚洲深爱激情| 亚洲国产视频一区| 久久久久久久综合日本| 在线亚洲欧美视频| 亚洲最新在线视频| 原创国产精品91| 国产精品色婷婷久久58| 亚洲字幕一区二区| 一二三四社区欧美黄| 久久国产精品第一页 | 亚洲精品久久久久久久久久久| 一本到高清视频免费精品| 亚洲夜间福利| 欧美/亚洲一区| 亚洲精品视频在线播放| 亚洲男人影院| 欧美激情第一页xxx| 国产精自产拍久久久久久| 在线观看视频日韩| 午夜精品亚洲一区二区三区嫩草| 欧美一区二区三区视频在线观看| 久久天堂国产精品| 在线亚洲高清视频| 老司机67194精品线观看| 国产精品美女久久福利网站| 91久久精品一区| 久久久久久久久综合| 亚洲精品日韩在线| 美玉足脚交一区二区三区图片| 正在播放亚洲一区| 欧美美女bb生活片| 亚洲电影免费在线观看| 久久国产黑丝| 午夜精品福利在线观看| 国产精品福利在线观看| 在线视频一区观看| 99v久久综合狠狠综合久久| 欧美另类99xxxxx| 一区二区三区免费网站| 亚洲激情第一区| 欧美好吊妞视频| 亚洲狼人综合| 亚洲精品视频免费观看| 欧美日韩国产免费观看| 在线亚洲免费| 午夜精品福利一区二区三区av | 一区二区三区四区五区视频| 91久久在线观看| 欧美视频一区| 蜜臀99久久精品久久久久久软件| 久久亚洲一区二区三区四区| 亚洲人永久免费| 一区二区三欧美| 伊人精品成人久久综合软件| 亚洲第一成人在线| 欧美日韩亚洲一区二区| 久久精品成人一区二区三区 | 久久精品国产v日韩v亚洲 | 欧美精品久久一区| 久久成人18免费网站| 欧美激情aaaa| 久久久久久久久久久久久女国产乱 | 欧美视频国产精品| 麻豆成人91精品二区三区| 欧美日韩免费精品| 欧美激情中文字幕一区二区 | 久久久综合香蕉尹人综合网| 日韩午夜三级在线| 久久欧美肥婆一二区| 久久精品一区二区三区四区| 欧美日韩一区二区视频在线| 欧美黄色小视频| 亚洲国产精品久久91精品| 欧美综合77777色婷婷| 欧美亚洲专区| 国产美女精品视频免费观看| 99精品热视频只有精品10| 亚洲网站在线观看| 国产精品美女久久久久久2018|