⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lion-tutorial22.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<html>

<head>
<link rel="stylesheet" href="../../asm.css">

<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>Iczelion's win32 asm tutorial</title>
</head>

<body bgcolor="#FFFFFF" background="../../images/back01.jpg">
<p align="center">Tutorial 22: Superclassing</p>
<hr size="1">
<strong> </strong> In this tutorial, we will learn about superclassing, what it 
is and what it is for. You will also learn how to provide Tab key navigation to 
the controls in your own window. <br>
Download the example <a href="files/tut22.zip">here</a> 
<h3> Theory:</h3>
In your programming career, you will surely encounter a situation where you need 
several controls with *slightly* different behavior. For example, you may need 
10 edit controls which accept only number. There are several ways to achieve that 
goal: 
<ul>
  <li> Create your own class and instantiate the controls</li>
  <li> Create those edit control and then subclass all of them</li>
  <li> Superclass the edit control</li>
</ul>
The first method is too tedious. You have to implement every functionality of 
the edit control yourself. Hardly a task to be taken lightly. The second method 
is better than the first one but still too much work. It is ok if you subclass 
only a few controls but it's going to be a nightmare to subclass a dozen or so 
controls. Superclassing is the technique you should use for this occasion. <br>
Subclassing is the method you use to *take control* of a particular window class. 
By *taking control*, I mean you can modify the properties of the window class 
to suit your purpose then then create the bunch of controls. <br>
The steps in superclassing is outlined below: 
<ul>
  <li> call GetClassInfoEx to obtain the information about the window class you 
    want to superclass. GetClassInfoEx requires a pointer to a WNDCLASSEX structure 
    which will be filled with the information if the call returns successfully.</li>
  <li> Modify the WNDCLASSEX members that you want. However, there are two members 
    which you MUST modify:</li>
  <ul>
    <li> hInstance&nbsp; You must put the instance handle of your program into 
      this member.</li>
    <li> lpszClassName&nbsp; You must provide it with a pointer to a new class 
      name.</li>
    <br>
    You need not modify lpfnWndProc member but most of the time, you need to do 
    it. Just remember to save the original lpfnWndProc member if you want to call 
    it with CallWindowProc. 
  </ul>
  <li> Register the modifed WNDCLASSEX structure. You'll have a new window class 
    which has several characteristics of the old window class.</li>
  <li> Create windows from the new class</li>
</ul>
Superclassing is better than subclassing if you want to create many controls with 
the same characteristics. 
<h3> Example:</h3>
<b>.386</b> <br>
<b>.model flat,stdcall</b> <br>
<b>option casemap:none</b> <br>
<b>include \masm32\include\windows.inc</b> <br>
<b>include \masm32\include\user32.inc</b> <br>
<b>include \masm32\include\kernel32.inc</b> <br>
<b>includelib \masm32\lib\user32.lib</b> <br>
<b>includelib \masm32\lib\kernel32.lib</b> 
<p><b>WM_SUPERCLASS equ WM_USER+5</b> <br>
  <b>WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD</b> <br>
  <b>EditWndProc PROTO :DWORD,:DWORD,:DWORD,:DWORD</b> 
<p><b>.data</b> <br>
  <b>ClassName&nbsp; db "SuperclassWinClass",0</b> <br>
  <b>AppName&nbsp;&nbsp;&nbsp; db "Superclassing Demo",0</b> <br>
  <b>EditClass&nbsp; db "EDIT",0</b> <br>
  <b>OurClass db "SUPEREDITCLASS",0</b> <br>
  <b>Message&nbsp; db "You pressed the Enter key in the text box!",0</b> 
<p><b>.data?</b> <br>
  <b>hInstance dd ?</b> <br>
  <b>hwndEdit dd 6 dup(?)</b> <br>
  <b>OldWndProc dd ?</b> 
<p><b>.code</b> <br>
  <b>start:</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke GetModuleHandle, NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp; hInstance,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke WinMain, hInstance,NULL,NULL, SW_SHOWDEFAULT</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; invoke ExitProcess,eax</b> 
<p><b>WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL msg:MSG</b> <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL hwnd:HWND</b> 
<p><b>&nbsp;&nbsp;&nbsp; mov wc.cbSize,SIZEOF WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.style, CS_HREDRAW or CS_VREDRAW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.lpfnWndProc, OFFSET WndProc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.cbClsExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.cbWndExtra,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; push hInst</b> <br>
  <b>&nbsp;&nbsp;&nbsp; pop wc.hInstance</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.hbrBackground,COLOR_APPWORKSPACE</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.lpszMenuName,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.lpszClassName,OFFSET ClassName</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadIcon,NULL,IDI_APPLICATION</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.hIcon,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.hIconSm,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke LoadCursor,NULL,IDC_ARROW</b> <br>
  <b>&nbsp;&nbsp;&nbsp; mov wc.hCursor,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke RegisterClassEx, addr wc</b> <br>
  <b>&nbsp;&nbsp;&nbsp; invoke CreateWindowEx,WS_EX_CLIENTEDGE+WS_EX_CONTROLPARENT,ADDR 
  ClassName,ADDR AppName,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CW_USEDEFAULT,350,220,NULL,NULL,\</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hInst,NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; mov hwnd,eax</b> 
<p><b>&nbsp;&nbsp;&nbsp; .while TRUE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetMessage, ADDR msg,NULL,0,0</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .BREAK .IF (!eax)</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke TranslateMessage, ADDR 
  msg</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke DispatchMessage, ADDR msg</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .endw</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp; mov eax,msg.wParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>WinMain endp</b> 
<p><b>WndProc proc uses ebx edi hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; LOCAL wc:WNDCLASSEX</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .if uMsg==WM_CREATE</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov wc.cbSize,sizeof WNDCLASSEX</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke GetClassInfoEx,NULL,addr 
  EditClass,addr wc</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push wc.lpfnWndProc</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop OldWndProc</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov wc.lpfnWndProc, OFFSET EditWndProc</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push hInstance</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop wc.hInstance</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov wc.lpszClassName,OFFSET OurClass</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke RegisterClassEx, addr wc</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xor ebx,ebx</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov edi,20</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .while ebx&lt;6</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke 
  CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  WS_CHILD+WS_VISIBLE+WS_BORDER,20,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  edi,300,25,hWnd,ebx,\</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  hInstance,NULL</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov dword 
  ptr [hwndEdit+4*ebx],eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add edi,25</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc ebx</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .endw</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke SetFocus,hwndEdit</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .elseif uMsg==WM_DESTROY</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke PostQuitMessage,NULL</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp; .else</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; invoke DefWindowProc,hWnd,uMsg,wParam,lParam</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .endif</b> <br>
  <b>&nbsp;&nbsp;&nbsp; xor eax,eax</b> <br>
  <b>&nbsp;&nbsp;&nbsp; ret</b> <br>
  <b>WndProc endp</b> 
<p><b>EditWndProc PROC hEdit:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD</b> <br>
  <b>&nbsp;&nbsp;&nbsp; .if uMsg==WM_CHAR</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov eax,wParam</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if (al>="0" &amp;&amp; al&lt;="9") 
  || (al>="A" &amp;&amp; al&lt;="F") || (al>="a" &amp;&amp; al&lt;="f") || al==VK_BACK</b> 
  <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .if al>="a" 
  &amp;&amp; al&lt;="f"</b> <br>
  <b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  sub al,20h</b> <br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -