WinAPI
Модуль 1.3
Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 2
Мінімальний 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 - ім'я класу.
Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 4
 Далі віконний клас потрібно зареєструвати в системі:
 При успішному завершенні функція повертає цілочисельний
код, відповідний рядку-імені класу в загальносистемної таблиці
рядків (такий код називається атомом). При помилці
повертається 0.
 Далі потрібно створити вікно. Викликається функція
WORD WINAPI RegisterClass(const WNDCLASS *lpwc)
HWND WINAPI CreateWindow()
Мінімальний 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 //покажчик на яку-небудь нісенітницю
)
Мінімальний 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)
Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 7
 Якщо клієнтська область головного вікна програми містить
об'єкти, промальовані за повідомленням WM_PAINT, має сенс
промальовувати ці об'єкти відразу після відображення
головного вікна на екрані. Функція UpdateWindow
безпосередньо викликає процедуру обробки подій зазначеного
вікна з повідомленням WM_PAINT (минаючи чергу
повідомлень додатка):
 Windows використовує два способи доставки повідомлень
процедурі обробки подій вікна:
 безпосередній виклик процедури обробки подій (позачергові
або невідкладні повідомлення - nonqueued messages);
 переміщення повідомлення в пов'язаний з даним додатком
буфер типу FIFO
BOOL WINAPI UpdateWindow(HWND hw)
Мінімальний 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)
)
Мінімальний 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)
Мінімальний 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))
Мінімальний Win32 додаток
Andrey Gladky
KspDevelop@gmail.co
m 11
 Процедура обробки подій повинна повернути певне 32-бітове
значення, інтерпретація якого також залежить від типу
повідомлення. У більшості випадків, якщо повідомлення успішно
оброблено, процедура повертає значення 0.
 Процедура обробки подій не повинна ігнорувати повідомлення.
Якщо процедура не обробляє якесь повідомлення, вона повинна
повернути його системі для обробки за замовчуванням. Для цього
викликається функція:
LRESULT WINAPI DefWindowProc(HWND hw, UINT msg, WPARAM wp,
LPARAM lp)
Демонстрація
Andrey Gladky
KspDevelop@gmail.co
m 12
Вікна повідомлень
Andrey Gladky
KspDevelop@gmail.co
m 13
MessageBox(HWND hWnd, LPCWSTR lpText, LPCWSTR,
lpCaption, UINT uType)
Andrey Gladky
KspDevelop@gmail.co
m 14
Обробка повідомлень миші

Win api module_1.3

  • 1.
  • 2.
  • 3.
    Мінімальний Win32 додаток AndreyGladky 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 додаток AndreyGladky KspDevelop@gmail.co m 4  Далі віконний клас потрібно зареєструвати в системі:  При успішному завершенні функція повертає цілочисельний код, відповідний рядку-імені класу в загальносистемної таблиці рядків (такий код називається атомом). При помилці повертається 0.  Далі потрібно створити вікно. Викликається функція WORD WINAPI RegisterClass(const WNDCLASS *lpwc) HWND WINAPI CreateWindow()
  • 5.
    Мінімальний Win32 додаток AndreyGladky 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 додаток AndreyGladky 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 додаток AndreyGladky KspDevelop@gmail.co m 7  Якщо клієнтська область головного вікна програми містить об'єкти, промальовані за повідомленням WM_PAINT, має сенс промальовувати ці об'єкти відразу після відображення головного вікна на екрані. Функція UpdateWindow безпосередньо викликає процедуру обробки подій зазначеного вікна з повідомленням WM_PAINT (минаючи чергу повідомлень додатка):  Windows використовує два способи доставки повідомлень процедурі обробки подій вікна:  безпосередній виклик процедури обробки подій (позачергові або невідкладні повідомлення - nonqueued messages);  переміщення повідомлення в пов'язаний з даним додатком буфер типу FIFO BOOL WINAPI UpdateWindow(HWND hw)
  • 8.
    Мінімальний Win32 додаток AndreyGladky 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 додаток AndreyGladky 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 додаток AndreyGladky 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 додаток AndreyGladky KspDevelop@gmail.co m 11  Процедура обробки подій повинна повернути певне 32-бітове значення, інтерпретація якого також залежить від типу повідомлення. У більшості випадків, якщо повідомлення успішно оброблено, процедура повертає значення 0.  Процедура обробки подій не повинна ігнорувати повідомлення. Якщо процедура не обробляє якесь повідомлення, вона повинна повернути його системі для обробки за замовчуванням. Для цього викликається функція: LRESULT WINAPI DefWindowProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp)
  • 12.
  • 13.
    Вікна повідомлень Andrey Gladky KspDevelop@gmail.co m13 MessageBox(HWND hWnd, LPCWSTR lpText, LPCWSTR, lpCaption, UINT uType)
  • 14.