4.1.8.СООБЩЕНИЯ И ИХ ОБРАБОТКА В СИСТЕМЕ WINDOWS

Сообщения Windows обрабатываются оконной функцией. Типы сообщений представляются 32-разрядными словами. Для идентификации этих чисел применяются макроимена. Наиболее часто используются следующие макроимена сообщений:

WM_CHAR              — нажата клавиша;

WM_PAINT             — запрос на перерисовку окна;

WM_LBUTTONDOWN       — нажата левая кнопка мыши;

WM_RBUTTONDOWN       — нажата правая кнопка мыши;

WM_COMMAND           — выбрана команда меню;

WM_TIMER             — истечение заданного интервала времени.

Каждое сообщение имеет два 32-разрядных параметра типов WPARAM и LPARAM. Обработку сообщений выполняет оконная функция, имеющая четыре параметра: дескриптор окна, сообщение и два указанных выше параметра.

Для доступа к младшему и старшему словам 32-битного двойного слова применяются функции LOWORD и HIWORDНапример, операции

x = LOWORD(lParam);

y = HIWORD(lParam);

записывают в (x, y) координаты курсора мыши в случаях обработки сообщения о нажатии левой или правой кнопки мыши.

Обработка нажатия клавиши. Для сообщения WM_CHAR параметр wParam содержит ASCII – код нажатой клавиши, LOWORD(lParam) – количество повторов, генерируемых при удержании клавиши в нажатом состоянии, HIWORD(lParam) содержит следующую информацию, определенную значениями битов:

     151 – клавиша отпущена, 0 – нажата;

     14:  устанавливается, если клавиша уже была нажата перед посылкой сообщения;

     13:  дополнительно нажата клавиша  [ALT];

  12-9:  используется системой;

       8:  нажата дополнительная или функциональная часть клавиатуры;

    7-0:  scan – код клавиши.

Для того, чтобы добавить в написанный выше каркас приложения обработку события WM_CHAR, определим массив символов для ввода и подключим библиотеки обработки строки и вывода на экран:

#include <string.h>

#include <stdio.h>

char str[80] = “ ”;     // буфер для строки ввода

Добавив обработку события WM_CHAR, получаем следующую оконную функцию:

LRESULT CALLBACK WindowFunc(HWND hwnd,

                            UINT message,

                            WPARAM wParam,

                            LPARAM lParam)

{

  HDC hdc;

  switch(message)

  {

case WM_CHAR:

      hdc = GetDC(hwnd);     // получить контекст устройства

      TextOut(hdc, 1, 1, “ “, 2);  // стереть старый символ

      sprintf(str, “%c”, (char)wParam);  // записать в буфер новый символ

      TextOut(hdc, 1, 1, str, strlen(str));    // вывести на экран

      ReleaseDC(hwnd, hdc);  // освободить контекст устройства

      break;

case WM_DESTROY:

      PostQuitMessage(0);     // сообщение о завершении

      break;

    default:      // обработка остальных сообщений

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

  }

  return 0;

}

Обработка запроса на перерисовку окна. Если нажать кнопку минимизации окна, а затем вновь распахнуть окно, то символы, записанные в окне с помощью TextOut(), будут потеряны. Система Windows, как правило, не запоминает содержимое окна, но каждый раз, когда нужно перерисовать окно, она посылает оконной функции сообщение WM_PAINT.

В некоторых случаях при перемещении и при изменении размеров окна система сохраняет и перерисовывает содержимое окна, но это не касается случая, когда окно минимизируется или перекрывается другим окном, а потом делается попытка восстановить его в исходное состояние. Для того, чтобы обрабатывать сообщение WM_PAINT, добавим соответствующий этому сообщению случай в оператор switch функции окна:

case WM_PAINT:

  hdc = BeginPaint(hwnd, &paintstruct);  // получить DC

  TextOut(hdc, 1, 1, str, strlen(str));

  EndPaint(hwnd, &paintstruct);    // освободить DC

  break;

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

struct PAINTSTRUCT

{

  HDC hdc;  // дескриптор DC

  BOOL fErase;    // true, если перерисовывается заполнение окна

  RECT rcPaint;   // координаты области перерисовки

  BOOL fRestore, fIncUpdate; // резерв

  BYTE rgbReserved[32]; // резерв

}

Здесь тип RECT описывает структуру

struct RECT

{

  LONG left, top, right, bottom;

}

Для обработки сообщения WM_PAINT добавим определение