三级PC辅导:超类化

文章作者 100test 发表时间 2007:09:08 13:09:24
来源 100Test.Com百考试题网


  在这一讲我们将学习什么是超类化以及它有什么作用;同时你还会学到怎样在自己的窗口中用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


相关文章


Win32调试API第二部分
Win32调试API第三部分
Win32调试API第一部分
系统托盘中的快捷图标
三级PC辅导:超类化
PC辅导:WINDOWS钩子函数
PC技术辅导:窗口子类化
PC技术辅导:列表视图控件
HELLOWORLD进阶汇编程序系列
澳大利亚华人论坛
考好网
日本华人论坛
华人移民留学论坛
英国华人论坛