WIN32汇编语言教程:第09章 通用控件 · 9.6 控件的超类化(2)
.386 .model flat, stdcall option casemap :none ;#################################################################### ; Include 文件定义 ;#################################################################### include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;#################################################################### ; Equ 等值定义 ;#################################################################### ICO_MAIN equ 1000 DLG_MAIN equ 1000 ;#################################################################### ; 数据段 ;#################################################################### .data? hInstance dd ? hWinMain dd ? lpOldProcEdit dd ? .const szAllowedChar db '0123456789ABCDEFabcdef',08h szEditClass db 'Edit',0 szClass db 'HexEdit',0 ;#################################################################### ; 代码段 ;#################################################################### .code ;#################################################################### ; HexEdit控件的新窗口过程 ;#################################################################### _ProcEdit proc uses ebx edi esi hWnd,uMsg,wParam,lParam mov eax,uMsg .if uMsg == WM_CHAR mov eax,wParam mov edi,offset szAllowedChar mov ecx,sizeof szAllowedChar repnz scasb .if ZERO? .if al > '9' and al,not 20h .endif invoke CallWindowProc,lpOldProcEdit,\ hWnd,uMsg,eax,lParam ret .endif .else invoke CallWindowProc,lpOldProcEdit,\ hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret _ProcEdit endp ;#################################################################### ; 基于Edit类建立一个新的类:HexEdit ;#################################################################### _SuperClass proc local @stWC:WNDCLASSEX mov @stWC.cbSize,sizeof @stWC invoke GetClassInfoEx,NULL,addr szEditClass,addr @stWC push @stWC.lpfnWndProc pop lpOldProcEdit mov @stWC.lpfnWndProc,offset _ProcEdit push hInstance pop @stWC.hInstance mov @stWC.lpszClassName,offset szClass invoke RegisterClassEx,addr @stWC ret _SuperClass endp ;#################################################################### _ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam mov eax,wMsg ;******************************************************************** .if eax == WM_CLOSE invoke EndDialog,hWnd,NULL ;******************************************************************** .else mov eax,FALSE ret .endif mov eax,TRUE ret _ProcDlgMain endp ;#################################################################### start: invoke GetModuleHandle,NULL mov hInstance,eax invoke _SuperClass invoke DialogBoxParam,hInstance,DLG_MAIN,\ NULL,offset _ProcDlgMain,NULL invoke ExitProcess,NULL ;#################################################################### end start
由于在对话框初始化的时候,对话框管理器就要根据对话框资源的内容创建每个子窗口控件,所以在调用DialogBoxParam函数显示对话框之前,“HexEdit”类就必须存在,否则初始化工作会失败。因此,程序在DialogBoxParam函数之前调用_SuperClass子程序进行超类化的工作。
在_SuperClass子程序中,程序通过GetClassInfoEx函数获取Edit控件的类结构,然后将结构中的窗口过程指到自己的_ProcEdit子程序中,接下来将hInstance字段设置为自己的实例句柄,并将类的名称改为“HexEdit”,最后用RegisterClassEx函数注册一个新的“HexEdit”类:
.const szEditClass db 'Edit',0 szClass db 'HexEdit',0 .code ... mov @stWC.cbSize,sizeof @stWC ;@stWC是一个WNDCLASSEX结构 invoke GetClassInfoEx,NULL,addr szEditClass,addr @stWC push @stWC.lpfnWndProc pop lpOldProcEdit mov @stWC.lpfnWndProc,offset _ProcEdit push hInstance pop @stWC.hInstance mov @stWC.lpszClassName,offset szClass invoke RegisterClassEx,addr @stWC
新的窗口过程和子类化窗口中的例子是一样的,在这里就不进行分析了,程序的结果就是:用HexEdit类建立的所有窗口的功能和子类化窗口例子中IDC_HEX编辑框的功能是一样的。
本程序演示的是派生类在对话框中的使用情况,在这里基于派生类创建的窗口是由对话框管理器自动调用CreateWindowEx函数创建的,如果将派生类使用在普通窗口中的话,可以通过指定派生类的名称,自己使用CreateWindowEx函数来创建。
上页:第09章 通用控件 · 9.6 控件的超类化(1) 下页:第10章 内存管理和文件操作 · 10.1 内存管理(1)
第09章 通用控件
版权所有 © 云南伯恩科技 证书:粤ICP备09170368号