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号