Шаг 8 - Подмена меню

Создание проекта

Продолжаем развитие нашего проекта. Нам в проекте нужно создать второе меню, также как и первое, но с идентификатором IDR_MENU_RUS. И создать пункты Файл и Закрыть. У пункта меню "закрыть" идентификатор должен совпадать с предыдущим меню. Это необходимо, чтобы не создавать несколько макросов обработки.

8_1.gif (5037 b)

Не забудьте сохранить изменения, после того как добавите меню и его пункты.

8_2.gif (1844 b)

И нам нужен еще один пункт в меню. Он будет нужен для того, чтобы переключать язык меню. Идентификатор у него должен быть ID_FILE_SWITCH. Этот пункт должен присутствовать в обоих меню.

8_3.gif (5591 b)

8_4.gif (5362 b)

Создаем код

Заведем переменную, в которой будем хранить состояние меню:

......
	void MenuExit(); // Процедура реакции на выбор пункта меню
	~CMainWnd();	// Деструктор
private:
	BOOL blMenu;	// какое меню активно
	CStatic* MyStatic;	// Указатель на объект надпись
	CMyButton* MyButton;	// Элемент управления кнопка
......

При создании класса окна ее надо инициализировать. Мы договоримся, что если IDR_MENU, то TRUE, а если IDR_MENU_RUS, то FALSE.

CMainWnd::CMainWnd()
{
	blMenu=FALSE;	// инициализация TRUE соответствует IDR_MENU
	Create(NULL,"Step8",WS_OVERLAPPEDWINDOW,rectDefault,
		NULL,NULL);	// Создать окно программы
	// оператор new по умолчанию в случае ошибки вернет NULL
	// проверка указателя на NULL дает возможность избавиться от дальнейших ошибок
	......

Реакция на событие выбора пункта меню в таблице откликов:

BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) // таблица откликов на сообщения
......
	ON_COMMAND(ID_FILE_EXIT,MenuExit)	// Вот она, обработка реакции на выбор меню
	ON_COMMAND(ID_FILE_SWITCH,MenuSwitch)// Реакция на выбор пункта о переключении языка меню
END_MESSAGE_MAP()

Описание функции реакции:

class CMainWnd : public CFrameWnd
{
	......
	void MenuExit();	// Процедура реакции на выбор пункта меню 
	void MenuSwitch();	// Процедура реакции на выбор пункта меню 
	~CMainWnd();	// Деструктор 
private:
	......
};

Ну и реализация:

void CMainWnd::MenuSwitch()
{
	m_wndMenu.DestroyMenu();	// Уничтожаем старое
	switch (blMenu)
	{
		case TRUE:
			m_wndMenu.LoadMenu(IDR_MENU);	// Читаем новое
			break;
		case FALSE:
			m_wndMenu.LoadMenu(IDR_MENU_RUS);	// Читаем новое
			break;
	}
	blMenu=!blMenu;	// Меняет переменную
	SetMenu(&m_wndMenu);	// Устанавливаем меню
}

Вот так должна работать Ваша программа:

8_5.gif (3153 b)

Описание

Функция DestroyMenu() уничтожает меню. Как видите, эта она является членом класса CMenu. Мы уничтожаем не просто меню программы, а меню класса меню связанного с окном программы. Уничтожается меню связанное функцией SetMenu(). Дальше Вам известно все. Читаем и устанавливаем.

На эту тему можно фантазировать. Например, меню на английском, немецком, французском на выбор? Или меню, которое постоянно изменяется при разных условиях. Или конкретное меню под конкретное рабочее место, под паролем на основании меню, в котором есть всё? Или .... будут, если подскажите идеи, где это можно применить.

Шпаргалка

  1. Удалить текущее меню:
    m_wndMenu.DestroyMenu();
  2. Прочитать новое:
    m_wndMenu.LoadMenu(IDR_MENU);
  3. Установить:
    SetMenu(&m_wndMenu);

Загрузить проект | Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем.