上一篇 | 下一篇

超类化

发布: 2008-6-26 22:54 | 作者: admin | 来源: | 查看: 0次

超类化:

  在这一讲我们将学习什么是超类化以及它有什么作用;同时你还会学到怎样在自己的窗口中用Tab键在控件中切换这一技巧。

理论:

在你的程序生涯中你肯定遇到过这样的情况,你需要一系列的控件,但它们之间却只有一点点的不同。例如,你可能需要10个只接受数字的 Edit 控件,当然你可以通过多种方法来达到这个目的。

创建自己的类并用它实例化为那些控件

创建那些 Edit 控件并把它们全部子类化

超类化Edit 控件

第一种方法太乏味了,因为你必须自己实现Edit 控件的每个功能,但这项工作不是轻松就能完成的。第二种方法好于第一种,但仍然要做许多工作,子类化几个Edit 控件还可以接受,但若要子类化十几二十个,这项工作简直就是一场恶梦。在这种情况下就应该使用超类化这个技巧,它是用于控制某一个特定窗口类的特殊方法。通过这种控制就可以修改窗口类的特性使之符合你的要求,然后再创建那一堆控件就可以了。

超类化有如下几个步骤:

通过调用 GetClassInfoEx 来获得想要进行超类化操作的窗口类的信息。函数GetClassInfoEx 需要一个指向 WNDCLASSEX 结构的指针,用于当成功返回时填入窗口类的信息。

按需要修改 WNDCLASSEX 结构的成员,其中有两个成员必须修改:

hInstance 存放程序的实例句柄

lpszClassName 指向一个新类名的指针

不必修改成员 lpfnWndProc,但大多数情况下还是需要的。但要记住如果要使用函数 CallWindowProc 调用老窗口的过程,那就必须保存成员 lpfnWndProc 的原值。

注册修改完的 WNDCLASSEX 结构,得到一个具有旧窗口类某些特性的新窗口类。

用新窗口类创建窗口

如果要创建具有相同特性的多个控件,超类化就比子类化要好。

举例:

.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

字号: | 推荐给好友

31/3123>

评分:0

我来说两句