Шаг 6 - Создание меню

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

Будем развивать наш проект. Но в нем нам нужно создать файл ресурсов. Тут вот придется потрудиться. У вас в левом углу должно быть окно WorkSpace. Вот такое:

6_1.gif (2799 b)

Если его нет, включите через View - WorkSpace:

6_2.gif (4082 b)

В этом окне есть вкладка File View. Нам туда. Там надо создать файл step6.rc, как в первом шаге создавали step1.cpp. У вас спросят нужно ли его создавать на диске, ответьте положительно, пожалуйста.

6_3.gif (6931 b)

Но это еще не все. В той же вкладке WorkSpace нужно два раза щелкнуть по файлу, чтобы он все-таки создался. Вот такая табличка будет при двойном щелчке. Ответив ДА вы создадите файл физически на диске.

6_4.gif (3212 b)

Далее нам на вкладку Resource. Там пусто. Мышку на папку, правую кнопку вниз, пункт меню Insert:

6_5.gif (1904 b)

В окне выбираем Menu и New. В результате в ресурсах появится меню. Создайте пункты меню. Пункт File и ниже Exit. Обязательно поменяйте идентификатор меню на IDR_MENU.

6_6.gif (1843 b)

В списке файлов (WorkSpace -> FileView) вы не найдете resource.h, если необходимо добавьте его (Add File to Project). В этом файле будут находиться идентификаторы ресурсов.

Создаем код

Добавляем в раздел описаний ссылку на файл с идентификаторами ресурсов.

 
......
#include "afxext.h"	// MFC Расширения
#include "resource.h"	// Идентификаторы ресурсов

#define IDC_MYBUTTON 100	// Идентификатор кнопки
......

Добавляем описание класса меню в класс рамки окна. Замечаете, на всё есть класс, это класс !!!

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);	// эта функция вызывается при создании окна
	~CMainWnd();	// Деструктор 
private:    
	CStatic* MyStatic;	// Указатель на объект надпись
	CMyButton* MyButton;	// Элемент управления кнопка
	CEdit* MyEdit;		// Указатель на объект поле редактирования
	CStatusBar m_wndStatusBar;	// класс панели состояния
	CMenu m_wndMenu;	// Это наш класс Меню
	DECLARE_MESSAGE_MAP();// таблица откликов
};

Добавляем в процедуру создания окна команды создания меню:

int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)  return -1;
	m_wndStatusBar.Create(this); 
	m_wndMenu.LoadMenu(IDR_MENU);	// Загрузить меню из файла ресурса
	SetMenu(&m_wndMenu);	// Установить меню
	return 0;
}

Собирайте программу и запускайте. Обратите внимание на то, что при компиляции программы производится и компиляция ресурсов.

--------------------Configuration: step6 - Win32 Debug--------------------
Compiling resources...
Compiling...
step6.cpp
Linking...

step6.exe - 0 error(s), 0 warning(s)

Вы увидите, что у нас появилось меню.

6_7.gif (1941 b)

Описание

Использование ресурсов является таким же приемом программирования в Windows, как прямое обращение к видеопамяти в DOS. Использовать ресурсы необязательно, всё можно сделать динамически! Но в ресурсах есть и преимущества. Вы сталкивались с тем, что Ваши специалисты теряются в английском? У Вас было желание перевести программу на русский? Любую программу с ресурсами можно изменить без перекомпиляции EXE файла. Меню, диалоговые панели, строки подсказки, иконы, картинки все это чаше всего находится в ресурсах. В Borland C++ 4.5 была очень хорошая программа Resource WorkShop. Она позволяла извлечь ресурсы из файла, редактировать и сохранять их на место, самое главное это отдельная программа и очень удобная.

Как и с элементами управления, каждый элемент ресурсов должен иметь идентификатор. В Windows идентификаторы на каждом шагу, как в известном мультфильме Билл всех подсчитал. Правило очередное - каждый ресурс должен быть пронумерован.

Идентификаторы ресурсов хранятся в *.h файлах. При создании файла ресурсов VC автоматически создает файл с описанием идентификатора ресурсов - "resource.h", его то мы и подключили первой командой. Как бы иначе программа догадалась, что они существуют?

Далее мы указали классу окна, что у нас есть класс меню. Он статический, это мы уже делали ранее.

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

LoadMenu() функция загрузки меню из ресурсов. Она возвращает значение типа BOOL указывающее на успех операции. Я это упустил сознательно. Если есть желание можете написать что-то типа if (m_wndMenu.LoadMenu(IDC_MENU)) .... else .... . Параметр только один - идентификатор меню в ресурсах.

SetMenu() устанавливает меню в окне. Она требует адрес класса типа CMenu. Имея статический класс CMenu адрес можно получить применив операцию взятия адреса &CMenu. Её мы и применили. Правило для статических классов Адрес Класса = &Класс.

Шпаргалка

  1. Объявить класс меню:
    ......
    CMenu m_wndMenu; 
    ......
    
  2. Загрузить и установить меню:
       
    ......
    m_wndMenu.LoadMenu(IDR_MENU);
    SetMenu(&m_wndMenu);
    ......
    

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