386 пишемо під архітектуру 386 model flat stdcall плоска модель пам ят

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
.386 ; пишемо під архітектуру 386
.model flat, stdcall ; плоска модель пам'яті, виклики функцій по стандарту stdcall (аргументи функціям передаються через стек в зворотньому порядку і сама функція повинна видяти їх звідти)
option casemap:none ; включаємо чутливість до регістру символів
include \masm32\include\windows.inc ; підключаємо обгортку для роботи з ОС Windows
include \masm32\include\user32.inc ; обгортка для user32.dll
includelib \masm32\lib\user32.lib ; скомпільована бібліотека для user32.dll
include \masm32\include\kernel32.inc ; обгортка для kernel32.dll
includelib \masm32\lib\kernel32.lib ; скомпільована бібліотека для kernel32.dll
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD ; прототип процедури WinMain
.DATA ; нижче дані, частини сегментів програми
ClassName db "WinAPIPaint", 0 ; клас вікна
AppName db "WinAPI. Малювання. Будинок. by Vladimir Shevchuk", 0 ; заголовок вікна
.DATA? ; невизначені сегменти
hInstance HINSTANCE ? ; інстанс хендл програми
.CODE ; код програми
start: ; початок програми
invoke GetModuleHandle, NULL ; отримуємо інстанс хендл
mov hInstance, eax ; hmodule == hinstance
invoke WinMain, hInstance, NULL, NULL, SW_SHOWDEFAULT ; викликаємо WinMain
invoke ExitProcess, eax ; виходимо
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD ; процедура WinMain
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 hInstance
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,CmdShow ; показати вікно
invoke UpdateWindow, hwnd ; оновлення області вікна
.WHILE TRUE ; безкінечний цикл :D (обробка подій)
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 endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.IF uMsg == WM_DESTROY ; якщо закрили вікно
invoke PostQuitMessage, NULL ; тоді вихід з програми
.ELSE ; інакше
invoke DefWindowProc, hWnd, uMsg, wParam, lParam ; Обробка повідомлень
ret ; вихід в батьківську процедуру
.ENDIF ; кінець блоку IF
xor eax, eax
ret ; вихід в батьківську процедуру
WndProc endp
end start ; кінець програми