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

// Определения для файла os2.h
#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS

// Файл содержит определения, необходимые
// для любого приложения OS/2
#include <os2.h>

// Этот файл нужен для определения функции sprintf
#include <stdio.h>

// Определение констант для приложения MYWINDOW
#include "mywindow.h"

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

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

// Идентификатор Anchor-block
HAB  hab;

// Идентификатор окна Frame Window - главного окна приложения
HWND hWndFrame;

// Идентификатор окна Client Window
HWND hWndClient;

// Заголовок приложения
CHAR szAppTitle[] = "My First OS/2 Application";

// ==========================================================
// Главная функция приложения 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[] = "MYWINDOW";

  // Инициализация приложения, необходимая для использования
  // функций Presentation Manager
  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
    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);

    // Перед аварийным завершением приложения уничтожаем
    // созданную ранее очередь сообщений и
    // вызываем функцию WinTerminate
    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);

  // Удаляем очередь сообщений и вызываем
  // функцию WinTerminate
  WinDestroyMsgQueue(hmq);
  WinTerminate(hab);

  // Возвращаем управление операционной системе
  return(0);
}

// ==========================================================
// Функция главного окна приложения
// Обрабатывает сообщения, поступающие в очередь приложения
// ==========================================================

MRESULT EXPENTRY
WndProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
  // Временный буфер для подготовки сообщения
  CHAR szMsg[100];

  switch (msg)
  {
    // Обработчик сообщения WM_ERASEBACKGROUND
    // Это сообщение поступает перед перерисовкой
    // внутренней области окна
    case WM_ERASEBACKGROUND:
      return(MRFROMLONG(1L));

    // Обработчик сообщений WM_BUTTON1DOWN и WM_BUTTON2DOWN
    // Эти сообщения поступают, когда пользователь делает
    // в окне приложения щелчок левой и правой кнопкой
    // мыши, соответственно
    case WM_BUTTON1DOWN:
    case WM_BUTTON2DOWN:
    {
      // Определяем координаты курсора мыши и записываем
      // их в виде текстовой строки во временный буфер
      sprintf(szMsg, "(x, y) = (%ld, %ld)",
        SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));

      // Отображаем содержимое временного буфера на экране
      WinMessageBox(HWND_DESKTOP, hWnd,  szMsg,
        "Координаты курсора мыши", 0, MB_INFORMATION | MB_OK);
    }

    // Если наша функция окна не обрабатывает сообщение,
    // его следует обязательно передать фукнции WinDefWindowProc
    default:
      return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  }
}

