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

📄 tut22.html

📁 WINDOWS程序员使用指南--汇编基础
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;
.else</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke CallWindowProc,OldWndProc,hEdit,uMsg,wParam,lParam</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;
.endif</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;
xor eax,eax</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>&nbsp;&nbsp;&nbsp;
ret</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>EditWndProc
endp</font></font></font></b>
<br><b><font face="Arial,Helvetica"><font color="#FF6600"><font size=-1>end
start</font></font></font></b>
<br>&nbsp;
<h3>
<font face="Arial,Helvetica"><font color="#3366FF">Analysis:</font></font></h3>
<font face="Arial,Helvetica"><font size=-1>The program will create a simple
window with 6 "modified" edit controls in its client area. The edit controls
will accept only hex digits. Actually, I modified the subclassing example
to do superclassing. The program starts normally and the interesting part
is when the main window is created:</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp; .if
uMsg==WM_CREATE</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov wc.cbSize,sizeof WNDCLASSEX</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetClassInfoEx,NULL,addr EditClass,addr wc</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>We must first fill the WNDCLASSEX
structure with the data from the class which we want to superclass, in
this case, it's EDIT class. Remember that you must set the cbSize member
of the WNDCLASSEX structure before you call GetClassInfoEx else the WNDCLASSEX
structure will not be filled properly. After GetClassInfoEx returns, wc
is filled with all information we need to create a new window class.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push wc.lpfnWndProc</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop OldWndProc</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov wc.lpfnWndProc, OFFSET EditWndProc</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
push hInstance</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
pop wc.hInstance</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov wc.lpszClassName,OFFSET OurClass</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>Now we must modify some members
of wc. The first one is the pointer to the window procedure. Since we need
to chain our own window procedure with the original one, we have to save
it into a variable so we can call it with CallWindowProc. This technique
is identical to subclassing except that you modify the WNDCLASSEX structure
directly without having to call SetWindowLong. The next two members must
be changed else you will not be able to register your new window class,
hInstance and lpsClassName. You must replace original hInstance value with
hInstance of your own program. And you must choose a new name for the new
class.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke RegisterClassEx, addr wc</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>When all is ready, register
the new class. You will get a new class with some characteristics of the
old class.</font></font>
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor ebx,ebx</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov edi,20</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.while ebx&lt;6</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR OurClass,NULL,\</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
WS_CHILD+WS_VISIBLE+WS_BORDER,20,\</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
edi,300,25,hWnd,ebx,\</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
hInstance,NULL</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
mov dword ptr [hwndEdit+4*ebx],eax</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
add edi,25</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
inc ebx</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endw</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetFocus,hwndEdit</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>Now that we registered the
class, we can create windows based on it. In the above snippet, I use ebx
as the counter of the number of windows created. edi is used as the y coordinate
of the left upper corner of the window. When a window is created, its handle
is stored in the array of dwords. When all windows are created, set input
focus to the first window.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>At this point, you got 6
edit controls which accept only hex digits. The substituted window proc
handles the filter. Actually, it's identical to the window proc in subclassing
example. As you can see, you don't have to do extra work of subclassing
them.</font></font>
<p><font face="Arial,Helvetica"><font size=-1>I throw in a code snippet
to handle control navigation with tabs to make this example more juicy.
Normally, if you put controls on a dialog box, the dialog box manager handles
the navigation keys for you so you can tab to go to the next control or
shift-tab to go back to the previous control. Alas, such feature is not
available if you put your controls on a simple window. You have to subclass
them so you can handle the Tab keys yourself. In our example, we need not
subclass the controls one by one because we already superclassed them,
so we can provide a "central control navigation manager" for them.</font></font>
<br>&nbsp;
<p><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.elseif al==VK_TAB</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetKeyState,VK_SHIFT</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
test eax,80000000</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.if ZERO?</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetWindow,hEdit,GW_HWNDNEXT</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.if eax==NULL</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetWindow,hEdit,GW_HWNDFIRST</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.else</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetWindow,hEdit,GW_HWNDPREV</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.if eax==NULL</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke GetWindow,hEdit,GW_HWNDLAST</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
.endif</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke SetFocus,eax</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
xor eax,eax</font></font></b>
<br><b><font face="Arial,Helvetica"><font size=-1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
ret</font></font></b>
<p><font face="Arial,Helvetica"><font size=-1>The above code snippet is
from EditWndClass procedure. It checks if the user press Tab key, if so,
it call GetKeyState to check if&nbsp; the SHIFT key is also pressed. GetKeyState
returns a value in eax that determines whether the specified key is pressed
or not. If the key is pressed, the high bit of eax is set. If not, the
high bit is clear. So we test the return value against 80000000h. If the
high bit is set, it means the user pressed shift+tab which we must handle
separately.</font></font>
<br><font face="Arial,Helvetica"><font size=-1>If the user press Tab key
alone, we call GetWindow to retrieve the handle of the next control. We
use GW_HWNDNEXT flag to tell GetWindow to obtain the handle to the window
that is next in line to the current hEdit. If this function returns NULL,
we interpret it as no more handle to obtain so the current hEdit is the
last control in the line. We will "wrap around" to the first control by
calling GetWindow with GW_HWNDFIRST flag. Similar to the Tab case, shift-tab
just works in reverse.</font></font>
<br>
<hr WIDTH="100%">
<center><b>[<a href="http://win32asm.cjb.net">Iczelion's Win32 Assembly
Homepage</a>]</b></center>

</body>
</html>

⌨️ 快捷键说明

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