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

#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS

#include <os2.h>
#include <stdio.h>
#include "menuapp.h"

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

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

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

// Идентификатор окна Frame Window
HWND hWndFrame;

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

// Заголовок приложения
CHAR szAppTitle[] = "Menu Demo Application";

// Идентификатор временного меню
HWND    hwndPopupMenu;

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

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

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

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

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

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

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

  USHORT  usItemId; // идентификатор меню
  HWND    hwndMenu; // идентификатор окна меню

  switch (msg)
  {
    case WM_ERASEBACKGROUND:
      return(MRFROMLONG(1L));

    // Выполняем инициализацию главного меню приложения
    case WM_INITMENU:
    {
      // Идентификатор меню
      usItemId = SHORT1FROMMP(mp1);

      // Идентификатор окна меню
      hwndMenu = HWNDFROMMP(mp2);

      // В меню File блокируем строки New и Open
      if(usItemId == IDM_FILE)
      {
        WinEnableMenuItem(hwndMenu, IDM_FILE_NEW,  FALSE);
        WinEnableMenuItem(hwndMenu, IDM_FILE_OPEN, FALSE);
      }

      // В меню Edit блокируем строки Undo и Redo
      else if(usItemId == IDM_EDIT)
      {
        WinEnableMenuItem(hwndMenu, IDM_EDIT_UNDO, FALSE);
        WinEnableMenuItem(hwndMenu, IDM_EDIT_REDO, FALSE);
      }
      return(WinDefWindowProc(hWnd, msg, mp1, mp2));
    }

    // Сообщение WM_COMMAND поступает в функцию окна,
    // кодгда пользователь выбирает одну из строк меню
    case WM_COMMAND:
    {
      // Анализируем код строки меню
      switch(LOUSHORT(mp1))
      {
        case IDM_FILE_NEW:
        case IDM_FILE_OPEN:
        case IDM_FILE_SAVE:
        case IDM_FILE_SAVEAS:

        case IDM_EDIT_UNDO:
        case IDM_EDIT_REDO:
        case IDM_EDIT_CUT:
        case IDM_EDIT_COPY:
        case IDM_EDIT_PASTE:
        case IDM_EDIT_CLEAR:
        case IDM_EDIT_DUPLICATE:
        case IDM_EDIT_SELECTALL:

        case IDM_OPTIONS_FONT_NORMAL:
        case IDM_OPTIONS_FONT_BOLD:
        case IDM_OPTIONS_FONT_ITALIC:
        case IDM_OPTIONS_FONT_UNDERLINE:
        case IDM_OPTIONS_PARA_LEFT:
        case IDM_OPTIONS_PARA_CENTER:
        case IDM_OPTIONS_PARA_RIGHT:
        case IDM_OPTIONS_PARA_JUSTIFY:

        case IDM_HELP_INDEX:
        case IDM_HELP_GENERAL:
        case IDM_HELP_USING:
        case IDM_HELP_KEYS:
        {
           WinMessageBox(HWND_DESKTOP, hWnd,
             "Функция не реализована",
             szAppTitle, 0, MB_INFORMATION | MB_OK);
          break;
        }

        case IDM_HELP_ABOUT:
        {
           WinMessageBox(HWND_DESKTOP, hWnd,
             "Приложение MenuApp, (C) Frolov A., 1996",
             szAppTitle, 0, MB_INFORMATION | MB_OK);
          break;
        }

        // Если из меню File выбрана строка Exit,
        // завершаем работу приложения
        case IDM_FILE_EXIT:
        {
           WinPostMsg(hWnd, WM_QUIT, 0L, 0L);
           break;
        }
      }
      return(WinDefWindowProc(hWnd, msg, mp1, mp2));

    }

    // В процессе инициализации главного окна приложения
    // загружаем временное меню и определяем идентфикатор
    // его окна
    case WM_CREATE:
    {
      hwndPopupMenu = WinLoadMenu(hWnd,
        NULLHANDLE, POPUP_MENU);
      return FALSE;
    }

    // Перед уничтожением главного окна приложения
    // уничтожаем окно временного меню
    case WM_DESTROY:
    {
      WinDestroyWindow(hwndPopupMenu);
      break;
    }

    // Если пользователь сделал в окне приложения щелчок
    // правой клавишей мыши, отображаем временное меню
    case WM_BUTTON2DOWN:
    {
      WinPopupMenu(hWnd, hWnd, hwndPopupMenu,
        SHORT1FROMMP(mp1), SHORT2FROMMP(mp1),
        IDM_FILE_NEW,
        PU_POSITIONONITEM | PU_HCONSTRAIN | PU_VCONSTRAIN |
        PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 | PU_KEYBOARD);

      return 0;
    }

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

