Александр Чиртик

Программирование в Delphi. Трюки и эффекты


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

окна вручную

      Раз уж речь зашла о приложениях с оконным интерфейсом, то самое время приступить к его реализации средствами Windows API. Итак, чтобы создать и заставить работать окно приложения, нужно выполнить следующие операции.

      1. Зарегистрировать класс окна с использованием функции RegisterClass или RegisterClassEx.

      2. Создать экземпляр окна зарегистрированного ранее класса.

      3. Организовать обработку сообщений, поступающих в очередь сообщений.

      Пример того, как можно организовать регистрацию класса окна, приведен в листинге 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.hb rBackground:= 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

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

      WM_PAINT:

      begin

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

      BeginPaint(hWnd, ps);

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

      EndPaint(hWnd, ps);

      end;

      else

      begin

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

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

      Exit;

      end;

      end;

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

      end;

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

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

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