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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
| // " /*...*/ " - перевод заметок редактора
// " // " - мои заметки
// Статьи для ознакомления:
// http://www.vsokovikov.narod.ru/New_MSDN_API
// https://docs.microsoft.com/en-us/windows/win32/api
// Терминология:
// Сообщение - при нажатии кнопки (Или другого действия) отправляется id команды в обработчик. id команды - это Сообщение
// Дескриптор (Так же handle, хендл) - идентификатор, который ОС присваивает объектам, обладающим свойствами окна (Относящихся к окну, например значок). В основном само окно
// Имя - название переменной или константы. Даётся на свой вкус
// Владелец - Родитель, к которому относится окно
#include <windows.h>
/* Это блок, где все входящие сообщения к окну должны что-то делать */
// Блок обработки информации
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) { // Функция с получением сообщений с программы (hwnd, Message... - имена) (P.S. WndProc уточнить имя ли это)
// LRESULT - значение ответ программы на сообщение
//CALLBACK - вернуть в программу (return)
//WindowProc или WndProc - описание реакции системы на сообщение (P.S. Проверить, может быть именем)
//HWND - дескриптор окна (ИД объекта-окна)
//UINT - только положительный int (0 to 4294967295), используется как номер переменной msg*
//WPARAM - флаг на размеры окна, сведённость или развёрнутость
//LPARAM - ширина и высота окна
switch(Message) { // Простая функция switch (В случае если Message ...)
/* После "Уничтожения" приказ на остановку потока */
case WM_DESTROY: { // В случае WM_DESTROY (Нажата кнопка закрытия окна)
PostQuitMessage(0); // Завершить программу (0 или int nExitCode) (P.S. Уточнить способности nExitCode)
break; // Конец случая
}
/* Остальное большинство сообщений обрабатываются с использованием дефолтных процедур */
default: // Если не совпало ни с одним из "case"
return DefWindowProc(hwnd, Message, wParam, lParam); // Вернуть дефолтный WndProc (P.S. Уточнить DefWindowProc и где используется вернувшийся результат)
}
return 0;
}
/* Основная функция программы с графическим интерфейсом, здесь начинается выполнение */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // Добавляется точка входа сообщений (hInstance, hPrevInstance... - имена)
// WINAPI - начальная точка входа (Функция)
// WinMain - любое имя
// HINSTANCE (hInstance) - основной дескриптор программы
// HINSTANCE (hPrevInstance) - дескриптор прошлого экземпляра программы (На новых версиях windows используется в редких случаях)
// LPSTR - указатель на строку, завершающуюся нулем или 8-разрядную Windows (P.S. Изучить эту тему подробнее)
// int nCmdShow - значение окна (Например свёрнутый или развёрнутый)
// Вводим переменные
WNDCLASSEX wc; /* Структура свойств нашего окна */ // Переменная, содержащая стиль, размер и т.д. (P.S. Изучить синтаксис)
HWND hwnd; /* "HANDLE", отсюда и буква H, или указатель на наше окно */ // Сокращение Handle WiNDow, все функции с припиской H обозначают указатели к окну
MSG msg; /* Временное хранилище для сообщений */ // Команда отправляется в msg, после обрабатывается и обнуляется
/* Обнулим структуру и устанавливаем то, что мы хотим изменить */
memset(&wc,0,sizeof(wc)); // memset - обнуление буфера к указанному символу (&Место обнуления, задаваемый символ, число символов (В данном случае размер структуры)
// Далее сами настройки, относящиеся к wc (wc.настройка = значение)
wc.cbSize = sizeof(WNDCLASSEX); // Установка размера структуры (В байтах), база - WNDCLASSEX
wc.lpfnWndProc = WndProc; /* Именно сюда мы будем отправлять сообщения */ // Отправка сообщений в блок обработки команд
wc.hInstance = hInstance; // Установка хендла
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Установка курсора в окне
/* Белый, COLOR_WINDOW это просто #define для цвета системы, попробуйте ctrl+Click по нему */
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); // Цвет фона программы (HBRUSH - "База типов цветов")(COLOR_WINDOW+1 - сам цвет, единичка для работоспособности)
wc.lpszClassName = "WindowClass"; // Имя класса окна
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* Загрузка стандартной иконки */
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* Используйте имя "А", чтобы использовать значок проекта */ // P.S. Возможно вместо NULL, проверить
if(!RegisterClassEx(&wc)) { // Если окно НЕ(!) создано (По структуре wc)
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK); // Создать окно сообщения
// NULL - Владелец окна сообщения, "Сообщение", "Название окна", Значок в окне (По желанию) | Кнопки на окне (По желанию)
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW, // Создать окно класса (Стиль, Название класса, Название окна, Начальная позиция окна | Набор стилей
CW_USEDEFAULT, /* x */
CW_USEDEFAULT, /* y */
640, /* Ширина */
480, /* Высота */
NULL,NULL,hInstance,NULL); // Хендл меню, Хендл владельца окна (в данном случае меню класса), хендл с которым связано окно, указатель на значение переданное окну через структуру
if(hwnd == NULL) { // Если хендл равен ничему (Не получилось создать)
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK); // Создать окно сообщения
return 0;
}
/*
Это сердце нашей программы, где все входные данные обрабатываются и
отправляются в WndProc. Обратите внимание, что GetMessage блокирует поток кода до тех пор, пока он что-то не получит, поэтому
этот цикл не приведет к неоправданно высокой загрузке процессора
*/
while(GetMessage(&msg, NULL, 0, 0) > 0) { /* Если ошибка не получена... */ // Пока значение сообщения...
// Из msg...
// Из окна NULL (У нас только одно окно)...
// Начиная со значения...
// Заканчивая значением...
// больше, чем 0
TranslateMessage(&msg); /* Перевести коды в символы, если таковые имеются */
DispatchMessage(&msg); /* Отправьте его в WndProc */
}
return msg.wParam; // вернуть wParam к основному блоку
} |