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

📄 lion-tut-c21.htm

📁 内有一些代码
💻 HTM
📖 第 1 页 / 共 2 页
字号:
    .if uMsg==WM_CREATE 
        invoke CreateWindowEx,NULL,addr EditClass, NULL, WS_CHILD+ WS_VISIBLE+ ES_MULTILINE+ ES_AUTOHSCROLL+ ES_AUTOVSCROLL, 0, 0, 0, 0, hWnd, NULL, hInstance, NULL 
        mov hwndEdit,eax 
    .elseif uMsg==WM_CTLCOLOREDIT 
        invoke SetTextColor,wParam,Yellow 
        invoke SetBkColor,wParam,Black 
       invoke GetStockObject,BLACK_BRUSH 
        ret 
    .elseif uMsg==WM_SIZE 
        mov edx,lParam 
        mov ecx,edx 
        shr ecx,16 
        and edx,0ffffh 
        invoke MoveWindow,hwndEdit,0,0,edx,ecx,TRUE 
    .elseif uMsg==WM_COMMAND 
       .if lParam==0 
            mov eax,wParam 
            .if ax==IDM_ASSEMBLE 
                mov sat.niLength,sizeof SECURITY_ATTRIBUTES 
                mov sat.lpSecurityDescriptor,NULL 
                mov sat.bInheritHandle,TRUE 
                invoke CreatePipe,addr hRead,addr hWrite,addr sat,NULL 
                .if eax==NULL 
                    invoke MessageBox, hWnd, addr CreatePipeError, addr AppName, MB_ICONERROR+ MB_OK 
                .else 
                    mov startupinfo.cb,sizeof STARTUPINFO 
                    invoke GetStartupInfo,addr startupinfo 
                    mov eax, hWrite 
                    mov startupinfo.hStdOutput,eax 
                    mov startupinfo.hStdError,eax 
                    mov startupinfo.dwFlags, STARTF_USESHOWWINDOW+ STARTF_USESTDHANDLES 
                    mov startupinfo.wShowWindow,SW_HIDE 
                    invoke CreateProcess, NULL, addr CommandLine, NULL, NULL, TRUE, NULL, NULL, NULL, addr startupinfo, addr pinfo 
                    .if eax==NULL 
                        invoke MessageBox,hWnd,addr CreateProcessError,addr         AppName,MB_ICONERROR+MB_OK 
                    .else 
                        invoke CloseHandle,hWrite 
                        .while TRUE 
                            invoke RtlZeroMemory,addr buffer,1024 
                            invoke ReadFile,hRead,addr buffer,1023,addr bytesRead,NULL 
                            .if eax==NULL 
                                .break 
                            .endif 
                            invoke SendMessage,hwndEdit,EM_SETSEL,-1,0 
                            invoke SendMessage,hwndEdit,EM_REPLACESEL,FALSE,addr buffer 
                        .endw 
                    .endif 
                    invoke CloseHandle,hRead 
                .endif 
            .endif 
        .endif 
    .elseif uMsg==WM_DESTROY 
        invoke PostQuitMessage,NULL 
    .else 
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret 
    .endif 
    xor eax,eax 
    ret 
WndProc endp 
end start </font></pre>
<p><font color="#FF0000" face="宋体">分析:</font></p>
<p><font face="宋体">这个例子调用 ml.exe 来汇编一个名为 test.asm 的程序,并且重定向 ml.exe 的输出到客户区的 Edit 
  控件中。当程序被加载时,象往常一样要注册窗口类和创建主窗口。在主窗口被创建的过程中要做的第一件事就是创建用于显示程序 ml.exe 输出的 Edit 控件。</font></p>
<p><font face="宋体">现在有趣的事来了,我们将改变此 Edit 控件的文本颜色和背景色。当 Edit 控件将要重画客户区时,它会给父窗口发送 
  WM_CTLCOLOREDIT 消息。参数 wParam 包含了用于画控件自己的客户区设备描述符的句柄 (HDC) 。我们可以利用这种机制来修改 HDC 
  的特性。 </font> </p>
<pre><font face="宋体">
<font color="#006666">    .elseif uMsg==WM_CTLCOLOREDIT 
        invoke SetTextColor,wParam,Yellow 
        invoke SetTextColor,wParam,Black 
        invoke GetStockObject,BLACK_BRUSH 
        ret</font></font></pre>
<p><font face="宋体">SetTextColor 把文本颜色变为黄色,背景颜色变为黑色。最后我们返回一个通过调用GetStockObject 
  而得到黑色刷子的句柄。处理WM_CTLCOLOREDIT 必须返回一个刷子的句柄,因为 Windows 将要使用这个刷子来重画 Edit 控件的背景。在这个例子中,我希望背景是黑色,所以返回了一个黑色刷子的句柄。 
  </font></p>
<p><font face="宋体">现在当用户选择 Assemble 子菜单时,就会创建一个匿名管道。</font></p>
<pre><font face="宋体" color="#006666">            .if ax==IDM_ASSEMBLE 
                mov sat.niLength,sizeof SECURITY_ATTRIBUTES 
                mov sat.lpSecurityDescriptor,NULL 
                mov sat.bInheritHandle,TRUE  
