Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Программирование для IBM OS/2

© Александр Фролов, Григорий Фролов
Том 25, М.: Диалог-МИФИ, 1993, 286 стр.

[Назад] [Содеожание] [Дальше]

8.2. Приложение BUTTON

Приложение BUTTON создает в своем главном окне две кнопки (рис. 8.1). Если пользователь нажимает на одну из них, на экране появляется сообщение с названием нажатой кнопки.

Рис. 8.1. Главное окно приложения BUTTON

Исходные тексты приложения приведены в листинге 8.1.

Листинг 8.1. Файл button\button.c

// =================================================
// Определения
// =================================================

#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS
#include <os2.h>
#include "button.h"

// Прототип функции окна приложения
MRESULT EXPENTRY WndProc(HWND, ULONG, MPARAM, MPARAM);

// =================================================
// Глобальные переменные
// =================================================

HAB  hab;
HWND hWndFrame;
HWND hWndClient;

// Идентификаторы кнопок
HWND hWndButton1;
HWND hWndButton2;

CHAR szAppTitle[] = "Button Demo";

// =================================================
// Главная функция приложения main 
// =================================================

int main ()
{
  HMQ   hmq;
  QMSG   qmsg;
  BOOL  fRc;

  // Флаги для создания окна Frame Window 
  ULONG flFrameFlags =
    FCF_SYSMENU    | FCF_TITLEBAR       | FCF_MINMAX   |
    FCF_SIZEBORDER | FCF_SHELLPOSITION | FCF_TASKLIST |
    FCF_ICON;

  // Имя класса главного окна
  CHAR  szWndClass[] = "BTNDEMO";

  hab = WinInitialize (0);
  if(hab == NULLHANDLE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка инициализации",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    return(-1);
  }

  // Создаем очередь сообщений
  hmq = WinCreateMsgQueue (hab, 0);
  if(hmq == NULLHANDLE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка при создании очереди сообщений",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    WinTerminate (hab);
    return(-1);
  }

  // Регистрация главного окна приложения
  fRc = WinRegisterClass (hab, szWndClass,
    (PFNWP)WndProc, 0, 0);
  if(fRc == FALSE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка при регистрации класса главного окна",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    WinDestroyMsgQueue (hmq);
    WinTerminate (hab);

    return(-1);
  }

  // Создаем главное окно приложения
  hWndFrame = WinCreateStdWindow  (HWND_DESKTOP,
    WS_VISIBLE ,
    &flFrameFlags, szWndClass, szAppTitle,
    0, 0, ID_APP_FRAMEWND, &hWndClient);
  if(hWndFrame == NULLHANDLE)
  {
    WinMessageBox (HWND_DESKTOP, HWND_DESKTOP,
      "Ошибка при создании главного окна",
      "Ошибка", 0, MB_ICONHAND | MB_OK);
    WinDestroyMsgQueue (hmq);
    WinTerminate (hab);

    return(-1);
  }

  // Запускаем цикл обработки сообщений
  while(WinGetMsg (hab, &qmsg, 0, 0, 0))
    WinDispatchMsg (hab, &qmsg);

  WinDestroyWindow(hWndFrame);
  WinDestroyMsgQueue (hmq);
  WinTerminate (hab);
  return(0);
}

// =================================================
// Функция главного окна приложения
// =================================================

MRESULT EXPENTRY
WndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
  HPS hps;
  RECTL rec;

  switch (msg)
  {
    // Создаем две кнопки
    case WM_CREATE :
    {
      hWndButton1 = WinCreateWindow (hWnd, WC_BUTTON ,
        "Кнопка 1", WS_VISIBLE  | BS_PUSHBUTTON,
        0, 0, 0, 0,
        hWnd, HWND_TOP , BTN1_ID, NULL, NULL);

      hWndButton2 = WinCreateWindow (hWnd, WC_BUTTON ,
        "Кнопка 2", WS_VISIBLE  | BS_PUSHBUTTON,
        0, 0, 0, 0,
        hWnd, HWND_TOP , BTN2_ID, NULL, NULL);

      return FALSE;
    }

    // Изменяем размер и расположение кнопок
    case WM_SIZE :
    {
      WinSetWindowPos (hWndButton1, HWND_TOP ,
        10, 10, 200, 50, 
        SWP _SIZE  | SWP_MOVE  | SWP_ZORDER );

      WinSetWindowPos (hWndButton2, HWND_TOP ,
        10, 70, 200, 50, 
        SWP _SIZE  | SWP_MOVE  | SWP_ZORDER );

      // Перерисовываем окно приложения
      WinInvalidateRect (hWnd, NULL, TRUE);
      return 0;
    }

    case WM_PAINT :
    {
      // Получаем пространство отображения
      hps = WinBeginPaint (hWnd, NULLHANDLE, &rec);

      // Закрашиваем область, требующую обновления
      WinFillRect (hps, &rec, CLR_WHITE);

      // Возвращаем пространство отображения
      WinEndPaint (hps);
      return 0;
    }

    case WM_ERASEBACKGROUND :
      return(MRFROMLONG(1L));

    // Это сообщение поступает в функцию окна,
    // когда пользователь нажимает одну из двух
    // кнопок
    case WM_COMMAND :
    {
      switch (COMMANDMSG(&msg) -> cmd)
      {
        case BTN1_ID:
        {
          WinMessageBox (HWND_DESKTOP, hWnd,
           "Нажата кнопка 1",
           "Сообщение", 0,
           MB_INFORMATION | MB_APPLMODAL |
             MB_MOVEABLE | MB_OK);
          break;
        }

        case BTN2_ID:
        {
          WinMessageBox (HWND_DESKTOP, hWnd,
           "Нажата кнопка 2",
           "Сообщение", 0,
           MB_INFORMATION | MB_APPLMODAL |
             MB_MOVEABLE | MB_OK);
          break;
        }
        default:
          break;
      }
      return 0;
    }
    default:
      return(WinDefWindowProc (hWnd, msg, mp1, mp2));
  }
}

