上一节 中我展示了一个用 MessageBox显示的 windows对话框,让读者对 32位汇编有一个感性的认识,本节通过创建一个 windows标准窗口,来展示一下相对完整的 windows程序的写法,同时熟悉一下汇编的基本语法。还是依旧, 先看例子,然后再讲述理论。
; FileName: NormalWindow.asm
; Function: Show a standar window
; Author: thinker
; Compile & Link:
; ml /c /coff NormalWindow.asm
; link /subsystem:windows NormalWindow.obj
.386
.model flat, stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include gdi32.inc
includelib gdi32.lib
.data?
hInstance dd ?
hWinMain dd ?
.const
szAppName db 'NormalWindow', 0
szText db 'things have changed from now', 0
szError db 'Error', 0
szErrorText db 'This program requires NT !', 0
szErrCreateWnd db 'CreateWindow Error.', 0
.code
_WinProc proc hWnd, uMsg, wParam, lParam
local @stPS:PAINTSTRUCT
local @stRC:RECT
local @hDC
mov eax, uMsg
.if eax == WM_PAINT
invoke BeginPaint, hWnd, addr @stPS
mov @hDC, eax
invoke SetTextColor, @hDC, 0ff00h
invoke SetBkColor, @hDC, 0
invoke GetClientRect, hWnd, addr @stRC
invoke DrawText, @hDC, offset szText, -1, addr @stRC, DT_SINGLELINE or DT_VCENTER or DT_CENTER
invoke EndPaint, hWnd, addr @stPS
.elseif eax == WM_CLOSE
invoke DestroyWindow, hWinMain
invoke PostQuitMessage, 0
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
xor eax, eax
ret
_WinProc endp
_WinMain proc
local @stWC:WNDCLASSEX
local @stMsg:MSG
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke RtlZeroMemory, addr @stWC, sizeof @stWC
mov @stWC.cbSize, sizeof WNDCLASSEX
mov @stWC.style, CS_HREDRAW or CS_VREDRAW
mov @stWC.lpfnWndProc, offset _WinProc
push hInstance
pop @stWC.hInstance
invoke LoadIcon, NULL, IDI_APPLICATION
mov @stWC.hIcon, eax
mov @stWC.hIconSm, eax
invoke LoadCursor, NULL, IDC_ARROW
mov @stWC.hCursor, eax
invoke GetStockObject, BLACK_BRUSH
mov @stWC.hbrBackground, eax
mov @stWC.lpszClassName, offset szAppName
invoke RegisterClassEx, addr @stWC
.if !eax
invoke MessageBox, NULL, offset szErrorText, offset szError, MB_OK or MB_ICONERROR
ret
.endif
invoke CreateWindowEx, /
WS_EX_CLIENTEDGE, /
offset szAppName, /
offset szAppName, /
WS_OVERLAPPEDWINDOW, /
CW_USEDEFAULT, /
CW_USEDEFAULT, /
CW_USEDEFAULT, /
CW_USEDEFAULT, /
NULL, /
NULL, /
hInstance, /
NULL
.if !eax
invoke MessageBox, NULL, offset szErrCreateWnd, offset szError, MB_OK or MB_ICONERROR
ret
.endif
mov hWinMain, eax
invoke ShowWindow, hWinMain, SW_SHOWNORMAL
invoke UpdateWindow, hWinMain
.while TRUE
invoke GetMessage, addr @stMsg, NULL, 0, 0
.break .if !eax
invoke TranslateMessage, addr @stMsg
invoke DispatchMessage, addr @stMsg
.endw
ret
_WinMain endp
start:
call _WinMain
invoke ExitProcess, NULL
end start
程序运行效果如下 (为了不占用太大空间,我把窗口拉小了 ):
关于程序的解释说明, 请看下一篇文章 。
<script type="text/javascript"> </script> <script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>