?? tut21.html
字號:
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.if eax==NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke MessageBox,hWnd,addr CreateProcessError,addr
AppName,MB_ICONERROR+MB_OK</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.else</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke CloseHandle,hWrite</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.while TRUE</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke RtlZeroMemory,addr buffer,1024</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke ReadFile,hRead,addr buffer,1023,addr bytesRead,NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.if eax==NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.break</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke SendMessage,hwndEdit,EM_SETSEL,-1,0</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke SendMessage,hwndEdit,EM_REPLACESEL,FALSE,addr buffer</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endw</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke CloseHandle,hRead</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.elseif uMsg==WM_DESTROY</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke PostQuitMessage,NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.else</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
xor eax,eax</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
ret</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>WndProc endp</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>end start</font></font></font></b></blockquote>
<h3>
<font face="Arial"><font size=+0>Analysis:</font></font></h3>
<font face="Arial"><font size=-1>The example will call ml.exe to assemble
a file named test.asm and redirect the output of ml.exe to the edit control
in its client area.</font></font>
<br><font face="Arial"><font size=-1>When the program is loaded, it registers
the window class and creates the main window as usual. The first thing
it does during main window creation is to create an edit control which
will be used to display the output of ml.exe.</font></font>
<br><font face="Arial"><font size=-1>Now the interesting part, we will
change the text and background color of the edit control. When an edit
control is going to paint its client area, it sends WM_CTLCOLOREDIT message
to its parent.</font></font>
<br><font face="Arial"><font size=-1>wParam contains the handle to the
device context that the edit control will use to write its own client area.
We can use this opportunity to modify the characteristics of the HDC.</font></font>
<blockquote><b><font face="Arial"><font size=-1> <font color="#999900">.elseif
uMsg==WM_CTLCOLOREDIT</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke SetTextColor,wParam,Yellow</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke SetTextColor,wParam,Black</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke GetStockObject,BLACK_BRUSH</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
ret</font></font></font></b></blockquote>
<font face="Arial"><font size=-1>SetTextColor changes the text color to
yellow. SetTextColor changes the background color of the text to black.
And lastly, we obtain the handle to the black brush which we return to
Windows. With WM_CTLCOLOREDIT message, you must return a handle to a brush
which Windows will use to paint the background of the edit control. In
our example, I want the background to be black so I return the handle to
the black brush to Windows.</font></font>
<br><font face="Arial"><font size=-1>Now when the user selects <font color="#FFFF00">Assemble</font>
menuitem, it creates an anonymous pipe.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
.if ax==IDM_ASSEMBLE</font></font></font></b>
<br>
<b><font face="Arial"><font color="#999900"><font size=-1>
mov sat.nLength,sizeof SECURITY_ATTRIBUTES</font></font></font></b> <br>
<b><font face="Arial"><font color="#999900"><font size=-1>
mov sat.lpSecurityDescriptor,NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
mov sat.bInheritHandle,TRUE</font></font></font></b>
<p><font face="Arial"><font size=-1>Prior to calling CreatePipe, we must
fill the SECURITY_ATTRIBUTES structure first. Note that we can use NULL
in lpSecurityDescriptor member if we don't care about security. And the
bInheritHandle member must be TRUE so that the pipe handles are inheritable
to the child process.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
invoke CreatePipe,addr hRead,addr hWrite,addr sat,NULL</font></font></font></b>
<p><font face="Arial"><font size=-1> After that, we call CreatePipe
which, if successful, will fill hRead and hWrite variables with the handles
to read and write ends of the pipe respectively.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
mov startupinfo.cb,sizeof STARTUPINFO</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke GetStartupInfo,addr startupinfo</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
mov eax, hWrite</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
mov startupinfo.hStdOutput,eax</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
mov startupinfo.hStdError,eax</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
mov startupinfo.dwFlags, STARTF_USESHOWWINDOW+ STARTF_USESTDHANDLES</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
mov startupinfo.wShowWindow,SW_HIDE</font></font></font></b>
<p><font face="Arial"><font size=-1>Next we must fill the STARTUPINFO structure.
We call GetStartupInfo to fill the STARTUPINFO structure with default values
of the parent process. You MUST fill the STARTUPINFO structure with this
call if you intend your code to work under both win9x and NT. After GetStartupInfo
call returns, you can modify the members that are important. We copy the
handle to the write end of the pipe into hStdOutput and hStdError since
we want the child process to use it instead of the default standard output/error
handles. We also want to hide the console window of the child process,
so we put SW_HIDE value into wShowWidow member. And lastly, we must indicate
that hStdOutput, hStdError and wShowWindow members are valid and must be
used by specifying the flags STARTF_USESHOWWINDOW and STARTF_USESTDHANDLES
in dwFlags member.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
invoke CreateProcess, NULL, addr CommandLine, NULL, NULL, TRUE, NULL, NULL,
NULL, addr startupinfo, addr pinfo</font></font></font></b>
<p><font face="Arial"><font size=-1>We now create the child process with
CreateProcess call. Note that the bInheritHandles parameter must be set
to TRUE for the pipe handle to work.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
invoke CloseHandle,hWrite</font></font></font></b>
<p><font face="Arial"><font size=-1>After we successfully create the child
process, we must close the write end of the pipe. Remember that we passed
the write handle to the child process via STARTUPINFO structure. If we
don't close the write handle from our end, there will be two write ends.
And that the pipe will not work. We must close the write handle after CreateProcess
but before we read data from the read end of the pipe.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
.while TRUE</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke RtlZeroMemory,addr buffer,1024</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke ReadFile,hRead,addr buffer,1023,addr bytesRead,NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.if eax==NULL</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.break</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endif</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke SendMessage,hwndEdit,EM_SETSEL,-1,0</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
invoke SendMessage,hwndEdit,EM_REPLACESEL,FALSE,addr buffer</font></font></font></b>
<br><b><font face="Arial"><font color="#999900"><font size=-1>
.endw</font></font></font></b>
<p><font face="Arial"><font size=-1>Now we are ready to read the data from
the standard output of the child process. We will stay in an infinite loop
until there are no more data left to read from the pipe. We call RtlZeroMemory
to fill the buffer with zeroes then call ReadFile, passing the read handle
of the pipe in place of a file handle. Note that we only read a maximum
of 1023 bytes since we need the data to be an ASCIIZ string which we can
pass on to the edit control.</font></font>
<br><font face="Arial"><font size=-1>When ReadFile returns with the data
in the buffer, we fill the data into the edit control. However, there is
a slight problem here. If we use SetWindowText to put the data into the
edit control, the new data will overwrite existing data! We want the data
to append to the end of the existing data.</font></font>
<br><font face="Arial"><font size=-1>To achieve that goal, we first move
the caret to the end of the text in the edit control by sending EM_SETSEL
message with wParam==-1. Next, we append the data at that point with EM_REPLACESEL
message.</font></font>
<p><b><font face="Arial"><font color="#999900"><font size=-1>
invoke CloseHandle,hRead</font></font></font></b>
<p><font face="Arial"><font size=-1>When ReadFile returns NULL, we break
out of the loop and close the read handle.</font></font>
<br>
<hr WIDTH="100%">
<center><b><a href="http://win32asm.cjb.net" style="text-decoration:none">Iczelion's
Win32 Assembly Homepage</a></b></center>
</body>
</html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -