Приложение MENUAPP
В приложении MENUAPP мы создадим стандартное меню верхнего уровня, показанное на рис. 3.5.
Рис. 3.5. Стандартное меню верхнего уровня в приложении MENUAPP
Временное меню Options, показанное на рис. 3.6, демонстрирует использование стилей меню MIS_BREAKSEPARATOR и MIS_STATIC , а также атрибута строки меню MIA_FRAMED .
Рис. 3.6. Временное меню Options
Если в окне Client Window сделать щелчок правой клавишей мыши, около курсора появится плавающее меню, которое в точности повторяет временное меню File (рис. 3.7).
Рис. 3.7. Плавающее меню, повторяющее временное меню File
Исходный текст приложения MENUAPP представлен в листинге 3.1.
Листинг 3.1. Файл menuapp\menuapp.c
// =================================================== // Определения // ===================================================
#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)); }