Microsoft Visual C++ и MFC. Программирование для Windows 95 и Windows NT. Часть 2 - Александр Фролов
Шрифт:
Интервал:
Закладка:
// Блокируем или разблокируем строку Process меню Mission
pCmdUI->Enable(bEnable);
}
//============================================================
// Метод OnUpdateConstruct класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnUpdateConstruct(CCmdUI* pCmdUI) {
// Устанавливаем или снимаем пометку
// строки Construction меню Mission
pCmdUI->SetRadio(bRadio);
}
//============================================================
// Метод OnUpdateDisable класса CMultiMenuWindow
//============================================================
void CMultiMenuWindow::OnUpdateDisable(CCmdUI* pCmdUI) {
// Устанавливаем или удаляем пометку
// у строки Disable меню Menu
pCmdUI->SetCheck(nCheck);
}
Создайте новый файл ресурсов и включите его в проект под именем MultiMenu.rc. Включите в него два меню, присвоив им идентификаторы IDR_RESTRICT_MENU и IDR_FULL_MENU.
Введите строки этих меню в соответствии с представленным нами файлом ресурсов (листинг 3.2). Для всех строк меню введите их описания. Они будут записаны в файл ресурсов как строковые ресурсы, имеющие одинаковые идентификаторы со строками меню.
Добавьте в файл ресурсов строку Ready, выбрав для нее идентификатор AFX_IDS_IDLEMESSAGE. Эта строка будет отображаться в панели состояния во время “бездействия” приложения.
Включите в файл ресурсов таблицу акселераторов, состоящую из трех команд: ID_MENU_DISABLE, ID_MISSION_PROCESS и ID_FILE_EXIT. Присвойте им комбинации клавиш <Ctrl+D>, <Ctrl+P> и <Ctrl+E> соответственно.
Листинг 3.3. Файл resource.h//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by MultiMenu.rc
//
#define IDR_RESTRICT_MENU 106
#define IDR_FULL_MENU 107
#define IDR_ACCELERATOR 108
#define ID_FILE_EXIT 40009
#define ID_MISSION_PROCESS 40013
#define ID_HELP_HELPINDEX 40014
#define ID_HELP_CONTEXTHELP 40015
#define ID_HELP_SYSTEMINFO 40016
#define ID_MISSION_CONSTRUCT 40017
#define ID_MENU_RESTRICT 40019
#define ID_MENU_FULL 40020
#define ID_MENU_DISABLE 40025
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_COMMAND_VALUE 40027
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Постройте приложение MultiMenu и запустите его. На экране появится окно приложения с главным меню и панелью состояния (рис. 3.4).
В панели состояния расположен один индикатор. В нем отображается подсказка о выбранной строке меню приложения или системного меню, а если приложение “бездействует” – строка Ready.
Рис. 3.4. Приложение MultiMenu
Сразу после запуска приложения MultiMenu используется меню с идентификатором IDR_FULL_MENU. Если вы выберите из меню Menu строку Restrict, то меню приложения будет заменено на меню IDR_RESTRICT_MENU. Это сокращенный вариант меню IDR_FULL_MENU, в котором отсутствуют некоторые строки, а строка Process перенесена из меню Mission в меню File.
Различные строки меню IDR_FULL_MENU и IDR_RESTRICT_MENU иллюстрируют режимы отображения строк меню. Так, при выборе из меню Menu строки Disable, блокируется строка Process в меню Mission. Около строки Disable при этом отображается символ √ (рис. 3.3). Чтобы снять блокировку, выберите строку Disable из меню Menu еще раз. Символ √ также исчезнет.
При выборе строки Process из меню Mission на экране появляется сообщение. Когда строка Process заблокирована, выбрать ее невозможно.
Если вы выберите из меню Mission строку Construction, то она будет выделена символом •. Повторный выбор этой строки снимает с нее выделение.
Чтобы завершить работу приложения MultiMenu, можно выбрать из меню File строку Exit или выбрать из системного меню приложения строку Close. Все остальные строки меню приложения не работают и заблокированы.
Для ускорения выбора некоторых команд из меню приложения можно воспользоваться клавишами акселерации. В программе определены три такие комбинации.
Комбинация клавиш Соответствующая строка меню <Ctrl+D> Строка Disable из меню Menu <Ctrl+P> Строка Process из меню Mission или из меню File (для сокращенного варианта меню) <Ctrl+E> Строка Exit из меню File Как работает приложение MultiMenuВ приложении MultiMenu определены два класса – главный класс приложения CStateApp и класс главного окна приложения CStateWindow.
Главный класс приложения CMultiMenuAppГлавный класс приложения CMultiMenuApp наследуется от базового класса CWinApp. Объект MultiMenuApp класса CMultiMenuApp объявлен как глобальный и создается сразу после запуска приложения.
В класс CMultiMenuApp входит только метод InitInstance. Он создает главное окно приложения, представленное классом CMultiMenuWindow, наследованным от класса CFrameWnd .
Класс главного окна приложения CMultiMenuWindowКласс CMultiMenuWindow управляет главным окном приложения, создает меню, загружает панель управления а также обрабатывает сообщения, в том числе командные сообщения и команды обновления от меню.
Фактически все методы, определенные в классе CMultiMenuWindow, можно условно разделить на три группы. В первую группу попал только один метод OnCreate. Он обрабатывает сообщение WM_CREATE, поступающее в момент создания окна приложения. Вторая группа состоит из шести методов — OnDisable, OnCommand, OnExit, OnConstruct, OnRestrictMenu и OnFullMenu. Эти методы используются для обработки командных сообщений от меню приложения. И, наконец, третья группа методов включает три метода - OnUpdateProcess, OnUpdateConstruct и OnUpdateDisable, которые обрабатывают команды обновления от трех различных строк меню приложения.
В состав класса также входит несколько элементов данных. Это флаги bEnable, bRadio и nCheck, управляющие характеристиками трех строк меню, а также объект m_wndStatusBar класса CStatusBar, представляющий панель состояния нашего приложения.
Рассмотрим отдельные методы класса CMultiMenuWindow более подробно.
Конструктор класса CMultiMenuWindowКонструктор класса CMultiMenuWindow используется для создания главного окна приложения, подключения меню, загрузки таблицы акселераторов и инициализации флагов.
Для создания окна приложения вызывается метод Create класса CFrameWnd. Обратите внимание, что метод Create создает окно с меню, которое имеет идентификатор IDR_MENU:
Create(NULL, "Status Bar Sample", WS_OVERLAPPEDWINDOW, rectDefault, NULL, MAKEINTRESOURCE(IDR_MENU));
Затем выполняется загрузка таблицы акселераторов IDR_ACCELERATOR с помощью метода LoadAccelTable класса CFrameWnd:
LoadAccelTable(MAKEINTRESOURCE(IDR_ACCELERATOR));
И, в конце, конструктор устанавливает значение флагов bEnable, bRadio и nCheck. Флагам bEnable и bRadio присваивается значение TRUE, а флагу nCheck – нулевое значение.
Таблица сообщений класса CMultiMenuWindowТаблица сообщений класса CMultiMenuWindow обрабатывает командные сообщения и команды обновления от меню приложения, а также содержит макрокоманду ON_WM_CREATE.
Макрокоманда ON_WM_CREATE вызывает метод OnCreate во время создания окна:
ON_WM_CREATE()
Для обработки командных сообщений от меню приложения в таблицу сообщений класса CMultiMenuWindow включены шесть макрокоманд ON_COMMAND. Они вызывают обработчики OnDisable, OnConstruct, OnCommand, OnFullMenu, OnRestrictMenu и OnMenuExit:
ON_COMMAND(ID_MENU_DISABLE, OnDisable)
ON_COMMAND(ID_MISSION_CONSTRUCT, OnConstruct)
ON_COMMAND(ID_FILE_EXIT, OnExit)
ON_COMMAND(ID_MISSION_PROCESS, OnCommand)
ON_COMMAND(ID_MENU_RESTRICT, OnRestrictMenu)
ON_COMMAND(ID_MENU_FULL, OnFullMenu)
Для обработки команд обновления в таблицу сообщений класса включены три макрокоманды ON_UPDATE_COMMAND_UI. Они вызывают методы OnUpdateProcess, OnUpdateConstruct и OnUpdateDisable:
ON_UPDATE_COMMAND_UI(ID_MISSION_PROCESS, OnUpdateProcess)
ON_UPDATE_COMMAND_UI(ID_MISSION_CONSTRUCT, OnUpdateConstruct)
ON_UPDATE_COMMAND_UI(ID_MENU_DISABLE, OnUpdateDisable)
Соответствие методов, вызываемых макрокомандами ON_COMMAND и ON_UPDATE_COMMAND_UI, строкам меню приложения вы можете посмотреть в файле ресурсов приложения, представленном в листинге 3.3.
Метод OnCreate класса CMultiMenuWindowМетод OnCreate класса CMultiMenuWindow сначала вызывает метод OnCreate базового класса CFrameWnd , чтобы создать главное окно приложения:
if (CFrameWnd::OnCreate(lpCreateStruct) == –1) return –1;
Затем мы создаем панель состояния, указывая в качестве ее родительского окна главное окно приложения. Для этого мы вызываем метод Create объекта m_wndStatusBar, представляющего панель состояния, передавая ему в качестве параметра значение this. В данном случае это означает, что окно приложения является родительским окном для панели состояния: