Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Visual1.doc
Скачиваний:
8
Добавлен:
07.03.2016
Размер:
4.35 Mб
Скачать

2.2. Цикли обробки повідомлень

Серцем будь-який Windows-програми є цикл обробки повідомлень (Message Loop), який практично завжди знаходиться у функції WinMain(). Ця функція в Windows-додатках відіграє ту ж роль, що і функція Main() в DOS-додатках, - її викликає операційна система відразу ж після завантаження програми в пам'ять. Програмісти тепер можуть не відволікатися на набирання тексту WinMain(), оскільки це зробить AppWizard. Але це не означає, що сама функція зникла. Текст типової функції WinMain() має наступний вид:

int APIENTRY WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR IpCmdLine,

int nCmdShow)

{

MSG msg;

if(!InitAppIication(hInstance))

return (FALSE);

if(!InitInstance(hInstance, nCmdShow))

return (FALSE);

while(GetMessage(&msg, NULL, 0, 0)) {

TranslateMessage(&msg);

DispatchMessage(&msg);

}

return (msg.wParam);

}

У С-програмах для Windows, схожих на цю, функція InitAppIication() викликає RegisterWindow(), a InitInstance() - CreateWindow(). Потім настає черга циклу обробки повідомлень. Він являє собою типову циклічну конструкцію С на базі оператора while, усередині якої викликається функція GetMessage(). Ця функція API заповнює msg кодом повідомлення, яке операційна система розподілила для цього додатка, і майже завжди повертає TRUE. Таким чином, цикл повторюється знову і знову до тих пір, поки працює програма. Єдиний варіант, при якому GetMessage() повертає FALSE, - отримання повідомлення WM_QUIT.

При роботі з повідомленнями, що надходять з клавіатури, деяку частину попередньої обробки бере на себе функція API TranslateMessage(). Її призначення полягає в наступному. Прикладної частини програми немає діла до повідомлень на кшталт "Натиснуто клавішу <А>" і "Звільнено клавішу <А>". Прикладну частину, в кінці кінців, цікавить тільки те, яку літеру (символ) ввів користувач, тобто її цілком задовольнить повідомлення "Введено символ А". Ось це перетворення - кілька повідомлень про деталі процесу в одне повідомлення про його суть - і виконує функція TranslateMessage(). Вона перехоплює повідомлення WM_KEYDOWN і WM_KEYUP і замість них посилає повідомлення WM_CHAR. Звичайно, якщо користуватися бібліотекою MFC, то такі дрібниці, як введення символу А, проходять, як правило, повз вас. Користувач вводить текст в текстовому полі або в інший елемент керування, і турбота програміста - витягти введений текст з цього об'єкта після того, як користувач клацне на ОК. Як був організований прийом символів з клавіатури, тепер вже не наша справа. Таким чином, на функцію TranslateMessage() можна не звертати особливої уваги.

Функція API DispatchMessage() викликає, у свою чергу, функцію WndProc() того вікна, для якого предназначено повідомлення. Типова функція WndProc() у, С-програмі для Windows являє собою величезний оператор switch з окремими case для кожного повідомлення, який додаток має намір самостійно обробляти. Текст її приведено далі:

LONG API ENTRY MainWndProc( HWND hwnd, // Дескриптор вікна.

UINT msg, // Тип повідомлення.

UINT wParam, // Додаткова інформація.

LONG lParam) // Додаткова інформація.

switch (msg){

case WM_MOUSEMOVE: {

// Обробка переміщення миші.

break;

case WM_LBUTTONDOWN: {

// Обробка клацання лівою кнопкою миші.

break;

case WM_RBUTTONDOWN: {

// Обробка клацання правою кнопкою миші.

break;

case WM_PAINT:

// Перемалювати вікно.

break;

case WM_DESTROY: // Повідомлення: вікно буде знищено.

PostQuitMessage(0);

return 0;

break;

default:

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

}

return (0);

}

Ви, звичайно, можете собі уявити, якої довжини досягає подібна функція в більш-менш порядному додатку. Супроводжувати таку програму дуже важко. MFC вирішує проблему в такий спосіб – інформація про повідомлення, які мають оброблятися, розташована ближче до функцій, які і повинні виконувати обробку. Таким чином, відпадає необхідність у величезних операторах switch, в яких зосереджено розподіл повідомлень.

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