Віконна функція і способи передачі повідомлень вікнам

Віконна функція викликається, коли в структуру mess потрапляє чергове повідомлення, вибране з вхідної черги Віконна функція повинна проаналізувати код повідомлення і обробити його З кожним вікном звязується своя віконна функція У програмі на С необхідно описати прототипи все віконних функцій, так як це прикладні функції з довільними іменами, а не системні, чиї прототипи описані в WINUSERH Незважаючи на те, що імена віконних функцій довільні, кількість і типи її параметрів, а також тип значення в Windows жорстко фіксовані Опис віконної функції на С має вигляд:

LRESULT CALIiBACK WndProc (HWND hwnd,UINT m,

WPARAM wParam,LPARAM lParam) { switch(mess)

{ case WM_DESTROY: / / Якщо користувач / / завершив додаток PostQuitMessage(0) return 0 / / Повернення в Windows default: return(DefWindowProc(hwnd,mess,wParam,lParam)) / / Інші повідомлення обробляємо функцією / / за замовчуванням

} / / Кінець switch} / / кінець віконної функції

Описувач CALLBACK віконної функції еквівалентний описателю STDCALL, визначає угоду звязки викликає і викликається функцій У Win32 практично для всіх функцій діє угода, за якою параметри функції при її виклику поміщаються в стек у зворотному порядку, тобто в глибині стека поміщається останній параметр, а на верхівці стека перший Витягує їх з стека сама функція, по прототипам опису заголовка функції легко обчислити кількість байтів, займаних параметрами Реальне звільнення памяті в стеку здійснюється командою ret n

Розглянемо структуру віконної функції Вона отримує 4 парамет-ра Перший параметр hwnd являє собою дескриптор вікна, якому призначено дане повідомлення Цей дескриптор потрібен при обробці повідомлень, наприклад, у тих випадках, якщо на базі одного класу вікна створюється кілька вікон, а оскільки віконна функція є спільною для класу, то аналіз дескриптора вікна дозволить ідентифікувати, в яке конкретно вікно прийшло повідомлення

Другий параметр m визначає код надійшло повідомлення Так як повідомлень багато, то за його кодом визначається і виконується конкретна гілка оператора switch в тілі віконної функції Однак реально в програмі потрібно обробляти не всі вступники повідомлення Для того щоб програміст міг включити у віконну функцію обробку тільки своїх повідомлень, в Windows передбачена функ-ція DefWindowProc, яка обробляє практично всі повідомлення, за винятком повідомлення WMDESTROY про знищення вікна Тому в простому випадку у віконній функції необхідно реалізувати обробку тільки цього повідомлення Розглянемо, як це реалізується

Користувач може закрити вікно різними способами, проте у всіх випадках Windows генерує повідомлення WMDESTROY, яка направляється не в чергу потоку, а відразу передається віконної функції При обробці WMDESTROY у віконній функції перед викликом функції PostQuitMessage можна звільнити створені ресурси, память, закрити файли і тп У найпростішому випадку можна вивести на екран попереджувальне повідомлення У мінімальній віконної функції ніяких дій не передбачено, відразу викликається функ-ція PostQuitMessage, генеруюча повідомлення WMQUIT, яке надходить в чергу програми Це повідомлення необхідно для того, щоб функція GetMessage завершилася з false, припинивши тим самим цикл обробки повідомлень

З вищевикладеного випливає, що віконна функція може отримати повідомлення як з черги потоку, так і безпосередньо Реалізують ці механізми передачі відповідно API-функції PostMes-sage і SendMessage

Функція PostMessage поміщає повідомлення в чергу повідомлень вікна із зазначеним дескриптором і повертає управління Якщо повідомлення поміщено в чергу, то функція повертає TRUE, інакше FALSE Вибрані повідомлення з черги буде в циклі обробки повідомлень

Функція SendMessage здійснює безпосередню передачу повідомлення віконної функції Відмінність SendMessage від PostMessage полягає в тому, що SendMessage викликає віконну функцію і повертає управління тільки після обробки повідомлення

Якщо в додатку деякі повідомлення обробляються дуже повільно (наприклад, для обробки потрібно один або кілька циклів), то під час цієї обробки створюється ефект зависання програми Для того щоб під час довгої обробки перевірити, чи є

Чи в черзі потоку повідомлення, використовується функція PeekMessage, практично ідентична GetMessage

PeekMessage має 5 параметрів, перші 4 з яких збігаються з параметрами GetMessage:

– адреса структури mess, в яку надходить взяте з черги повідомлення

– дескриптор вікна, чиї повідомлення будуть оброблені

– мінімальний і максимальний номера фільтровану повідомлень

– прапор видалити повідомлення, що вказує видаляти чи повідомлення з черги після вибірки (PMNOREMOVE залишити в черзі, РМ REMOVE видалити з черги)

Тоді при повільній обробці подій рекомендується вставити фрагмент:

if (PeekMessage(&ampmess,NULL,0,0,PM_REMOVE)) DispatchMessage(&ampmess)

Джерело: Сучкова, ЛІ Win32 API: основи програмування: навчальний посібник / ЛІ Сучкова АлтГТУ ім ШІ Ползунова -Барнаул, АлтГТУ, 2010 138 с, іл

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*