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

#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include "textout.h"

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

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

HAB  hab;
HWND hWndFrame;
HWND hWndClient;

CHAR szAppTitle[] = "TextOut 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[] = "TEXTOUT";

  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)
{
  CHAR szMsg[100];
  int nMsgSize;
  HPS hps;
  POINTL ptl;
  RECTL rec;

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

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

      // Рисуем текстовую строку, начиная с точки,
      // имеющей координаты (10, 10)
      ptl.x = 10L;
      ptl.y = 10L;
      GpiCharStringAt(hps, &ptl, 10, "Hello, PM!");

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

    // Позволяем окну Frame Window стереть содержимое
    // окна Client Window
    case WM_ERASEBACKGROUND:
      return(MRFROMLONG(1L));

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

    // Если пользователь сделал щелчок левой клавишей
    // мыши в окне приложения, в месте расположения
    // курсора мыши отображаем координаты этого курсора
    case WM_BUTTON1DOWN:
    {
      // Получаем пространство отображения
      hps = WinGetPS(hWnd);

      // Определяем координаты курсора мыши и записываем
      // их в виде текстовой строки во временный буфер
      sprintf(szMsg, "(x, y) = (%ld, %ld)",
        SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));

      // Определяем координаты точки для вывода текста
      ptl.x = SHORT1FROMMP(mp1);
      ptl.y = SHORT2FROMMP(mp1);

      // Определяем размер текстовой строки
      nMsgSize = strlen(szMsg);

      // Рисуем текстовую строку
      GpiCharStringAt(hps, &ptl, nMsgSize, szMsg);

      // Освобождаем пространство отображения
      WinReleasePS(hps);
      return 0;
    }

    default:
      return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  }
}

