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

#define INCL_WIN
#define INCL_GPI
#define INCL_WINDIALOGS

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

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

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

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

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

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

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

// Идентификатор меню Edit
HWND hwndEditMenu;

// Идентификатор меню верхнего уровня
HWND hwndMenu;

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

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

  MENUITEM mi;

  switch (msg)
  {
    case WM_CREATE:
    {
      HWND hwndSystemMenu;
      HWND hwndSystemSubMenu;
      SHORT sSysMeniID;

      // ---------------------------------------------
      // Добавляем строку к системному меню
      // ---------------------------------------------

      // Определяем идентификатор окна системного меню
      hwndSystemMenu = WinWindowFromID(
        WinQueryWindow(hWnd, QW_PARENT), FID_SYSMENU);

      // Определяем идентификатор системного меню
      sSysMeniID = (SHORT)WinSendMsg(hwndSystemMenu,
        MM_ITEMIDFROMPOSITION, MPFROMSHORT(0), NULL);

      // Определяем характеристики системного меню
      WinSendMsg(hwndSystemMenu, MM_QUERYITEM,
        MPFROMSHORT(sSysMeniID), MPFROMP(&mi));

      // Идентификатор окна временного системного меню
      hwndSystemSubMenu = mi.hwndSubMenu;

      // Заполняем структуру для разделительной линии
      mi.afStyle = MIS_SEPARATOR;
      mi.afAttribute = 0;
      mi.hwndSubMenu = 0;
      mi.hItem = 0;
      mi.id = -1;
      mi.iPosition = MIT_END;

      // Добавляем разделительную линию
      WinSendMsg(hwndSystemSubMenu, MM_INSERTITEM,
        MPFROMP(&mi), NULL);

      // Заполняем структуру для добавляемой строки
      mi.afStyle = MIS_TEXT;
      mi.id = IDM_HELP_ABOUT;

      // Добавляем строку Product Information
      WinSendMsg(hwndSystemSubMenu, MM_INSERTITEM,
        MPFROMP(&mi), "Product Information...");

      // ---------------------------------------------
      // Добавляем временное меню Edit
      // ---------------------------------------------

      // Получаем идентификатор окна меню
      // верхнего уровня
      hwndMenu = WinWindowFromID(
        WinQueryWindow(hWnd, QW_PARENT), FID_MENU);

      // Создаем пустое меню Edit
      hwndEditMenu = WinCreateMenu(HWND_OBJECT, NULL);

      // Присваиваем меню Edit идентификатор IDM_EDIT
      WinSetWindowUShort(hwndEditMenu, QWS_ID, IDM_EDIT);

      // Добавляем строки в меню
      mi.iPosition = MIT_END;
      mi.afStyle = MIS_TEXT;
      mi.afAttribute = 0;
      mi.hwndSubMenu = 0;
      mi.hItem = 0;
      mi.id = IDM_EDIT_UNDO;

      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Undo");

      mi.id = IDM_EDIT_REDO;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Redo");

      mi.id = IDM_EDIT_CUT;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "Cu~t");

      mi.id = IDM_EDIT_COPY;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Copy");

      mi.id = IDM_EDIT_PASTE;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Paste");

      mi.id = IDM_EDIT_CLEAR;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "C~lear");

      // Добавляем разделительную линию
      mi.afStyle = MIS_SEPARATOR;
      mi.id = -1;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Duplicate");

      // Добавляем еще две строки
      mi.afStyle = MIS_TEXT;
      mi.id = IDM_EDIT_DUPLICATE;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Duplicate");

      mi.id = IDM_EDIT_SELECTALL;
      WinSendMsg(hwndEditMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Select all");

      // Добавляем меню Edit в меню верхнего уровня
      mi.iPosition = 1;
      mi.afStyle = MIS_TEXT | MIS_SUBMENU;
      mi.afAttribute = 0;
      mi.id = IDM_EDIT;
      mi.hwndSubMenu = hwndEditMenu;

      WinSendMsg(hwndMenu, MM_INSERTITEM,
        MPFROMP(&mi), "~Edit");

      return FALSE;
    }

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

    // Сообщение 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,
             "Приложение MenuMod, (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));
    }

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

