Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1_Перший крок.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
119.81 Кб
Скачать

Step 3: Цикл чекання повідомлень

Те, що ми викладаємо нижче насправді є двигуном а\всієї програми. Це – цикл чекання і обробки подій

while(GetMessage(&Msg, NULL, 0, 0) > 0)

{

TranslateMessage(&Msg);

DispatchMessage(&Msg);

}

return Msg.wParam;

GetMessage() читає інформацію із черги повідомлень ОС (рух мишкою, натискання клавіш кмишки чи клавіатури , тощо). За одне звернення до gets a message ми отримуємо інформацію про одну (чергову) подію.

TranslateMessage() виділяє додаткову інформацію із події WM_CHAR (у випадку натискання клавіш клавіатури) , вирізняючи подію втоплювання від події відпускання клавіш (WM_KEYUP і WM_KEYDOWN)

DispatchMessage() повертає повідомлення тому вікну, від якого воно отримало повідомлення ( частіше за все, вікну ОС)

Step 4: Віконна процедура

Обробкою подій, які розпізнаються в циклі читання черги подій, обробляються віконною процедурою із наступним стандартним оформленням..

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

switch(msg)

{

case WM_CLOSE:

DestroyWindow(hwnd);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hwnd, msg, wParam, lParam);

}

return 0;

}

В залежності від подій , користувач тут може описати їх обслуговування. За умовчуванням віконна процедура обслуговує тільки такі повідомлення:

WM_CLOSE- поступає у випадку натисканні користувачем кнопки (справа вверху)

Викликом функції DestroyWindow() система посилає повідомлення WM_DESTROY вікну, яке має бути ліквідованим (вікно з хендлом hwnd та всі його вікна-потомки). Для повного завершення прикладної програми потрібно послати в ОС повідомлення WM_QUIT, яке і здійснюється функцією PostQuitMessage(0)

Все, що не передбачено вами в циклі чекання, обробляється за умовчуванням системною функцією DefWindowProc.

Що таке цикл чекання повідомлень

Що таке повідомлення ( a Message)?

Повідомлення – це іменоване значення цілого числа. Якщо ви заглянете до файлу включення windows.h, то там визнайдете таке

#define WM_INITDIALOG 0x0110

#define WM_COMMAND 0x0111

#define WM_LBUTTONDOWN 0x0201

і т.д

І якщо ви хочете, щоб вікно щось виконало, то ви посилаєте йому повідомлення. Звичайно ви повинні передбачити обробку цього повідомлення так як у попередньому прикладі.

Загалом, всяке віконне повідомлення може мати два іменовані (системні) параметри: wParam та lParam. Як правило, wParam має 16 bit, а lParam - 32 bit. Правда, у Win32 вони обидва 32 бітні і не всяке повідомлення їх використовує. Наприклад, повідомлення WM_CLOSE не використовує їх взагалі., в той час як повідомлення WM_COMMAND,яке формується при виборі пункта меню, використовує обидва числа.

Слово wParam містить два 16 розрядних значення HIWORD(wParam) та LOWORD(wParam). У випадку WM_COMMAND iперше містить ознаку меню (галочку вибору), а друге – номер пункта меню. Параметр lParam містить HWND (window handle) того об’єкту керування, від якого поступило повідомлення.

Для посилки повідомлення програмно користуйтесь системними функціями PostMessage() або SendMessage().

PostMessage() поміщає повідомлення в чергу і продовжує подальше виконання програми без затримки. SendMessage()посилає повідомлення до віконної процедури іншого вікна поза чергою і чекає від нього відповіді.

Що таке черга повдомлень

Уявімо собі, що ваша програма оборобляє повідомлення WM_PAINT ( малює щось у вікні). А в цей час ви натиснули якусь клавішу на клавіатурі. Яка може бути подальша поведінка вашої програми?

  • можна перервати малювання і обслужити натискання клавіші;

  • можна продоажити малювання, але при цьому втратити подію натискання.

Система поступає інакше. Вона занесе повідомлення до спеціального буфера(черги) і продовжить малювання, а після закінчення малювання прочитає чергове повідомлення і обслужить його.

Шо таке цикл чекання повідомлень

while(GetMessage(&Msg, NULL, 0, 0) > 0)

{

TranslateMessage(&Msg);

DispatchMessage(&Msg);

}

  1. Цикл викликає функцію GetMessage(), яка переглядає чергу повідомлень і вибирає чергове повідомлення заносячи його до структури Msg.

  2. Якщо повідомлення є (функція повертає додатнє значення) тоді здійснюється його обробка.

  3. Значення із Msg заноситься до функції TranslateMessage(&Msg),яка із події натискання на клавішу клавіатури (якщо це була така подія) виділяє події утоплювання і відпускання клавіші.

  4. Функція DispatchMessage()приймає повідомлення, визначає від якого вікна воно надійшло і та викликає процедуру, відповідальну за обробку цього повідомлення. (вміст віконної процедури і як його може змінювати програміст ми вже розглядали.

Схема роботи циклу чекання зображена на наступному малюнку

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]