Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
System programming / Конспект лекций / Лекция 8 Ресурсы часть 2.doc
Скачиваний:
52
Добавлен:
08.05.2015
Размер:
83.97 Кб
Скачать

Независимые всплывающие меню

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

В файле описания ресурсов меню определяется почти так, как ранее. Отличие состоит только в том, что главное меню содержит только один пункт — всплывающее меню, содержащее опции File, Edit, Background и Help.

hMenu = LoadMenu (hinst, szAppName) ;

hMenu = GetSubMenu (hMenu, 0) ;

При обработке сообщения WM_RBUTTONDOWN, программа получает положение указателя мыши, преобразует это положение в коорди­наты экрана и передает их функции TrackPopupMenu:

point.x = LOWORD (IParam) ;

point.у = HIWORD (IParam) ;

ClientToScreen (hwnd, Spoint) ;

TrackPopupMenu (hMenu, 0, point.x, point.y, 0, hwnd, NULL) ;

Затем Windows выводит на экран всплывающее меню с пунктами File, Edit, Background и Help. Выбор любого из этих пунктов приводит к тому, что вложенное всплывающее окно меню появляется на экране правее выбран­ной опции. Функции этого меню те же, что и у обычного меню.

Изменение меню

Мы уже видели, как функция AppendMenu может использоваться для опре­деления меню в целом внутри программы и добавления пунктов к систем­ному меню. До появления Windows 3.0 для выполнения этой работы исполь­зовалась функция ChangeMenu. Функция ChangeMenu была столь многогранной по своим задачам, что была одной из наиболее сложных функций в Windows. В Windows 95 эта функция по-прежнему имеется, но ее задачи распределены между пятью новыми функциями:

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

DeleteMenu удаляет существующий пункт меню и уничтожает его.

InsertMenu — вставляет в меню новый пункт.

ModifyMenu — изменяет существующий пункт меню.

RemoveMenu — удаляет существующий пункт меню.

Отличие между функциями DeleteMenu и RemoveMenu весьма важно, если указанный пункт меню является всплывающим меню. Функция DeleteMenu уничтожает всплывающее меню, а функция RemoveMenu — нет.

Другие команды меню

Для работы с меню имеется еще несколько полезных функций.

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

DrawMenuBar (hwnd) ;

Описатель всплывающего меню можно получить с помощью функции GetSubMenu:

hMenuPopup = GetSubMenu (hMenu, iPosition) ;

где iPosition это индекс (отсчитываемый с 0) всплывающего меню внутри главного меню, которое задается параметром hMenu. Затем, полученный описатель всплывающего меню hMenuPopup можно использовать в других функциях, например, AppendMenu.

Текущее число пунктов главного или всплывающего меню можно получить с помощью функции GetMenuItemCount:

iCount = GetMenuItemCount (hMenu) ;

Идентификатор меню для пункта всплывающего меню можно получить следующим образом:

id = GetMenuItemID (hMenuPopup, iPosition) ;

Установить или удалить метку пункта всплывающего меню с помощью функции

CheckMenuItem (hMenu, id, iCheck) ;

hMenu - описатель главного меню, id — идентификатором меню, а значение параметра iCheck равно либо MF_CHECKED, либо MF_UNCHECKED. Если hMenu является описателем всплывающего меню, то параметр id может стать не идентификатором ме­ню, а индексом положения. Если пользоваться этим индексом удобнее, то в третьем параметре указывается флаг MF_BYPOSITION. Например:

CheckMenuItem (hMenu, iPosition, MF_CHECKED I MF_BYPOSITION) ;

Работа функции EnableMenuItem похожа на работу функции CheckMenuItem за исключением того, что третьим параметром может быть MF_JENABLED, MF_DISABLED или MF_GRAYED.

EnableMenuItem ((HMENU) wParam, IDM_PASTE, MF_ENABLED) ;

Если используется функция EnableMenuItem для пункта главного меню, содержащего всплывающее меню, то в качестве третьего параметра следует использовать идентификатор MF_BYPOSITION, поскольку этот пункт меню не имеет идентификатора меню.

Функция HiliteMenuItem напоминает функции CheckMenuItem и EnableMenuItem, но использует идентификаторы MF_HILITE и MF_UNHILITE. Эта функция обеспечивает инверсное изображение, которое Windows использует, когда вы перемещаете указатель от одного из пунктов меню к другому. Обычным приложениям нет необходимости использовать функцию HiliteMenuItem.

Что еще нужно сделать с меню? Если вы забыли, какие символьные строки использовались в вашем меню, то освежить память можно следующим образом:

iByteCount = GetMenuString (hMenu, id, pString, iMaxCount, iFlag) ;

Параметр iFlag равен либо MF_BYCOMMAND (при этом id это иденти­фикатор меню), либо MF_JBYPOSITION (при этом id — это индекс положе­ния). Функция копирует iMaxCount байтов строки символов в pString и возвращает число скопированных байтов.

Может быть, вы хотите узнать, каковы текущие флаги пункта меню:

iFlags = GetMenuState (hMenu, id, iFlag) ;

И снова, параметр iFlag равен либо MF_BYCOMMAND, либо MF_BYPOSITION. Возвращаемое значение функции iFlags — это комбинация всех текущих флагов. Вы можете определить текущие флаги, проверив iFlags с помощью идентификаторов MF_DISABLED, MF_GRAYED, MF_CHECKED, MF_MENUBREAK, MF_MENUBARBREAK и MF_SEPARATOR.

А может быть, вам уже слегка надоело меню. В таком случае, если меню вам больше не нужно, его можно удалить:

DestroyMenu (hMenu) ;

Эта функция делает недействительным описатель меню.