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

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

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

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

HAB  hab;
HWND hWndFrame;
HWND hWndClient;

// Идентификаторы регуляторов
HWND hWndCirc1;
HWND hWndCirc2;
HWND hWndCirc3;

// Компоненты цвета
SHORT sColorR = 255, sColorG = 255, sColorB = 255;

CHAR szAppTitle[] = "Slider 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[] = "SLIDERDEMO";

  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:
    {
      // Создаем регулятор красного цвета
      hWndCirc1 = WinCreateWindow(hWnd,
        WC_CIRCULARSLIDER,
        "Красный", WS_VISIBLE, 0, 0, 0, 0,
        hWnd, HWND_TOP, CIRCSLD1_ID, NULL, NULL);

      // Устанавливаем диапазон изменения значений
      WinSendMsg(hWndCirc1, CSM_SETRANGE,
        MPFROMLONG(0L), MPFROMLONG(255L));

      // Устанавливаем шаг для изменения позиции
      // и шаг размещения меток
      WinSendMsg(hWndCirc1, CSM_SETINCREMENT,
        MPFROMLONG(10L), MPFROMLONG(2L));

      // Устанавливаем начальное значение
      WinSendMsg(hWndCirc1, CSM_SETVALUE,
        MPFROMLONG(255L), NULL);

      // Создаем регулятор зеленого цвета
      // и настраиваем его параметры
      hWndCirc2 = WinCreateWindow(hWnd,
      WC_CIRCULARSLIDER,
        "Зеленый", WS_VISIBLE, 0, 0, 0, 0,
        hWnd, HWND_TOP, CIRCSLD2_ID, NULL, NULL);

      WinSendMsg(hWndCirc2, CSM_SETRANGE,
        MPFROMLONG(0L), MPFROMLONG(255L));

      WinSendMsg(hWndCirc2, CSM_SETINCREMENT,
        MPFROMLONG(10L), MPFROMLONG(2L));

      WinSendMsg(hWndCirc2, CSM_SETVALUE,
        MPFROMLONG(255L), NULL);

      // Создаем регулятор синего цвета
      // и настраиваем его параметры
      hWndCirc3 = WinCreateWindow(hWnd, WC_CIRCULARSLIDER,
        "Синий", WS_VISIBLE, 0, 0, 0, 0,
        hWnd, HWND_TOP, CIRCSLD3_ID, NULL, NULL);

      WinSendMsg(hWndCirc3, CSM_SETRANGE,
        MPFROMLONG(0L), MPFROMLONG(255L));

      WinSendMsg(hWndCirc3, CSM_SETINCREMENT,
        MPFROMLONG(10L), MPFROMLONG(2L));

      WinSendMsg(hWndCirc3, CSM_SETVALUE,
        MPFROMLONG(255L), NULL);

      return FALSE;
    }

    // Изменяем размер и расположение регуляторов
    case WM_SIZE:
    {
      WinSetWindowPos(hWndCirc1, HWND_TOP,
      0, 0, 150, 150, SWP_SIZE | SWP_MOVE | SWP_ZORDER);

      WinSetWindowPos(hWndCirc2, HWND_TOP,
      150, 0, 150, 150, SWP_SIZE | SWP_MOVE | SWP_ZORDER);

      WinSetWindowPos(hWndCirc3, HWND_TOP,
      300, 0, 150, 150, SWP_SIZE | SWP_MOVE | SWP_ZORDER);

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

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

      // Переключаем таблицу цветов в режим RGB
      GpiCreateLogColorTable(hps,
        LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL);

      // Закрашиваем область, требующую обновление
      WinFillRect(hps, &rec,
        (ULONG)sColorR << 16 |
        (ULONG)sColorG << 8  | (ULONG)sColorB);

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

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

    case WM_CONTROL:
    {
      // Сообщение пришло от красного регулятора
      if(SHORT1FROMMP(mp1) == CIRCSLD1_ID)
      {
        // Выделяем код извещения
        if(SHORT2FROMMP(mp1) == CSN_CHANGED)
        {
           // Устанавливаем новое значение цвета
           sColorR = (SHORT)mp2;

           // Перерисовываем окно
           WinInvalidateRect(hWnd, NULL, TRUE);
        }
      }

      // Сообщение от зеленого регулятора
      else if(SHORT1FROMMP(mp1) == CIRCSLD2_ID)
      {
        if(SHORT2FROMMP(mp1) == CSN_CHANGED)
        {
           sColorG = (SHORT)mp2;
           WinInvalidateRect(hWnd, NULL, TRUE);
        }
      }

      // Сообщение от синего регулятора
      else if(SHORT1FROMMP(mp1) == CIRCSLD3_ID)
      {
        if(SHORT2FROMMP(mp1) == CSN_CHANGED)
        {
           sColorB = (SHORT)mp2;
           WinInvalidateRect(hWnd, NULL, TRUE);
        }
      }
      return 0;
    }
    default:
      return(WinDefWindowProc(hWnd, msg, mp1, mp2));
  }
}

