§ Основной код
* hInstance Переданная текущая программа * hPrevInstance Программа, которая передала управление * lpCmdLine Строка запроса (нулевой символ в конце) * nShowCmd Показывает состояние окнаПодробное описание в этой статье.
@echo off g++ -m32 -g3 -static-libgcc -mwindows -lgdi32 main.cpp -o main.exe strip main.exe main.exe
#include "demoapp.cpp" int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { DemoApp app; app.init(hInstance, 1280, 800, "Windows", 50, 4); int test = 0; while (app.wait()) { // Срабатывает на таймере if (app.is_timer()) { test++; for (int y = 0; y < 200; y++) for (int x = 0; x < 320; x++) app.pset(x, y, x*y + test); } app.repaint(); } return 0; }
§ Класс-обработчик demoapp.cpp
// Опции компилятора -static-libgcc -mwindows -lgdi32 // Убрать лишнее из генерируемого файла #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdio.h> #include <stdlib.h> #include "demoapp.h" // --------------------------------------------------------------------------------------- class DemoApp { protected: HWND hWnd; INT64 frameMillisecond; int last_events; public: // Инициализация окна, создание и назначение обработчиков // fps количество кадров в секунду // scale: 0=1x1, 1=2x2, 2=4x4, ... void init(HINSTANCE hInstance, int width, int height, const char* name, int fps, int scale) { DWORD dwExStyle = WS_EX_APPWINDOW; DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU; int x, y, w, h; WNDCLASS wc; RECT rc; wc.style = CS_OWNDC; wc.lpfnWndProc = MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("MainWndEx"); if (!RegisterClass(&wc)) { MessageBox(NULL, TEXT("RegisterClass failed!"), TEXT("Error"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND); return; } rc.left = 0; rc.top = 0; rc.right = width; rc.bottom = height; window_width = width; window_height = height; win_ws = window_width / scale; win_hs = window_height / scale; if (!AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle)) { MessageBox(NULL, TEXT("AdjustWindowRectEx failed!"), TEXT("Error"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND); return; } w = width; h = height; x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; y = (GetSystemMetrics(SM_CYSCREEN) - h) / 2; EventAccept = 0; last_events = 0; frameMillisecond = 1000 / fps; // Выделить память для пиксельного буфера pixels = (COLORREF*) malloc (width * height * sizeof(COLORREF)); hWnd = CreateWindowEx(dwExStyle, wc.lpszClassName, name, dwStyle, x, y, w, h, NULL, NULL, hInstance, NULL); if (!hWnd) { MessageBox(NULL, TEXT("CreateWindowEx failed."), TEXT("Error"), MB_ICONERROR | MB_OK | MB_SETFOREGROUND); return; } bitmapInfo.bmiHeader.biSize = sizeof(bitmapInfo); bitmapInfo.bmiHeader.biWidth = width / scale; bitmapInfo.bmiHeader.biHeight = -height / scale; bitmapInfo.bmiHeader.biPlanes = 1; bitmapInfo.bmiHeader.biBitCount = 32; bitmapInfo.bmiHeader.biCompression = BI_RGB; SetTimer(hWnd, 0, frameMillisecond, NULL); ShowWindow(hWnd, SW_SHOWNORMAL); UpdateWindow(hWnd); } // Перерисовка окна void repaint() { if (is_timer()) { InvalidateRect(hWnd, NULL, FALSE); } } // Сработал таймер int is_timer() { return last_events & MYEVENT_WM_TIMER ? 1 : 0; } // Сработала клавиатура int is_keydown() { return last_events & MYEVENT_WM_KEYDOWN ? 1 : 0; } int is_keyup() { return last_events & MYEVENT_WM_KEYUP ? 1 : 0; } int kb_key() { return DataKeyboard; } // Обработка сообщений от windows int peek_messages() { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // Выход из процедуры ожидания if (msg.message == WM_QUIT) return 0; TranslateMessage (&msg); DispatchMessage (&msg); } Sleep(1); return 1; } // Процедура ожидания int wait() { EventAccept = 0; do { if (peek_messages() == 0) return 0; } while (!EventAccept); last_events = EventAccept; return EventAccept; } // ==== Графические процедуры ==== // Поставить точку в буфере void pset(int x, int y, int color) { if (x >= 0 && y >= 0 && x < win_ws && y < win_hs) { pixels[win_ws*y + x] = color; } } // Нарисовать линию void line(int x1, int y1, int x2, int y2, int color) { int deltax = abs(x2 - x1); int deltay = abs(y2 - y1); int signx = x1 < x2 ? 1 : -1; int signy = y1 < y2 ? 1 : -1; int error = deltax - deltay; int error2; pset(x2, y2, color); while (x1 != x2 || y1 != y2) { pset(x1, y1, color); error2 = error * 2; if (error2 > -deltay) { error -= deltay; x1 += signx; } if (error2 < deltax) { error += deltax; y1 += signy; } } } // Очистить весь экран void cls(int color) { for (int i = 0; i < win_ws * win_hs; i++) pixels[i] = color; } }; // Обработчик событий от Windows LRESULT CALLBACK MainWndProc(HWND MyWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_CLOSE: case WM_DESTROY: PostQuitMessage(0); return 0; case WM_ERASEBKGND: return TRUE; case WM_KEYDOWN: EventAccept |= MYEVENT_WM_KEYDOWN; DataKeyboard = wParam; return 0; case WM_KEYUP: EventAccept |= MYEVENT_WM_KEYUP; DataKeyboard = wParam; return 0; case WM_TIMER: EventAccept |= MYEVENT_WM_TIMER; return 0; case WM_PAINT: PAINTSTRUCT ps; RECT r; HDC hDC; hDC = BeginPaint(MyWnd, &ps); GetClientRect(MyWnd, &r); // dstx, dsty, dstw, dsth, srcx, srcy, scrw, scrh StretchDIBits( hDC, 0, 0, window_width, window_height, 0, 0, win_ws, win_hs, pixels, &bitmapInfo, DIB_RGB_COLORS, SRCCOPY); EndPaint(MyWnd, &ps); return 0; } return DefWindowProc(MyWnd, msg, wParam, lParam); }
§ Заголовочный файл demoapp.h
// Объявление процедуры обработки данных LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow); // Глобальные данные int window_width, window_height; int win_ws, win_hs; int EventAccept; WPARAM DataKeyboard; // Хранение пиксельных данных static COLORREF* pixels; static BITMAPINFO bitmapInfo; enum Events { MYEVENT_WM_TIMER = 1, MYEVENT_WM_KEYDOWN = 2, MYEVENT_WM_KEYUP = 4, };
25 июн, 2021
© 2007-2023 Мочил фиговый человек