Глобальные переменные

В области глобальных переменных определены переменные hWndButton1 и hWndButton2, в которых хранятся идентификаторы двух созданных приложением кнопок.

Функция main

Функция main не имеет особенностей. Она создает главное окно приложений, очередь сообщений и запускает цикл обработки сообщений.

Функция окна WndProc

Рассмотрим обработку сообщений, поступающих в функцию окна приложения BUTTON.

Сообщение WM_CREATE

Обработчик сообщения WM_CREATE создает две кнопки, пользуясь для этого функцией WinCreateWindow :

hWndButton1 = WinCreateWindow (hWnd, WC_BUTTON ,
  "Кнопка 1", WS_VISIBLE  | BS_PUSHBUTTON,
  0, 0, 0, 0,
  hWnd, HWND_TOP , BTN1_ID, NULL, NULL);
hWndButton2 = WinCreateWindow (hWnd, WC_BUTTON ,
  "Кнопка 2", WS_VISIBLE  | BS_PUSHBUTTON,
  0, 0, 0, 0,
  hWnd, HWND_TOP , BTN2_ID, NULL, NULL);

Первая из этих кнопок имеет идентифкатор BTN1_ID, вторая - BTN2_ID. Идентификаторы окон для этих кнопок записываются, соответственно, в глобальные переменные hWndButton1 и hWndButton2.

Обратите внимание, что для координат и размеров кнопок указаны нулевые значения. Реальные размеры кнопок будут установлены при обработке сообщения WM_SIZE .

Обработчик сообщения WM_CREATE возвращает значение FALSE, разрешая тем самым создание главного окна приложения.

Сообщение WM_SIZE

Обработчик сообщения WM_SIZE изменяет расположение и размеры двух кнопок, используя для этого функцию WinSetWindowPos :

WinSetWindowPos (hWndButton1, HWND_TOP ,
  10, 10, 200, 50, SWP _SIZE  | SWP_MOVE  | SWP_ZORDER );
WinSetWindowPos (hWndButton2, HWND_TOP ,
  10, 70, 200, 50, SWP _SIZE  | SWP_MOVE  | SWP_ZORDER );

После этого содержимое главного окна перерисовывается.

Сообщение WM_PAINT

Единственная задача обработчика сообщения WM_PAINT заключается в закраске внутренней области окна Client Window при изменении размеров главного окна приложения. Для закраски используется функция WinFillRect .

Сообщение WM_COMMAND

Так как наше приложение не имеет меню, обработчик сообщения WM_COMMAND анализирует только идентификатор кнопки, пославшей извещающее сообщение. Этот идентификатор извлекается при помощи макрокоманды COMMANDMSG.

В зависимости от того, какая кнопка была нажата, обработчик сообщения WM_COMMAND выводит на экран то или иное сообщение.

Обратите внимание на параметры функции WinMessageBox , с помощью которой выводится это сообщение:

WinMessageBox (HWND_DESKTOP, hWnd,"Нажата кнопка 1",
  "Сообщение", 0,
  MB_INFORMATION | MB_APPLMODAL | MB_MOVEABLE | MB_OK);

При вызове функции WinMessageBox мы указали флаг MB_APPLMODAL , в результате чего диалоговая панель с сообщением стала модальной в рамках приложения BUTTON. Последнее означает, что работа приложения будет продолжена только после того, как пользователь нажмет расположенную на диалоговой панели кнопку OK.

Указав флаг MB_SYSTEMMODAL , можно создать так называемую системную модальную диалоговую панель . Пока пользователь не завершит работу с этой диалоговой панелью, работа системы Presentation Manager будет приостановлена. Системные модальные диалоговые панели используются, например, для отображения критичных сообщений, когда для продолжения работы системы требуется вмешательство пользователя.

Файл button.h

Файл button.h (листинг 8.2) содержит описание идентификатора главного окна приложения ID_APP_FRAMEWND, а также идентификаторов двух кнопок BTN1_ID и BTN2_ID.

Листинг 8.2. Файл button\button.h

#define ID_APP_FRAMEWND 1
#define BTN1_ID         100
#define BTN2_ID         101

Файл button.rc

В файле button.rc (листинг 8.3) описана пиктограмма приложения BUTTON.

Листинг 8.3. Файл button\button.rc

#include <os2.h>
#include "button.h"
ICON ID_APP_FRAMEWND BUTTON.ICO

Файл button.def

Файл определения модуля button.def приложения BUTTON приведен в листинге 8.4.

Листинг 8.4. Файл button\button.def

NAME        BUTTON   WINDOWAPI
DESCRIPTION 'Button Application (C) Frolov A., 1996'
HEAPSIZE    4096
STACKSIZE   32768
EXPORTS     WndProc
[Назад] [Содеожание] [Дальше]