Шаг 7 - Обработка команд меню

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

Мучаем дальше наш проект. Если Вы захотите перенести файлы из предыдущего проекта, то учтите, что нужно будет перенести еще и resource.h и step6.rc. Эти файлы нужно добавить в проект, перед добавлением step6.rc нужно переименовать в step7.rc.

К моменту начала ваш проект должен иметь меню, и пункт меню Exit должен быть серым. Есть песня со словами "был-бы серым, но кто-то взял и покрыл меня сажей". Или в этом роде, не в этом суть, суть в процессе. Меню серое, а пока серое стучи не стучи толку нет. Вот мы и будем делать его черным.

7_1.gif (2098 b)

Создаем код

Добавляем функцию к классу рамки окна для обработки команд меню. Эта функция будет использоваться в обработчике событий. Она должна быть типа void и без параметров.

class CMainWnd : public CFrameWnd
{
public:
	CMainWnd();	// Конструктор по умолчанию
	afx_msg void OnLButtonDblClk( UINT, CPoint );	// виртуальная процедура ответа на левую кнопку
	afx_msg void OnRButtonDblClk( UINT, CPoint );	// виртуальная процедура ответа на правую кнопку
	afx_msg void OnKeyDown( UINT, UINT, UINT );	// виртуальная процедура ответа на клавишу
	int OnCreate(LPCREATESTRUCT lpCreateStruct);	// эта функция вызывается при создании окна
	void MenuExit();	// Процедура реакции на выбор пункта меню 
	~CMainWnd();	// Деструктор 
private:    
	CStatic* MyStatic;	// Указатель на объект надпись
	CMyButton* MyButton;	// Элемент управления кнопка
	CEdit* MyEdit;	// Указатель на объект поле редактирования
	CStatusBar m_wndStatusBar;	// класс панели состояния
	CMenu m_wndMenu;	// Это наш класс Меню
	DECLARE_MESSAGE_MAP();	// таблица откликов
};

А теперь в обработчике событий нужно добавить реакцию на выбор пункта меню:

BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)	// таблица откликов на сообщения
	ON_WM_LBUTTONDBLCLK()	// реакция на нажатие левой кнопки мыши
	ON_WM_RBUTTONDBLCLK()	// реакция на нажатие правой кнопки мышки
	ON_WM_KEYDOWN()	// реакция на нажатие клавиши
	ON_WM_CREATE()	// событие создания окна
	ON_COMMAND(ID_FILE_EXIT,MenuExit)	// Вот она , обработка реакции на выбор меню
END_MESSAGE_MAP()

Обратите внимание на идентификатор пункта меню. Откуда я его взял? При создании пункта меню ему задается идентификатор, который записывается в resource.h.

// Used by step7.rc
//
#define IDR_MENU                        101
#define ID_FILE_EXIT                    40001

// Next default values for new objects

При желании его можно поменять в режиме редактирования ресурсов щелкнув правой кнопкой мыши по пункту меню и вызвав свойства (Properties).

7_2.gif (2569 b)

И сама функция обработки (вообще это процедура, так как не возвращает значение, но вроде в С++ всё функции ?). Её можно поместить сразу после обработки сообщений.

void CMainWnd::MenuExit()
{
	DestroyWindow(); // Уничтожить окно 
}

Собирайте проект и запускайте программу. Пункт меню будет черный. Это говорит о том, что его можно использовать. При выборе этого пункта меню программа прекратит свою работу.

7_3.gif (1989 b)

Описание

В классе необходимо описать функцию реакции. Просмотрите предыдущие обработки. Не перепутайте. Объявляете функцию в классе, в котором и будут обрабатывать, и в которой есть обработчик.

Макрос ON_COMMAND предназначен для обработки команд вашего меню. В параметры ставите идентификатор и имя функции. Функция должна иметь тип void, что значит пусто, и она не вернет параметры. После Паскаля это удивительно. Что это за функция, которая не возвращает параметры. Это процедура !! Ну это на совести С++. То, что она тип void логично - куда возвращать результат, в меню что-ли ? И без параметров она, откуда им взяться ? Правило - функция реакции на меню с виду пустая, как бубен.

Функция DestroyWindow() разрушает окно. При этом тип у неё BOOL, окно и не всегда можно уничтожить, помните это и обрабатывайте, если необходимо. Правило: внутри пустой функции важно содержание!

Программа реагирует на нажатие меню, как я на запах кофе!

Шпаргалка

  1. Добавляем функцию, которая обработает вызов меню, в класс рамки окна:
    class CMainWnd : public CFrameWnd
    {
    public:
    	......
    	void MenuExit();
    	...... 
    };
    
  2. Создаем её обработку в обработчике событий класса рамки окна.
    BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)	
    	......
    	ON_COMMAND(ID_FILE_EXIT,MenuExit)      
    	......
    END_MESSAGE_MAP()
    
  3. Пишем, что делать:
    void CMainWnd::MenuExit()
    {
    	......	 
    }
    

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