Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
38
Добавлен:
16.02.2016
Размер:
7.08 Mб
Скачать

2. Запрограммировать метод обработки сообщения, добавляющий (и уда­ляющий) в созданное меню динамический элемент меню (например, имя файла).

Предположим, что при активизации дочернего окна MDI-приложения к некоторому раскрывающемуся меню будет добавлено три динамических элемента меню. Первое, что следует сделать, - это определить в редакторе меню идентификаторы ресурса для этих элементов меню. Далее с помощью ClassWizard следует вставить для класса дочернего окна-рамки (например, CChildFrame1) метод обработки сообщения WM_MDIACTTVATE.

Приведем сокращенный текст кода метода обработки сообщения WM_MDIACTIVATE, добавляющий динамический элемент меню.

void CCaildFrame::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)

{ if (bActivate) // Окно активно CMenu *pMenu=AfxGetMainWnd()->GetMenu(); // Указатель на меню int iNum; UNIT uID;

for (iNum = pMenu->GetMenuItemCount()-l; iNum>=0; iNum—) { CMenu* pSumMenu= pMenu->GetSubMenu(iNum); // Указатель на подменю if (pSubMenu && pSubMenu->GetMenuItemID() == ID_Last // ID_Last идентификатор элемента меню, предшествующего // добавляемому динамическому элементу меню pMenu=pSubMenu; uID=IDJLast+l; } // sStr - заголовок динамического элемена меню

pMenu->AppendMenu(MF STRING || MF ENABLED, uID, sStr);

Класс CMenu

Класс CMenu инкапсулирует функционирование Windows-меню HMENU в объекте данного класса. Он поддерживает создание, управление, изменение и разрушение меню.

Для создания и использования нового меню в некотором окне можно:

• создать объект CMenu;

• вызвать метод CWnd::SetMenu для назначения меню данному окну (после отключения предыдущего меню, если оно было, вызовом метода Detach);

Метод CWnd::SetMenu устанавливает для окна новое меню, инициирует | перерисовку меню окна и передает объект меню "в собственность" окне. Метод Detach отсоединяет HMENU от объектГ CMenu, не выполняя при этом разрушения меню. Меню само автоматически разрушается при разру- I шении окна, владеющего этим меню.

Меню также может быть создано из шаблона, расположенного в памяти J вызовом метода LoadMenuIndirect.

Самым простым способом, однако, является создание меню на основе шаблона ресурса меню, созданного средствами редактора меню. Для его использования достаточно вызвать метод LoadMenu, выполняющий загруз­ку ресурса меню.

Элемент меню может указываться по идентификатору команды, если он есть, или по позиции. Позиция первого элемента равна нулю.

Отметим, что при определении элемента меню по позиции всегда ис­пользуется текущий объект CMenu:

• если CMenu является линейкой меню (меню верхнего уровня), то это позиция элемента в линейке меню;

• если Степи - это подменю или вложенное меню, то позиция указывает соответственно на элемент подменю или вложенного меню.

Члены класса cMenu: :m_hMenu

Определяет дескриптор HMENU Windows-меню, пристыкованного к объекту CMenu.

CMenu();

Конструктор объекта CMenu.

Для того чтобы создать меню после выполнения конструктора, необхо­димо вызвать один из следующих методов, выполняющих создание или загрузку меню:

• GreateMenu,

• CreatePopupMenu,

• LoadMenu,

• LoadMenuIndirect,

• Attach.

BOOL CreateMenu ( );

Создает Windows-меню и пристыковывает его к объекту CMenu.

Создаваемое меню первоначально пусто. Для добавления элементов ме­ню можно использовать методы AppendMenu или InsertMenu.

Если меню подчинено окну, то оно автоматически разрушается при раз- j рушении окна. В противном случае приложение предварительно перед своим завершением должно освободить системные ресурсы, ассоциируемые с меню, вызвав метод DestroyMenu.

BOOL CreatePopupMenu ();

Метод создает пустое подменю (ниспадающее меню) и пристыковывает его к объекту CMenu.

Подменю может быть добавлено к существующему меню или подменю.

Метод TrackPopupMenu позволяет отображать подменю как плавающее . меню.

BOOL LoadMenu (LPCTSTR lpszResourceName); BOOL LoadMenu (UINT nIDResource);

Метод загружает ресурс меню из выполнимого файла приложения и пристыковывает его к объекту CMenu. Параметры:

lpszResourceName - указатель на строку, содержащую имя ресурса меню.

nIDResource - ID ресурса меню.

BOOL LoadMenuIndirect (const void* lpMenuTemplate);

Метод загружает меню из шаблона меню из памяти и пристыковывает его к объекту CMenu. Параметры:

lpMenuTemplate - указатель на шаблон меню (это структура MENUITEMTEMPLATEHEADER и набор из одной или более структур MENUITEMTEMPLATE).

BOOL Attach (HMENU hMenu);

Метод пристыковывает существующее Windows-меню к объекту CMenu. После этого с меню можно работать, как с объектом класса CMenu.

Если пристыковываемое Windows-меню уже ассоциировано с каким-либо окном, то для получения указателя можно использовать метод CWnd::GetMenu.

Пример:

CMenu mnu; \ HMENU hmnu = pWnd->GetMenu(); i mnu.Attach( hmnu);

static CMenu* PASCAL FromHandle (HMENU hMenu);

Метод возвращает указатель на объект CMenu для заданного Windows-меню.

Если Windows-меню не сопоставлен никакой объект CMenu, то метод возвращает указатель на временно созданный и пристыкованный объект.

HMENU GetSafeHmenu ( ) const;

Метод возвращает HMENU для объекта CMenu. BOOL DestroyMenu ( );

Метод разрушает меню и освобождает все используемые им ресурсы Windows. При этом меню отстыковывается от объекта CMenu. Этот метод автоматически вызывается из деструктора.

BOOL DeleteMenu (UINT nPosition, UINT nFlags);

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

Параметры:

nPosition - определяет удаляемый элемент меню в соответствии со значени­ем nFlags.

nFlags - определяет, как следует интерпретировать параметр nPosition и мо­жет принимать следующие значения:

MF_BYCOMMAND - параметр nPosition указывает Ш команды сущест­вующего пункта меню;

MF_BYPOSITION - параметр nPosition указывает позицию существую­щего пункта меню. Позиция первого элемента меню равна нулю.

При изменении меню, расположенного в окне, приложение должно вы­звать метод CWnd::DrawMenuBar.

BOOL TrackPopupMenu (UINT nFlags, int x, int y, CWnd* pWnd, LPCRECT ipRect = NULL);

Метод отображает плавающее подменю в указанной позиции и само­стоятельно отслеживает выбор пункта меню. Плавающее меню может быть отображено в любом месте экрана. Такое меню также называется контек­стным меню.

Параметры:

nFlags - параметр определяет позицию экрана и кнопку мыши и может быть задан следующими флажками:

• для указания позиции выравнивания по горизонтали относительно х-ко-ординаты: TPM_CENTERALIGN, TPMJLEFTALIGN, TPM_RIGHTALIGN;

• для определения кнопки мыши, выполняющей выбор пункта меню: TPM_LEFTBUTTON, TPM_RIGHTBUTTON.

х - позиция подменю по горизонтали в экранных координатах. у - позиция верхней точки подменю по вертикали в экранных координатах. pWnd - указатель окна, владеющего подменю. Это окно получает от меню со­общение WMCOMMAND после завершения TrackPopupMenu.

IpRect - указатель на структуру RECT, содержащую экранные координаты прямоугольной области, при щелчке пользователя внутри которой не проис­ходит удаления подменю. Если значение этого параметра равно NULL, то такая прямоугольная область ограничивается рамкой меню.

BOOL AppendMenu (UINT nFlags, UINT nIDNewItem = 0, LPCTSTR

ipszNewItem = NULL);

BOOL AppendMenu (UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);

Метод добавляет новый элемент в конец меню.

При любом изменении элементов меню приложение должно вызывать метод CWnd::DrawMenuBar.

Параметры:

nFlags - определяет состояние добавляемого элемента меню и может быть указан комбинацией следующих флажков:

MF_CHECKED - переключаемый элемент: состояние включен (V);

MF_UNCHECKED - переключаемый элемент: состояние выключен;

MF_DISABLED - элемент недоступен для выбора;

MF_ENABLED - элемент доступен;

MF_GRAYED - элемент недоступен для выбора и отображается "посеревшим";

MFJMENUBARBREAK - элемент линейки меню размещается на новой стро­ке, а элемент подменю - в новом столбце, отделенном вертикальной линией;

MF_MENUBREAK - элемент линейки меню размещается на новой строке, а элемент подменю - в новом столбце, но без разделительной линии между столбцами;

MF_OWNERDRAW - самоотображаемый элемент меню (не используется для элементов линейки меню). При первом отображении элемента меню окно, владеющее меню, получает сообщение WM_MEASUREITEM для определения ширины и высоты элемента меню. Для обновления отображения элемента меню владельцу меню посылается сообщение WM_DRAWITEM;

MF_POPUP - элемент меню имеет ассоциированное с ним подменю, деск­риптор которого задается параметром ID. Используется для добавле­ния или подменю верхнего уровня (для линейки меню) или построе­ния иерархических подменю;

MF_SEPARATOR - отображение горизонтальной разделительной линии (только для подменю);

MF_STRING - элемент меню является строкой текста.

nIDNewItem - в зависимости от значения параметра nFlags определяет или

ID команды нового элемента меню, или указатель (HMENU) Подменю (nFlags= MFPOPUP). Параметр игнорируется для nFlags, равного I

MF_SEPARATOR.

ipszNewItem - определяет содержание нового элемента меню. В зависимости от ;

значения nFlags этот параметр может иметь различную интерпретацию:

MF_OWNERDRAW - содержит 32-битовое значение, используемое прило­жением для дополнительной информации, ассоциируемой с элемен­том меню. Это 32-битовое значение доступно при обработке сооб­щений WM_MEASUREITEM и WM_DRAWITEM (значение содер­жится в члене itemData структуры, используемой этими сообщениями);

MF_STRING - содержит указатель на строку (используется по умолчанию); ]

MF_SEPARATOR - параметр IpszNewItem игнорируется.

рВтр - указатель на объект CBitmap, который будет использоваться как \

элемент меню.

BOOL InsertMenu ( UINT nPosition, UINT nFlags, UINT nIDNewItem = 0, LPCTSTR IpszNewItem = NULL );

BOOL InsertMenu ( UINT nPosition, UINT nFlags, UINT nIDNewItem, const CBitmap* pBmp);

Метод вставляет новый элемент меню в указанную параметром nPosition позицию.

Когда nIDNewItem определяет подменю, то он становится частью меню, в которое вставляется. При разрушении меню вставленное меню также бу­дет разрушено. Для избежания конфликтов вставленное меню должно быть отстыковано от объекта CMenu.

Отметим, что если в MDI-приложении дочернее окно документа распах­нуто до полноэкранного состояния (максимизировано) и приложение вы­полняет вставку подменю, используя флажок MF_BYPOSITION (по пози­ции), то реально будет выполнена вставка на один элемент левее ожидаемого результата. Это происходит в связи с тем, что линейка меню для полноэк­ранного состояния дочернего окна дополняется слева его системным меню Control. При нормальном состоянии системное меню Control располагается в левом верхнем углу дочернего окна документа. UINT CheckMenuItem ( UINT nIDCheckltem, UINT nCheck );

Метод устанавливает или снимает для переключаемого элемента меню состояние включен/выключен (V).

При успешном завершении метод возвращает значение предыдущего состояния элемента: MF_CHECKED или MF_UNCHECKED, а если эле­мент не существует, то значение OxFFFFFFFF.

Параметры:

nIDCheckltem - указывает элемент меню по идентификатору (иCheck = MF_BYCOMMAND) или по порядковому номеру - позиции (nCheckMF_BYPOSITION).

nCheck - определяет, как указывается элемент меню и устанавливаемое со­стояние. Параметр может быть задан комбинацией флажков MF_CHECKED или MFJJNCHECKED с флажками MF_BYPOSITION или MF_BYCOMMAND.

Отметим, что переключаемым элементом может быть как элемент под­меню, так и элемент меню (но не элемент линейки меню). Элемент подме­ню может быть указан только по позиции, так как не имеет идентификато­ра элемента меню, ассоциированного с ним.

BOOL CheckMenuRadioItem ( UINT nIDFirst, UINT nIDLast, UINT nIDItem, UINT nFlags);

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

Параметры:

nIDFirst, nIDLast - определяют первый и последний элементы меню группы элементов.

nIDItem - определяет помечаемый элемент меню.

nFlags - указывает как интерпретируются значения параметров: при значе­нии, равном MF_BYCOMMAND, используется ID существующих элемен­тов меню (значение по умолчанию), при значении MFBYPOSITION, па­раметры указывают позицию элементов меню.

UINT EnableMenuItem( UINT nIDEnableltem, UINT nEnable );

Метод устанавливает для указанного элемента меню одно из следующих состояний: MF_DISABLED, MF_ENABLED, MF_GRAYED.

При успешном завершении метод возвращает предыдущее состояние, в противном случае - значение -1.

Параметр nEnable также указывает, как задан элемент меню: по иденти­фикатору (MF_BYCOMMAND) или по no3HUHH(MF_BYPOSiTION). UINT GetMenuItemCount ( ) const;

При успешном завершении метод возвращает количество элементов данного меню (линейки меню или подменю), и -1 - в противном случае.

UINT GetMenuItemID ( int nPos ) const;

При успешном завершении метод возвращает идентификатор ID ука- J занного по позиции элемента подменю; если указано само подменю, то I значение -1; если указан элемент-разделитель, то значение 0. UINT GetMenuState ( UINT nID, UINT nFlags ) const;

Метод возвращает состояние элемента меню или количество элементов ;j в подменю.

Параметр nld может указываться или по позиции, или по идентифика-тору команды, в зависимости от значения nFlags.

Если указанный элемент не существует, то метод возвращает значение | OxFFFFFFFF. Если nld указывает подменю, то старший байт содержит ко- | личество элементов в подменю, а младший - флажки, ассоциируемые с | этим подменю. В противном случае (для элемента меню) возвращаемое значение является маской значений флажков, начинающихся с префикса , MF_. Маска описывает состояние элемента меню, комбинируя допустимые значения (оператор ИЛИ).

int GetMenuString( UINT nIDItem, LPTSTR ipString, int nMaxCount, UINT nFlags) const; int GetMenuString( UINT nIDItem, CString& rString, UINT nFlags ) const;

Метод определяет надпись для указанного элемента меню и возвращает I число байт, скопированных в указанный буфер (не включая 0-символ).

Параметр nIDItem может указываться или по позиции, или по иденти­фикатору команды, в зависимости от значения nFlags.

Параметр nMaxCount должен быть на единицу больше, чем длина над- < писи (не включая 0-символ). CMenu* GetSubMenu (int nPos ) const;

Метод возвращает указатель на объект CMenu, определяющий по значе- ; нию m_hMenu подменю, или NULL.

BOOL ModifyMenu ( UINT nPosition, UINT nFlags, UINT nlDNewItem = 0, LPCTSTR ipszNewItem = NULL );

BOOL ModifyMenu ( UINT nPosition, UINT nFlags, UINT nlDNewItem, const CBitmap* pBmp );

Эти методы позволяют модифицировать существующие элементы меню. BOOL RemoveMenu ( UINT nPosition, UINT nFlags );

Метод удаляет из меню указанный элемент меню (и ассоциированное с ним подменю).

Для того чтобы повторно использовать удаляемое меню, можно перед I вызовом этого метода вызвать метод GetSubMenu для получения подменю CMenu.

Для удаления меню и одновременного освобождения ресурсов следует использовать метод DeleteMenu.

BOOL SetMenuItemBitmaps (UINT nPosition, UINT nFlags, const CBitmap* pBmpUnchecked, const CBitmap* pBmpChecked);

Метод ассоциирует с указанным элементом меню заданное битовое изо­бражение, отображаемое, когда элемент меню имеет состояние вклю­чен/выключен.

Если один из параметров pBmpUnchecked или pBmpChecked равен NULL, то Windows ничего не отображает для пометки элемента меню, но если оба параметра одновременно равны NULL, то используется стандарт­ный символ пометки V.

При разрушении меню приложение само должно удалить объекты CBitmap.

Для получения размера стандартного символа пометки следует исполь­зовать метод GetMenuCheckMarkDimensions.

BOOL SetMenuContextHelpId (DWORD dwContextHelpl );

Метод позволяет установить идентификатор ID контекста справки, ас­социированной с CMenu. Это идентификатор разделяется всеми элемента­ми меню: нельзя установить свой ID контекста для отдельного элемента меню.

Параметры:

dwContextHelpId - ID контекста справки, ассоциированной с CMenu. DWORD GetMenuContextHelpId ( ) const;

Метод возвращает идентификатор ID контекста справки, ассоциирован­ной с CMenu, или 0 в противном случае.

virtual void Drawltem (LPDRAWITEMSTRUCT ipDrawItemStmci);

Метод вызывается средой выполнения при изменении меню, для кото­рого установлен флажок самоотображения. Информация для отрисовки элемента меню передается в структуре DRAWITEMSTRUCT.

При этом приложение до завершения выполнения этого метода должно восстановить графический контекст устройства.

Структура DRAWITEMSTRUCT имеет следующее описание:

typedef struct tagDRAWITEMSTRUCT {

UINT CtlType; // Тип элемента управления UINT CtllD; // ID элемента управления

//(не используется для меню) UINT itemID; UINT itemAction; UINT ; itemState; HWND ■ hwndltem;

HDC hDC; RECT rcltera; DWORD itemData; } DRAWITEMSTRUCT;

Самоотображаемое окно или самоотображаемый элемент управления или меню получают в lParam указатель на эту структуру при обработке со­общения WM_DRAWITEM.

Член CtlType определяет тип элемента управления и может быть задан сле­дующими флажками: ODT_BUTTON, ODT_COMBOBOX, ODTJLISTBOX, ODT_MENU, ODTJiSTVIEW, ODT_STATIC, ODT_TAB. CtllD - ID списка, комбинированного списка или кнопки. Для меню не ис­пользуется.

itemID - ID элемента меню или индекс элемента в списке или комбиниро­ванном списке.

itemAction - определяет, в каких случаях выполнять перерисовку: ODA_DRAWENTIRE - необходима перерисовка; ODA_FOCUS - перерисовка при получении или потере фокуса; ODA_SELECT - перерисовка при изменении состояния выделенное™. itemState - определяет визуальное состояние элемента после выполнения перерисовки и указывается следующими флажками: ODS_CHECKED, ODS_DISABLED, ODS_FOCUS, ODS_GRAYED, ODS_SELECTED, ODS_COMBOBOXEDIT, ODS_DEFAULT.

hwndltem - указатель окна элемента управления или HMENU меню, содер­жащего элемент меню. hDC - контекст устройства.

rcltem - прямоугольная область для контекста устройства, определяемого членом hDC.

itemData - для элементов управления список может содержать значение, пе­редаваемое методами CComboBox::AddString, CComboBox::InsertString, CListBox::AddString, CListBox::InsertString; для меню - значение, передавае­мое методами CMenu::AppendMenu, CMenu::InsertMenu или CMenu:: ModifyMenu.

Соседние файлы в папке VC++Баженова