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号