§ Основной код
* hInstance Переданная текущая программа
* hPrevInstance Программа, которая передала управление
* lpCmdLine Строка запроса (нулевой символ в конце)
* nShowCmd Показывает состояние окна
Подробное описание
в этой статье.
1@echo off
2g++ -m32 -g3 -static-libgcc -mwindows -lgdi32 main.cpp -o main.exe
3strip main.exe
4main.exe
1#include "demoapp.cpp"
2
3int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
4{
5 DemoApp app;
6 app.init(hInstance, 1280, 800, "Windows", 50, 4);
7
8 int test = 0;
9 while (app.wait()) {
10
11
12 if (app.is_timer()) {
13
14 test++;
15 for (int y = 0; y < 200; y++)
16 for (int x = 0; x < 320; x++)
17 app.pset(x, y, x*y + test);
18 }
19
20 app.repaint();
21 }
22
23 return 0;
24}
§ Класс-обработчик demoapp.cpp
1
2
3
4#define WIN32_LEAN_AND_MEAN
5
6#include <windows.h>
7#include <stdio.h>
8#include <stdlib.h>
9
10#include "demoapp.h"
11
12
13
14class DemoApp {
15protected:
16
17 HWND hWnd;
18 INT64 frameMillisecond;
19 int last_events;
20
21public:
22
23
24
25
26 void init(HINSTANCE hInstance, int width, int height, const char* name, int fps, int scale) {
27
28 DWORD dwExStyle = WS_EX_APPWINDOW;
29 DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
30
31 int x, y, w, h;
32
33 WNDCLASS wc;
34 RECT rc;
35
36 wc.style = CS_OWNDC;
37 wc.lpfnWndProc = MainWndProc;
38 wc.cbClsExtra = 0;
39 wc.cbWndExtra = 0;
40 wc.hInstance = hInstance;
41 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
42 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
43 wc.hbrBackground = NULL;
44 wc.lpszMenuName = NULL;
45 wc.lpszClassName = TEXT("MainWndEx");
46
47 if (!RegisterClass(&wc)) {
48
49 MessageBox(NULL, TEXT("RegisterClass failed!"), TEXT("Error"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND);
50 return;
51 }
52
53 rc.left = 0;
54 rc.top = 0;
55 rc.right = width;
56 rc.bottom = height;
57
58 window_width = width;
59 window_height = height;
60
61 win_ws = window_width / scale;
62 win_hs = window_height / scale;
63
64 if (!AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle)) {
65
66 MessageBox(NULL, TEXT("AdjustWindowRectEx failed!"), TEXT("Error"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND);
67 return;
68 }
69
70 w = width;
71 h = height;
72 x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2;
73 y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2;
74
75 EventAccept = 0;
76 last_events = 0;
77 frameMillisecond = 1000 / fps;
78
79
80 pixels = (COLORREF*) malloc (width * height * sizeof(COLORREF));
81
82 hWnd = CreateWindowEx(dwExStyle, wc.lpszClassName, name, dwStyle, x, y, w, h, NULL, NULL, hInstance, NULL);
83 if (!hWnd) {
84 MessageBox(NULL, TEXT("CreateWindowEx failed."), TEXT("Error"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND);
85 return;
86 }
87
88 bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo);
89 bitmapInfo.bmiHeader.biWidth = width / scale;
90 bitmapInfo.bmiHeader.biHeight = -height / scale;
91 bitmapInfo.bmiHeader.biPlanes = 1;
92 bitmapInfo.bmiHeader.biBitCount = 32;
93 bitmapInfo.bmiHeader.biCompression = BI_RGB;
94
95 SetTimer(hWnd, 0, frameMillisecond, NULL);
96 ShowWindow(hWnd, SW_SHOWNORMAL);
97 UpdateWindow(hWnd);
98 }
99
100
101 void repaint() {
102
103 if (is_timer()) {
104 InvalidateRect(hWnd, NULL, FALSE);
105 }
106 }
107
108
109 int is_timer() {
110 return last_events & MYEVENT_WM_TIMER ? 1 : 0;
111 }
112
113
114 int is_keydown() { return last_events & MYEVENT_WM_KEYDOWN ? 1 : 0; }
115 int is_keyup() { return last_events & MYEVENT_WM_KEYUP ? 1 : 0; }
116 int kb_key() { return DataKeyboard; }
117
118
119 int peek_messages() {
120
121 MSG msg;
122
123 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
124
125
126 if (msg.message == WM_QUIT)
127 return 0;
128
129 TranslateMessage (&msg);
130 DispatchMessage (&msg);
131 }
132
133 Sleep(1);
134 return 1;
135 }
136
137
138 int wait() {
139
140 EventAccept = 0;
141 do {
142
143 if (peek_messages() == 0)
144 return 0;
145
146 } while (!EventAccept);
147
148 last_events = EventAccept;
149 return EventAccept;
150 }
151
152
153
154
155 void pset(int x, int y, int color) {
156
157 if (x >= 0 && y >= 0 && x < win_ws && y < win_hs) {
158 pixels[win_ws*y + x] = color;
159 }
160 }
161
162
163 void line(int x1, int y1, int x2, int y2, int color) {
164
165 int deltax = abs(x2 - x1);
166 int deltay = abs(y2 - y1);
167 int signx = x1 < x2 ? 1 : -1;
168 int signy = y1 < y2 ? 1 : -1;
169
170 int error = deltax - deltay;
171 int error2;
172
173 pset(x2, y2, color);
174 while (x1 != x2 || y1 != y2)
175 {
176 pset(x1, y1, color);
177 error2 = error * 2;
178
179 if (error2 > -deltay) {
180 error -= deltay;
181 x1 += signx;
182 }
183
184 if (error2 < deltax) {
185 error += deltax;
186 y1 += signy;
187 }
188 }
189 }
190
191
192 void cls(int color) {
193
194 for (int i = 0; i < win_ws * win_hs; i++)
195 pixels[i] = color;
196 }
197};
198
199
200LRESULT CALLBACK MainWndProc(HWND MyWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
201
202 switch (msg) {
203
204 case WM_CLOSE:
205 case WM_DESTROY:
206
207 PostQuitMessage(0);
208 return 0;
209
210 case WM_ERASEBKGND:
211 return TRUE;
212
213 case WM_KEYDOWN:
214
215 EventAccept |= MYEVENT_WM_KEYDOWN;
216 DataKeyboard = wParam;
217 return 0;
218
219 case WM_KEYUP:
220
221 EventAccept |= MYEVENT_WM_KEYUP;
222 DataKeyboard = wParam;
223 return 0;
224
225 case WM_TIMER:
226
227 EventAccept |= MYEVENT_WM_TIMER;
228 return 0;
229
230 case WM_PAINT:
231
232 PAINTSTRUCT ps;
233 RECT r;
234 HDC hDC;
235
236 hDC = BeginPaint(MyWnd, &ps);
237 GetClientRect(MyWnd, &r);
238
239
240 StretchDIBits(
241 hDC,
242 0, 0, window_width, window_height,
243 0, 0, win_ws, win_hs,
244 pixels, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY);
245
246 EndPaint(MyWnd, &ps);
247 return 0;
248 }
249
250 return DefWindowProc(MyWnd, msg, wParam, lParam);
251}
§ Заголовочный файл demoapp.h
1
2LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
3int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow);
4
5
6int window_width, window_height;
7int win_ws, win_hs;
8int EventAccept;
9WPARAM DataKeyboard;
10
11
12static COLORREF* pixels;
13static BITMAPINFO bitmapInfo;
14
15enum Events {
16
17 MYEVENT_WM_TIMER = 1,
18 MYEVENT_WM_KEYDOWN = 2,
19 MYEVENT_WM_KEYUP = 4,
20};