</font></pre>
<p><font face="宋体"> 在调用CreatePipe 之前,必须要填写SECURITY_ATTRIBUTES 结构。如果我们不关心安全性的话,可以在lpSecurityDescriptor 
  成员中填入 NULL 。bInheritHandle 则必须为 TRUE ,这样管道的句柄才可以被子进程继承。</font></p>
<p><font face="宋体"> <font color="#006666">invoke CreatePipe,addr hRead,addr hWrite,addr 
  sat,NULL </font></font></p>
<p><font face="宋体">在此之后,我们调用CreatePipe 来创建管道,如果成功,那么变量hRead 和 hWrite 将分别被填入相应的管道的读出端和写入端的句柄。 
  </font></p>
<pre><font face="宋体">
<font color="#006666">                    mov startupinfo.cb,sizeof STARTUPINFO 
                    invoke GetStartupInfo,addr startupinfo 
                    mov eax, hWrite 
                    mov startupinfo.hStdOutput,eax 
                    mov startupinfo.hStdError,eax 
                    mov startupinfo.dwFlags, STARTF_USESHOWWINDOW+ STARTF_USESTDHANDLES 
                    mov startupinfo.wShowWindow,SW_HIDE </font>
</font></pre>
<p><font face="宋体"> 下一步就是填写STARTUPINFO 结构了。调用 GetStartupinfo 用父进程的缺省值来填写STARTUPINFO 
  结构。如果要使程序同时工作在 Windows9x 和 Windows NT 下,就必须调用GetStartupInfo 来填写STARTUPINFO 结构。调用返回后,就可以修改重要的成员了。因为我们要子进程输出到父进程而不是缺省的标准输出和标准错误,所以我们把hStdOutput 
  和 hStdError 都赋成管道写端的句柄。为了隐藏子进程的主窗口,必须把成员变量wShowWidow 赋值为SW_HIDE 。最后通过把成员 dwFlags 
  赋值为STARTF_USESHOWWINDOW 和 STARTF_USESTDHANDLES 来指明成员hStdOutput, hStdError 和 
  wShowWindow 是有效的。</font></p>
<p><font face="宋体"> <font color="#006666">invoke CreateProcess, NULL, addr CommandLine, 
  NULL, NULL, TRUE, NULL, NULL, NULL, addr startupinfo, addr pinfo</font> </font></p>
<p><font face="宋体">现在调用CreateProcess 来创建子进程。注意为使管道工作,参数bInheritHandles 必须设置为TRUE。 
  invoke CloseHandle,hWrite 成功创建子进程之后,在父进程中必须关闭管道的写端。我们已经把写端的句柄通过结构STARTUPINFO 
  传给了子进程。如果不关闭,那么管道就有两个写入端,而这样的管道是不会工作的。所以必须在创建子进程后但在读数据前关闭这个句柄。 </font></p>
<pre><font face="宋体">
                        .while TRUE 
                            invoke RtlZeroMemory,addr buffer,1024 
                            invoke ReadFile,hRead,addr buffer,1023,addr bytesRead,NULL 
                            .if eax==NULL 
                                .break 
                            .endif 
                            invoke SendMessage,hwndEdit,EM_SETSEL,-1,0 
                            invoke SendMessage,hwndEdit,EM_REPLACESEL,FALSE,addr buffer 
                        .endw 

</font></pre>
<p><font face="宋体"> 现在已经准备好从子进程的标准输出读数据了。直到再也没有数据了,即 ReadFile 返回为 NULL时才会退出循环,否则一直会等待数据。我们调用ReadFile 
  之前先调用RtlZeroMemory 来清空内存,并且用管道的读句柄代替文件句柄。注意读数据的最大长度为 1023 ( sizeof(buffer)-1 
  ),因为我们需要把接受的字符变为一个 Edit 控件可以处理的 ASCII 串。当ReadFile 返回时,就把此数据传给 Edit 控件。然而这有一个小小的问题,如果使用SetWindowText 
  API 往 Edit 控件中写数据,新数据就会覆盖已存在的旧数据,而我们想把新数据添加在已有数据的后面。为达此目的,首先通过发送一个 wParam 为-1的 
  EM_SETSEL 消息,把 Edit 控件的输入焦点移动到文本的末端;然后发送一个 EM_REPLACESEL 消息把数据添加后面。</font></p>
<p><font face="宋体"> <font color="#006666">invoke CloseHandle,hRead</font></font></p>
<p><font face="宋体"> 当ReadFile 返回为NULL时,就跳出循环并关闭管道的读句柄。 </font></p>
<HR SIZE=1>
<DIV align=center> <font face="宋体"> 
  <SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
  <BR>
  </font></DIV>
<font face="宋体"><!-- 10:1 文本广告交换 --> </font> 
<DIV align=center> <font face="宋体"> 
  <SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
  <!-- 10:1 文本广告交换 --></font></DIV>
<HR SIZE=1>
<DIV align=center><font face="宋体">翻译:ZhangJun,校对:LuoYunBin's Win32 ASM Page, <A 
href="http://asm.yeah.net/">http://asm.yeah.net</A></font></DIV>
</BODY></HTML>

⌨️ 快捷键说明

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