Скачать книгу

в очередь сообщений.

      Пример того, как можно организовать регистрацию класса окна, приведен в листинге 2.4.

Листинг 2.4. Регистрация класса окна

      function RegisterWindow():Boolean;

      var

      wcx: WNDCLASSEX;

      begin

      ZeroMemory(Addr(wcx), SizeOf(wcx));

      //Формирование информации о классе окна

      wcx.cbSize := SizeOf(wcx);

      wcx.hInstance := GetModuleHandle(nil);

      wcx.hIcon := LoadIcon(0, IDI_ASTERISK); //Стандартный значок

      wcx.hIconSm := wcx.hIcon;

      wcx.hCursor := LoadCursor(0, IDC_ARROW); //Стандартный указатель

      wcx.hbrBackground := GetStockObject(WHITE_BRUSH); //Серый

      //цвет фона

      wcx.style := 0;

      //..самые важные параметры

      wcx.lpszClassName := 'MyWindowClass'; //Название класса

      wcx.lpfnWndProc := Addr(WindowFunc); //Адрес функции

      //обработки сообщений

      //Регистрация класса окна

      RegisterWindow := RegisterClassEx(wcx) <> 0;

      end;

      Здесь существенным моментом является обязательное заполнение структуры WNDCLASSEX информацией о классе окна. Самой необычной вам должна показаться следующая строка:

      wcx.lpfnWndProc := Addr(WindowFunc); //Адрес функции обработки сообщений

      Здесь мы сохранили адрес функции WindowFunc (листинг 2.5) – обработчик оконных сообщений (называемый также оконной процедурой). После вызова функции RegisterClassEx система запомнит этот адрес и будет вызывать нашу функцию-обработчик каждый раз при необходимости обработать сообщение, пришедшее окну. Простейшая реализация функции WindowFunc приводится в листинге 2.5.

Листинг 2.5. Функция обработки сообщений

      //Функция обработки сообщений

      function WindowFunc(hWnd:HWND; msg:UINT; wParam:WPARAM;

      lParam:LPARAM):LRESULT; stdcall;

      var

      ps: PAINTSTRUCT;

      begin

      case msg of

      WM_CLOSE:

      if (hWnd = hMainWnd) then

      PostQuitMessage(0); //При закрытии окна – выход

      WM_PAINT:

      begin

      //Перерисовка содержимого окна

      BeginPaint(hWnd, ps);

      TextOut(ps.hdc, 10, 10, 'Текст в окне', 12);

      EndPaint(hWnd, ps);

      end;

      else

      begin

      //Обработка по умолчанию

      WindowFunc := DefWindowProc(hWnd, msg, wParam, lParam);

      Exit;

      end;

      end;

      WindowFunc := S_OK; //Сообщение обработано

      end;

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

      Обратите особое внимание на прототип этой функции: типы возвращаемых значений, типы параметров и способ вызова функции должны быть именно такими, как в листинге 2.5. Возвращаемое значение зависит от конкретного сообщения. Чаще всего это SOK (константа, равная 0) в случае успешной обработки сообщения.

      Далее в листинге 2.6 приводится часть программы, собственно использующая регистрацию, создание окна, а также организующая обработку сообщений для созданного окна.

Листинг 2.6. Регистрация и создание окна. Цикл обработки сообщений

      program Window;

      uses

      Windows, Messages;

      {$R *.res}

      var

      hMainWnd: HWND;

      mess: MSG;

      …

      begin

      //Создание окна

      if not RegisterWindow() then Exit;

      hMainWnd := CreateWindow(

      'MyWindowClass', //Имя класса окна

      'Главное окно', //Заголовок окна

      WS_VISIBLE

Скачать книгу