Шаг 246 - Использование динамического меню

Для создания динамических меню используются диапазоны обработчиков команд описанные в прошлом шаге. Здесь мы сконцентрируемся непосредственно на управлении меню. Для этого используем проект созданный в прошлом шаге. Для начала научимся добавлять к меню полосу разделения MF_SEPARATOR. В меню Edit создадим новый пункт меню Add Separator и привяжем к нему функцию обработки в классе вида.

void CTestRangeView::OnEditAddseparator() 
{
	// TODO: Add your command handler code here
}

Заведем указатель на класс меню (CMenu). И установим этот указатель непосредственно на наше меню. Дальше нам придется проверить, что мы действительно этот указатель получили с помощью ASSERT.

void CTestRangeView::OnEditAddseparator() 
{
	CMenu *cm;
	cm=AfxGetMainWnd()->GetMenu();
	ASSERT(cm != NULL);
}

Теперь нам нужно получить указатель на пункт меню. Это мы сделаем используя еще один класс меню и функцию GetSubMenu.

void CTestRangeView::OnEditAddseparator() 
{
	CMenu *cm;
	CMenu *cmSub;
	cm=AfxGetMainWnd()->GetMenu();
	ASSERT(cm != NULL);
	cmSub=cm->GetSubMenu(4);
	ASSERT(cmSub != NULL);
}

Здесь нужно указать позицию. Счет позиций начинается с нуля. И теперь мы можем добавить в меню полосу разделения.

void CTestRangeView::OnEditAddseparator() 
{
	.......
	ASSERT(cmSub != NULL);
	cmSub->AppendMenu(MF_SEPARATOR); 
}

Если Вы посмотрите на меню Test, то увидите, что полоса меню добавилась. Теперь давайте попробуем добавить пункты меню. Для этого нам нужно добавить идентификаторы этих пунктов. В файл Resource.h для того, чтобы эти идентификаторы больше не использовались.

//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by TestRange.rc
//
#...........
#define ID_TEST_MENU3                   32773
//----- NEW----
#define ID_TEST_MENU4                   32777
#define ID_TEST_MENU5                   32778
//-------------
#define ID_EDIT_ADDSEPARATOR            32774

// Next default values for new objects
......

Мы теперь можем добавлять динамически и пункты меню. Вот так используя идентификатор.

void CTestRangeView::OnEditAddseparator() 
{
	.....
	ASSERT(cmSub != NULL);
	cmSub->AppendMenu(MF_SEPARATOR); 
	cmSub->AppendMenu(MF_STRING,ID_TEST_MENU4,"Menu4");
	cmSub->AppendMenu(MF_STRING,ID_TEST_MENU5,"Menu5");
}

Если Вы сейчас запустите приложение, то увидите, что несмотря на то, что эти пункты меню добавляются они неактивные. Естественно нужно изменить диапазон в обработчике команд. Вот так:

BEGIN_MESSAGE_MAP(CTestRangeView, CView)
	.......
	ON_COMMAND_RANGE(ID_TEST_MENU1,ID_TEST_MENU5,onColor)
END_MESSAGE_MAP()

Теперь они будут активными и смогут обрабатываться. Вы увидите это по окну сообщения.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Каев Артем - 26.10.2000