.386
.model flat,stdcall
option casemap:noneWinMain proto :DWORD,:DWORD,:DWORD,:DWORD
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib.DATA
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
OurText db "Win32 assembly is great and easy!",0.DATA?
hInstance HINSTANCE ?
CommandLine LPSTR ?.CODE
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eaxWinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInst
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW
mov eax,msg.wParam
ret
WinMain endpWndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==WM_PAINT
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke GetClientRect,hWnd, ADDR rect
invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, \
DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWnd, ADDR ps
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax, eax
ret
WndProc endp
end start
LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT
Toto jsou
lokální proměnné, které používají GDI funkce v naší WM_PAINT části.
hdc ukládá handel ke kontextu zařízení obdržený od funkce BeginPaint,
ps je PAINTSTRUCT struktura. Většinou nepoužíváte hodnoty uložené v ps.
Je předána BeginPaint funkci a Windows ji naplní vhodnými hodnotami.
Vy poté předáte ps EndPaint funkci, když skončíte s kreslením do klientské oblasti.
rect je RECT struktura definována takto:
RECT StructLeft a top jsou souřadnice horního levého rohu, Right a bottom jsou souřadnice pravého dolního rohu obdélníku. Jedna věc je důležitá: Počátek os x-y leží v horním levém rohu klientské oblasti, takže např. bod y=10 je POD bodem y=0.
left LONG ?
top LONG ?
right LONG ?
bottom LONG ?
RECT ends
invoke BeginPaint,hWnd, ADDR ps
mov hdc,eax
invoke GetClientRect,hWnd, ADDR rect
invoke DrawText, hdc,ADDR OurText,-1, ADDR rect, \
DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWnd, ADDR ps
Jako reakci na WM_PAINT zprávu voláte BeginPaint s handelem k oknu, do kterého chcete kreslit a neinicializovanou PAINTSTRUCT strukturu jako parametry. Po úspěšném zavolání obsahuje eax handle ke kontextu zařízení. Dále voláme GetClientRect, abychom získali rozměry klientské oblasti. Rozměry jsou vráceny v proměnné rect, kterou předáváme funkci DrawText jako jeden z jejich parametrů. DrawText syntaxe je:
DrawText proto hdc:HDC, lpString:DWORD, nCount:DWORD, lpRect:DWORD, uFormat:DWORD
DrawText je vyšší API funkce pro výstup textu. Stará se o některé detaily jako je zarovnání slov, centrování apod., aby jste se mohli zaměřit na řetězec, který chcete nakreslit. Její nižší (low-level) bratříček, TextOut, bude objektem našeho zkoumání příště :). DrawText zformátuje řetězec tak, aby se vešel do obdélníku. Použije současně zvolený font, barvu a pozadí (v kontextu zařízení) a nakreslí text. Vrací výšku textu v jednotkách zařízení, v našem případě v pixelech. Pojďme si prohlédnout její parametry: