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

📄 021.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 2 页
字号:
    LOCAL bytesRead:DWORD 
    LOCAL hdc:DWORD 
    LOCAL sat:SECURITY_ATTRIBUTES 
    .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 
分析:

这个例子调用 ml.exe 来汇编一个名为 test.asm 的程序,并且重定向 ml.exe 的输出到客户区的 Edit 控件中。当程序被加载时,象往常一样要注册窗口类和创建主窗口。在主窗口被创建的过程中要做的第一件事就是创建用于显示程序 ml.exe 输出的 Edit 控件。

现在有趣的事来了,我们将改变此 Edit 控件的文本颜色和背景色。当 Edit 控件将要重画客户区时,它会给父窗口发送 WM_CTLCOLOREDIT 消息。参数 wParam 包含了用于画控件自己的客户区设备描述符的句柄 (HDC) 。我们可以利用这种机制来修改 HDC 的特性。 


    .elseif uMsg==WM_CTLCOLOREDIT 
        invoke SetTextColor,wParam,Yellow 
        invoke SetTextColor,wParam,Black 
        invoke GetStockObject,BLACK_BRUSH 
        ret
SetTextColor 把文本颜色变为黄色,背景颜色变为黑色。最后我们返回一个通过调用GetStockObject 而得到黑色刷子的句柄。处理WM_CTLCOLOREDIT 必须返回一个刷子的句柄,因为 Windows 将要使用这个刷子来重画 Edit 控件的背景。在这个例子中,我希望背景是黑色,所以返回了一个黑色刷子的句柄。 

现在当用户选择 Assemble 子菜单时,就会创建一个匿名管道。

            .if ax==IDM_ASSEMBLE 
                mov sat.niLength,sizeof SECURITY_ATTRIBUTES 
                mov sat.lpSecurityDescriptor,NULL 
                mov sat.bInheritHandle,TRUE  

在调用CreatePipe 之前,必须要填写SECURITY_ATTRIBUTES 结构。如果我们不关心安全性的话,可以在lpSecurityDescriptor 成员中填入 NULL 。bInheritHandle 则必须为 TRUE ,这样管道的句柄才可以被子进程继承。

invoke CreatePipe,addr hRead,addr hWrite,addr sat,NULL 

在此之后,我们调用CreatePipe 来创建管道,如果成功,那么变量hRead 和 hWrite 将分别被填入相应的管道的读出端和写入端的句柄。 


                    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 

下一步就是填写STARTUPINFO 结构了。调用 GetStartupinfo 用父进程的缺省值来填写STARTUPINFO 结构。如果要使程序同时工作在 Windows9x 和 Windows NT 下,就必须调用GetStartupInfo 来填写STARTUPINFO 结构。调用返回后,就可以修改重要的成员了。因为我们要子进程输出到父进程而不是缺省的标准输出和标准错误,所以我们把hStdOutput 和 hStdError 都赋成管道写端的句柄。为了隐藏子进程的主窗口,必须把成员变量wShowWidow 赋值为SW_HIDE 。最后通过把成员 dwFlags 赋值为STARTF_USESHOWWINDOW 和 STARTF_USESTDHANDLES 来指明成员hStdOutput, hStdError 和 wShowWindow 是有效的。

invoke CreateProcess, NULL, addr CommandLine, NULL, NULL, TRUE, NULL, NULL, NULL, addr startupinfo, addr pinfo 

现在调用CreateProcess 来创建子进程。注意为使管道工作,参数bInheritHandles 必须设置为TRUE。 invoke CloseHandle,hWrite 成功创建子进程之后,在父进程中必须关闭管道的写端。我们已经把写端的句柄通过结构STARTUPINFO 传给了子进程。如果不关闭,那么管道就有两个写入端,而这样的管道是不会工作的。所以必须在创建子进程后但在读数据前关闭这个句柄。 


                        .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 


现在已经准备好从子进程的标准输出读数据了。直到再也没有数据了,即 ReadFile 返回为 NULL时才会退出循环,否则一直会等待数据。我们调用ReadFile 之前先调用RtlZeroMemory 来清空内存,并且用管道的读句柄代替文件句柄。注意读数据的最大长度为 1023 ( sizeof(buffer)-1 ),因为我们需要把接受的字符变为一个 Edit 控件可以处理的 ASCII 串。当ReadFile 返回时,就把此数据传给 Edit 控件。然而这有一个小小的问题,如果使用SetWindowText API 往 Edit 控件中写数据,新数据就会覆盖已存在的旧数据,而我们想把新数据添加在已有数据的后面。为达此目的,首先通过发送一个 wParam 为-1的 EM_SETSEL 消息,把 Edit 控件的输入焦点移动到文本的末端;然后发送一个 EM_REPLACESEL 消息把数据添加后面。

invoke CloseHandle,hRead

当ReadFile 返回为NULL时,就跳出循环并关闭管道的读句柄。 


--------------------------------------------------------------------------------




--------------------------------------------------------------------------------

⌨️ 快捷键说明

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