Мучаем дальше наш проект. Если Вы захотите перенести файлы из предыдущего проекта, то учтите, что нужно будет перенести еще и resource.h и step6.rc. Эти файлы нужно добавить в проект, перед добавлением step6.rc нужно переименовать в step7.rc.
К моменту начала ваш проект должен иметь меню, и пункт меню Exit должен быть серым. Есть песня со словами "был-бы серым, но кто-то взял и покрыл меня сажей". Или в этом роде, не в этом суть, суть в процессе. Меню серое, а пока серое стучи не стучи толку нет. Вот мы и будем делать его черным.
Добавляем функцию к классу рамки окна для обработки команд меню. Эта функция будет использоваться в обработчике событий. Она должна быть типа 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).
И сама функция обработки (вообще это процедура, так как не возвращает значение, но вроде в С++ всё функции ?). Её можно поместить сразу после обработки сообщений.
void CMainWnd::MenuExit() { DestroyWindow(); // Уничтожить окно }
Собирайте проект и запускайте программу. Пункт меню будет черный. Это говорит о том, что его можно использовать. При выборе этого пункта меню программа прекратит свою работу.
В классе необходимо описать функцию реакции. Просмотрите предыдущие обработки. Не перепутайте. Объявляете функцию в классе, в котором и будут обрабатывать, и в которой есть обработчик.
Макрос ON_COMMAND предназначен для обработки команд вашего меню. В параметры ставите идентификатор и имя функции. Функция должна иметь тип void, что значит пусто, и она не вернет параметры. После Паскаля это удивительно. Что это за функция, которая не возвращает параметры. Это процедура !! Ну это на совести С++. То, что она тип void логично - куда возвращать результат, в меню что-ли ? И без параметров она, откуда им взяться ? Правило - функция реакции на меню с виду пустая, как бубен.
Функция DestroyWindow() разрушает окно. При этом тип у неё BOOL, окно и не всегда можно уничтожить, помните это и обрабатывайте, если необходимо. Правило: внутри пустой функции важно содержание!
Программа реагирует на нажатие меню, как я на запах кофе!
class CMainWnd : public CFrameWnd { public: ...... void MenuExit(); ...... };
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) ...... ON_COMMAND(ID_FILE_EXIT,MenuExit) ...... END_MESSAGE_MAP()
void CMainWnd::MenuExit() { ...... }