3. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 3
Щоб визначити новий клас вікна, треба заповнити структуру
WNDCLASS, що містить такі поля:
UINT style - стиль (поведінка) класу вікон,
WNDPROC lpfnWndProc - процедура обробки подій вікна,
int cbClsExtra - розмір додаткової пам'яті в системній структурі класу
для даних користувача,
int cbWndExtra - розмір додаткової пам'яті в системній структурі вікна
для даних користувача,
HINSTANCE hInstance - дескриптор модуля (примірника програми), в
якому реалізована процедура обробки,
HICON hIcon - дескриптор іконки вікна,
HCURSOR hCursor - дескриптор курсора миші для вікна,
HBRUSH hbrBackground - дескриптор "пензлика" для зафарбовування
фону вікна,
LPCSTR lpszMenuName - ім'я ресурсу, що містить меню вікна,
LPCSTR lpszClassName - ім'я класу.
4. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 4
Далі віконний клас потрібно зареєструвати в системі:
При успішному завершенні функція повертає цілочисельний
код, відповідний рядку-імені класу в загальносистемної таблиці
рядків (такий код називається атомом). При помилці
повертається 0.
Далі потрібно створити вікно. Викликається функція
WORD WINAPI RegisterClass(const WNDCLASS *lpwc)
HWND WINAPI CreateWindow()
5. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 5
Замість параметрів x, y, nWidth, nHeight допустимо передавати
константу CW_USEDEFAULT, що дозволяє операційній
системі задати ці числа на її розсуд.
HWND WINAPI CreateWindow (
LPCSTR lpClassName, //ім'я класу
LPCSTR lpWindowName, //ім'я вікна (заголовок)
DWORD dwStyle, //стиль (поведінка) вікна
int x, //горизонтальна позиція вікна на екрані
int y, //вертикальна позиція вікна на екрані
int nWidth, //ширина вікна
int nHeight, //висота вікна
HWND hWndParent, //дескриптор батьківського вікна
HMENU hMenu, //дескриптор меню
HANDLE hInstance, //дескриптор екземпляра програми
LPVOID lpParam //покажчик на яку-небудь нісенітницю
)
6. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 6
Після створення вікна потрібно зробити його видимим
(відобразити), якщо тільки воно не створено зі стилем
WS_VISIBLE:
Другий параметр цієї функції - код стану відображення вікна. В
якості цього коду можна взяти значення четвертого параметра, з
яким була запущена функція WinMain. Інші можливі значення
цього параметра:
SW_SHOW - відобразити і активувати вікно;
SW_HIDE - приховати вікно;
SW_MAXIMIZE - розгорнути вікно на весь екран;
SW_RESTORE - активувати вікно і відобразити його в розмірах за
умовчанням;
SW_MINIMIZE - згорнути вікно.
Якщо перед викликом цієї функції вікно було видимим, функція
повертає TRUE, якщо ж вікно було приховано - FALSE.
BOOL WINAPI ShowWindow(HWND hw, int ss)
7. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 7
Якщо клієнтська область головного вікна програми містить
об'єкти, промальовані за повідомленням WM_PAINT, має сенс
промальовувати ці об'єкти відразу після відображення
головного вікна на екрані. Функція UpdateWindow
безпосередньо викликає процедуру обробки подій зазначеного
вікна з повідомленням WM_PAINT (минаючи чергу
повідомлень додатка):
Windows використовує два способи доставки повідомлень
процедурі обробки подій вікна:
безпосередній виклик процедури обробки подій (позачергові
або невідкладні повідомлення - nonqueued messages);
переміщення повідомлення в пов'язаний з даним додатком
буфер типу FIFO
BOOL WINAPI UpdateWindow(HWND hw)
8. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 8
До позачергових повідомлень відносяться ті повідомлення, які
безпосередньо впливають на вікно, наприклад, повідомлення активації
вікна WM_ACTIVATE і т.п. Крім того, поза чергою повідомлень
обробляються повідомлення, згенеровані різними викликами Win32
API, такими як SetWindowPos, UpdateWindow, SendMessage,
SendDlgItemMessage ...
До відкладених повідомлень відносяться повідомлення, пов'язані з
реакцією користувача: натискання клавіш на клавіатурі, рух мишки та
кліки. Щоб витягти повідомлення з черги, програма викликає функцію
BOOL WINAPI GetMessage (
MSG * lpmsg, //сюди потрапляє повідомлення з усякими параметрами
HWND hw, //витягувати тільки повідомлення для вказаного вікна
(NULL - все)
UINT wMsgFilterMin, //фільтр повідомлень (нам не треба - ставимо 0)
UINT wMsgFilterMax //фільтр повідомлень (нам не треба - ставимо 0)
)
9. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 9
Ця функція повертає FALSE, якщо отримано повідомлення WM_QUIT,
і TRUE в іншому випадку.
Очевидно, що умовою продовження циклу обробки подій є результат
цієї функції. Якщо додаток хоче завершити свою роботу, він посилає
саме собі повідомлення WM_QUIT за допомогою функції
Її параметр - статус виходу програми. Зазвичай ця функція
викликається у відповідь на повідомлення про знищення вікна
WM_DESTROY.
Після вилучення повідомлення з черги слід викликати функцію
TranslateMessage, що переводить повідомлення від натиснутих
клавіш в легкооброблювальний вигляд, а потім викликає функцію
DispatchMessage, яка визначає призначення цього повідомлення і
викликає відповідну процедуру обробки подій.
void WINAPI PostQuitMessage (int nExitCode)
BOOL WINAPI TranslateMessage(const MSG *lpmsg)
LONG WINAPI DispatchMessage(const MSG *lpmsg)
10. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 10
Процедура обробки повідомлень вікна повинна бути оголошена за
наступним прототипу:
Значення параметрів: hw - дескриптор вікна, якому призначено
повідомлення, msg - код повідомлення, wp і lp - 32-бітові параметри
повідомлення, інтерпретація яких залежить від коду повідомлення.
Найчастіше старший / молодший байт або старше / молодше слово
параметрів повідомлення несуть незалежний сенс, тоді зручно
використовувати певні в windows.h макроси:
Наприклад, повідомлення WM_COMMAND надсилається вікну в
трьох випадках:
1. користувач вибрав яку-небудь команду меню;
2. користувач натиснув "гарячу" клавішу (accelerator);
3. в дочірньому вікні відбулася певна подія.
LRESULT CALLBACK WindowProc (HWND hw, UINT msg, WPARAM wp, LPARAM lp)
#define LOBYTE(w) ((BYTE) (w))
#define HIBYTE(w) ((BYTE) (((WORD) (w) >> 8) & 0xFF))
#define LOWORD(l) ((WORD) (l))
#define HIWORD(l) ((WORD) (((DWORD) (l) >> 16) & 0xFFFF))
11. Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 11
Процедура обробки подій повинна повернути певне 32-бітове
значення, інтерпретація якого також залежить від типу
повідомлення. У більшості випадків, якщо повідомлення успішно
оброблено, процедура повертає значення 0.
Процедура обробки подій не повинна ігнорувати повідомлення.
Якщо процедура не обробляє якесь повідомлення, вона повинна
повернути його системі для обробки за замовчуванням. Для цього
викликається функція:
LRESULT WINAPI DefWindowProc(HWND hw, UINT msg, WPARAM wp,
LPARAM lp)