WIN32汇编语言教程:第04章 第一个窗口程序 · 4.1 开始了解窗口(2)
先通过一个简单的例子来说明两种程序设计方式的不同,以DOS下的文件比较命令comp为例,程序运行时先提示输入第一个文件名,然后是输入第二个文件名,程序比较后退出,同时把结果输出在屏幕上。假如有一个窗口版的comp程序,那么运行时会在屏幕上出现一个对话框,上面有两个文本框用来输入两个文件名,还会有个“比较”按钮,按下后开始比较文件,用户可以随时按下“关闭”按钮来退出程序。
两种程序的运行会有相当大的不同,如图4.2所示,DOS程序必须按照顺序运行,当运行到输入第二个文件名时,用户不可能回到第一步修改第一个文件名,这时候用户也不能退出(除非用户强制用Ctrl+C键,但这不是程序的本意);而在窗口程序中用户可以随意选择先输入哪个文件名,同时也可以对窗口进行各种操作,当用户做任何一个操作的时候,相当于发出了一个消息,这些消息没有任何顺序关系,程序中必须随时准备处理不同的消息。
图4.2 不同的程序结构模式
这就决定了窗口程序必定在结构上和DOS程序有很大的不同,窗口程序实现大部分功能的代码应该呆在同一个模块——图中的“消息处理”模块中,这个模块可以随时应付所有类型的消息,只有这样才能随时响应用户的各种操作。
下面先来看一个地地道道的Win32汇编窗口程序。
2. FirstWindow源代码
读者可以在所带光盘的Chapter04\FirstWindow目录中找到源代码,目录里面有两个文件,它们是汇编源文件FirstWindow.asm和nmake工具使用的makefile,汇编源程序如下:
;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※ .586 .model flat,stdcall option casemap:none include windows.inc include gdi32.inc includelib gdi32.lib include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib .data? hInstance dd ? lpCmdLine dd ? hWinMain dd ? .const szClassName db "Win32",0 szCaptionMain db "窗口标题",0 szText db "WIN32位汇编语言程序设计(窗口应用程序源码)",0 .code ;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※ ; 窗口过程 ProcWinMain proc uses ebx edi esi,hWnd,uMsg,wParam,lParam local @stPs:PAINTSTRUCT local @stRect:RECT local @hDc ;处理消息 mov eax,uMsg ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .if eax == WM_PAINT invoke BeginPaint,hWnd,addr @stPs mov @hDc,eax invoke GetClientRect,hWnd,addr @stRect invoke DrawText,@hDc,addr szText,-1,\ addr @stRect, DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint,hWnd,addr @stPs ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .elseif eax == WM_CLOSE invoke DestroyWindow,hWinMain invoke PostQuitMessage,NULL ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ xor eax,eax ret ProcWinMain endp ;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※ WinMain proc uses ebx edi esi,_hInstance,_hPrevInstance,_lpCmdLine,_nCmdShow local @stWc:WNDCLASSEX local @stMsg:MSG ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; 注册窗口类 invoke RtlZeroMemory,addr @stWc,sizeof WNDCLASSEX mov @stWc.cbSize,sizeof WNDCLASSEX invoke LoadCursor,0,IDC_ARROW mov @stWc.hCursor,eax push _hInstance pop @stWc.hInstance mov @stWc.style,CS_HREDRAW or CS_VREDRAW mov @stWc.lpfnWndProc,offset ProcWinMain ;窗口过程地址 mov @stWc.hbrBackground,COLOR_WINDOW + 1 mov @stWc.lpszClassName,offset szClassName invoke RegisterClassEx,addr @stWc ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; 建立并显示窗口 invoke CreateWindowEx,WS_EX_CLIENTEDGE,offset szClassName,offset szCaptionMain,\ WS_OVERLAPPEDWINDOW,100,100,480,320,NULL,NULL,hInstance,NULL mov hWinMain,eax invoke ShowWindow,hWinMain,_nCmdShow invoke UpdateWindow,hWinMain ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; 消息循环 .while TRUE invoke GetMessage,addr @stMsg,NULL,0,0 .break .if eax == 0 invoke TranslateMessage,addr @stMsg invoke DispatchMessage,addr @stMsg .endw ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ret WinMain endp ;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※ start: invoke GetModuleHandle,NULL mov hInstance,eax invoke GetCommandLine mov lpCmdLine,eax invoke WinMain,hInstance,NULL,lpCmdLine,SW_SHOWNORMAL invoke ExitProcess,NULL end start ;※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
上页:第04章 第一个窗口程序 · 4.1 开始了解窗口(1) 下页:第04章 第一个窗口程序 · 4.1 开始了解窗口(3)
第04章 第一个窗口程序
版权所有 © 云南伯恩科技 证书:粤ICP备09170368号