Обробка повідомлень Windows та компонентних повідомлень
Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.
Будь-який компонент, як і програма загалом, працює під керуванням Windows1. Ця операційна система надсилає додатку багато повідомлень, пов'язаних з діями користувача або особливостями виконання коду. Більшість повідомлень породжує стандартні події, розглянуті у 9.2. Однак компонент (програма) може визначати нестандартні (користувацькі) повідомлення та пересилати їх іншим компонентам або програмі, подібно до того, як це відбувається з повідомленнями Windows. Крім того, можливо, вам знадобиться самостійно реалізувати перехоплення та обробку повідомлень Windows.
У Delphi визначено також безліч компонентних повідомлень, якими обмінюються компоненти. За допомогою цих повідомлень вони сповіщають одне одного про зміну поточного стану.
У цьому розділі описано, як перехоплювати та обробляти компонентні повідомлення та повідомлення Windows.
9.4.1. Суть повідомлень Windows та їх передача
Повідомлення Windows є такою структурою даних: type TMessage - packed record
Msg: Cardinal; case Integer of 0: (
1 Нагадаю, що у книзі не розглядаються компоненти для ОС Linux. Особливості обробки повідомлень
WParam: Longlnt; LParam: Longlnt; Result: Longlnt); 1: (
Головним полем структури є поле Msg, де передається ідентифікатор повідомлення. У модулі Messages визначено ідентифікатори всіх повідомлень, що діють у 32-розрядних версіях Windows у вигляді констант WM_XXXX. Для них зарезервовані значення типу Cardinal від 0 до 1023 включно. Поля WParam та LParam1 трактуються залежно від ідентифікатора повідомлення. Наприклад, для повідомлення WM_KEY поле WParam містить віртуальний коднатиснутою клавіші, а поле LParam – деяку додаткову інформацію (кількість повторних натискань, скан-код клавіші тощо). Зауважу, що більшість повідомлень Windows у модулі Messages мають спеціалізовані типи TWMXXXX, які містять назви полів, що відповідають їхньому призначенню для цього повідомлення. Так, для повідомлення WM_KEY, пов'язаного з натисканням клавіші, наведено наступний тип TWMKey:
TWMKey = packed record
При маніпуляції мишею виникає повідомлення WM_MOUSE, якому відповідає такий тип:
TWMMouse = packed record
Msg: Cardinal; Keys: Longint; case Integer of 0: (
XPos: Smallint; YPos: Smallint); 1: (
1 Назви полів збережені такими ж, як у Windows 16, в якій поле WParam мало тип Word, a LParam - тип Longlnt.
Підготовлене ядром Windows повідомлення передається методу MainWndProc, який має всі візуальні віконні компоненти. Цей спосіб не обробляє отримане повідомлення. Він створює захищений блок обробки повідомлення і передає повідомлення для подальшої обробки активному компоненту, викликаючи віртуальний метод WndProc, що вказується своєю властивістю WindowProc. Цей метод здійснює аналіз повідомлення та викликає потрібний метод диспетчеризації, який, своєю чергою, викликає оброблювач користувача (рис. 9.1).
Мал. 9.1. Обробка повідомлення Windows
Всі методи WndProc вміють здійснювати обробку призначених для відповідних компонентів подій, а також обробку інших, що замовчується. Зазвичай тіло методу WndProc містить кілька операторів if і один або кілька операторів case, за допомогою яких аналізується поле Msg отриманого повідомлення та викликається відповідний метод диспетчеризації. Якщо не знайдено відповідний метод диспетчеризації, здійснюєтьсязамовчування обробки повідомлення (зазвичай повідомлення просто ігнорується).