Главная » Win32 API » Работа с меню

0

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

Любое меню состоит из пунктов, обозначаемых словом или графи­ческим изображением. Пункт меню может быть отмечен галочкой, что означает выбор некоторого режима работы приложения. Если после выбора пункта меню на экране должно появиться диалоговое окно, то после названия пункта меню ставится многоточие.

По способу создания различают статическое и динамическое меню. Статическое меню создается заранее и не изменяется в процессе рабо­ты программы. Динамическое меню возможно изменять в зависимости от нужд приложения.

Наиболее простым способом создания меню является его описание как ресурса в файле ресурсов с расширением гс. Описание меню имеет следующий вид:

идентификатор_меню MENU        [load]    [mem] BEGIN

END

Параметр load необязателен. Он используется для определения мо­мента загрузки меню в память. Если этот параметр указан как PRELOAD, меню загружается в память сразу после запуска приложе­ния. По умолчанию используется значение LOADONCALL, в этом случае загрузка меню в память происходит только при его отображе­нии.

Параметр тет также необязателен. Он влияет на тип памяти, вы­деляемой для хранения шаблона, и может указываться как FIXED (ре­сурс всегда остается в фиксированной области памяти), MOVEABLE (при необходимости ресурс может перемещаться в памяти, это значе­ние используется по умолчанию) или DISCARDABLE (если ресурс больше не нужен, занимаемая им память может быть использована для других задач). Значение DISCARDABLE может использоваться вместе со значением MOVEABLE.

Между строками BEGIN и END в описании меню располагаются операторы описания строк MENUITEM и операторы описания выпа­дающих меню POPUP.

Оператор MENUITEM имеет следующий формат:

MENUITEM text, id [, param]

Параметр text определяет имя строки меню в двойных кавычках, например, "File". Строка может содержать символы &, \t, \a. Если в строке меню перед буквой стоит знак &, при выводе меню данная бук­ва будет подчеркнута. Например, строка "&File" будет отображаться как "File". Клавиша, соответствующая подчеркнутой букве, может быть использована в комбинации с клавишей <Alt> для ускоренного выбора строки. Для того чтобы записать в строку сам символ &, его следует повторить дважды. Аналогично, для записи в строку меню символа двойной кавычки его также следует повторить дважды.

Символ \t включает в строку меню символ табуляции и может быть использован при выравнивании текста в таблицах. Этот символ обыч­но используется только во выпадающих и плавающих меню, но не в основном меню приложения, расположенном под заголовком главного окна.

Символ \а выравнивает текст по правой границе выпадающего меню или полосы меню.

Параметр id представляет собой целое число, которое должно од­нозначно идентифицировать строку меню. Приложение получит это число в параметре wParam сообщения WMCOMMAND, когда будет выбрана данная строка.

Необязательный параметр рагат указывается как совокупность ат­рибутов, разделенных запятой или пробелом. Атрибуты, приведенные ниже, определяют внешний вид и поведение строки меню:

•            CHECKED при выводе меню на экран строка меню отмеча­ется галочкой;

•            GRAYED строка меню отображается серым цветом и нахо­дится в неактивном состоянии. Такую строку нельзя выбрать. Этот ат­рибут несовместим с атрибутом INACTIVE;

•            HELP слева от текста располагается разделитель в виде вер­тикальной линии;

•            INACTIVE строка меню отображается в нормальном виде (не серым цветом), но находится в неактивном состоянии. Этот атрибут несовместим с атрибутом GRAYED;

•            MENUBREAK если описывается меню верхнего уровня, элемент меню выводится с новой строки. Если описывается выпадаю­щее меню, элемент меню выводится в новом столбце;

•            MENUBARBREAK аналогично атрибуту MENUBREAK, но дополнительно новый столбец отделяется вертикальной линией (ис­пользуется при создании выпадающих меню).

Для описания выпадающих меню используется оператор POPUP:

POPUP text [, param] BEGIN

END

Между строками BEGIN и END в описании выпадающего меню располагаются операторы описания строк MENUITEM и операторы описания вложенных меню POPUP. Параметры text и рагат указыва­ются так же, как и для оператора MENUITEM.

Для того чтобы создать в меню горизонтальную разделительную линию, используется специальный вид оператора MENUITEM:

MENUITEM SEPARATOR

Поясним сказанное выше на простом примере. Пусть необходимо

создать главное меню, включающее пункты File, Test и Help, причем пунктам File и Help соответствует выпадающее меню из одного пунк­та, пункту Test выпадающее меню из трех пунктов. Такое меню бу­дет описано в файле ресурсов следующим образом:

MYAPP MENU DISCARDABIiE BEGIN

POPUP "File" BEGIN

MENUITEM "Exit", 101 END

POPUP "Test" BEGIN

MENUITEM "Item 1", 201

MENUITEM "Item 2", 202

MENUITEM "Item 3", 203 END

POPUP "Help" BEGIN

MENUITEM "About My Application…", 301 END END

При выборе пункта «File» окно приложения имеет вид, представ­ленный на рисунке 3.1,а, а при выборе пункта «Test» вид, представ­ленный на рисунке 3.1,6.


Рисунок 3.1

Следующий этап после создания ресурса меню подключение ме­ню к окну приложения.

Подключить меню можно на этапе регистрации класса окна или для отдельного окна при его создании функцией CreateWindow(Ex).

Если при регистрации класса окна в поле IpszMenuName структуры типа WNDCLASS указать адрес текстовой строки, содержащей имя шаблона меню в файле ресурсов, все перекрывающиеся и временные окна, создаваемые на базе этого класса, будут иметь меню, определен­ное данным шаблоном. Дочерние окна (child window) не могут иметь меню. Например, пусть в файле описания ресурсов шаблон меню оп­ределен под именем APPMENU:

APP_MENU MENU BEGIN

END

В этом случае для подключения меню при регистрации класса вы должны записать адрес текстовой строки "APPMENU" в поле IpszMenuName структуры wc, имеющей тип WNDCLASS:

wc.IpszMenuName = "APP_MENU" ;

Когда для класса окна определено меню, все перекрывающиеся и временные окна, создаваемые на базе этого класса, будут иметь меню, если при создании окна функцией CreateWindow указан идентифика­тор меню, равный нулю.

Для подключения меню, отличного от указанного в классе окна, необходимо задать идентификатор нужного меню при создании окна функцией CreateWindow через 9 параметр этой функции дескриптор меню hMenu.

Значение параметра идентификатора меню может быть получено, например, от функции LoadMenu , определенной в программном ин­терфейсе Windows. Параметры LoadMenu:

-   дескриптор текущей копии приложения, полученный через соот­ветствующий параметр функции WinMain;

-   указатель IpszMenuName на строку символов, заканчивающуюся двоичным нулем и содержащую имя загружаемого шаблона меню.

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

Для динамического создания и изменения меню используются функции CreateMenu, AppendMenu, LoadMenuIndirect, InsertMenu, RemoveMenu, SetMenuItemlnfo, CheckMenuItem, EnableMenuItem,

ModifyMenu.

Меню посылает в оконную функцию создавшего его окна следую­щие сообщения. Сообщение WMINITMENU посылается перед ото­бражением меню и может быть использовано для инициализации. Со­общение WMCOMMAND посылается после того, как пользователь выберет одну из активных строк меню. Системное меню посылает в окно приложения сообщение WMSYSCOMMAND, которое обычно не обрабатывается приложением (передается функции DefWindowProc). В процессе выбора строки из меню, когда курсор перемещается по строкам меню, функция окна, создавшего меню, по­лучает сообщение WMMENUSELECT. Перед инициализацией выпа­дающего меню функция окна получает сообщение WMINITMENUPOPUP.

Из всех этих сообщений наибольший интерес представляют сооб­щения WMINITMENU, WMINITMENUPOPUP, WMCOMMAND, WMSYSCOMMAND. Рассмотрим их более подробно.

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

Сообщение WMINITMENUPOPUP посылается окну, когда Windows готова отобразить выпадающее меню. Младшее слово пара­метра IParam содержит порядковый номер выпадающего меню в меню верхнего уровня, старшее слово содержит 1 для системного меню или О для обычного меню. Это сообщение можно использовать для активи­зации или блокирования отдельных строк выпадающего меню.

Сообщение WMMENUSELECT генерируется в процессе переме­щения курсора по строкам меню, его ценность заключается в отобра­жении текущих действий пользователя. Младшее слово wParam со­держит идентификатор пункта меню. Старшее слово wParam содержит состояние пункта меню:

MFCHECKED отмечен;

MFDISABLED заблокирован;

MFGRAYED недоступен;

MFHILITE высвечен;

MFMOUSESELECT выбран мышью;

MFPOPUP открывается выпадающее меню.

Сообщение WMCOMMAND посылается при выборе пункта меню. Параметр wParam содержит идентификатор пункта меню, определен­ный в шаблоне меню. В оконной функции, обрабатывающей сообще­ния от меню, значения параметра wParam проверяются и выполняются соответствующие действия.

Сообщение WMSYSCOMMAND приходит в функцию окна при­ложения, когда пользователь выбирает строку из системного меню. Параметр wParam, как и для сообщения WMCOMMAND, содержит идентификатор строки меню, в данном случае, идентификатор строки системного меню.

Рассмотрим пример обработки выбора пунктов меню в оконной функции. Пусть в файле menu.rc описано меню, состоящее из 4 пунк­тов, каждому из которых назначен свой идентификатор:

#define IDM_TEST 100 #define IDM_HELLO 200 #define IDM_GOODBYE 300 #define IDM_EXIT 400 700 MENU DISCARDABIiE BEGIN

POPUP "&Show" BEGIN

MENUITEM "Test", IDMJTEST MENUITEM "Hello",  IDM_HELLO MENUITEM "Bye",  IDM_GOODBYE MENUITEM "Exit", IDM_EXIT END END

Обработка выбора этих пунктов, за исключением пункта EXIT, за­ключается в выводе текстовых сообщений, описанных как строки, за­вершающиеся двоичными нулями:

szText Test_string,"Test menu item" s z Text Hello_s tring,"Hello! " s z Text Goodbye_s tring,"Bye!"

Оконная функция имеет вид:

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY

invoke PostQuitMessage,NULL

.ELSEIF uMsg==WM_COMMAND mov eax,wParam . IF eax=IDM_TEST

invoke MessageBox, NULL, ADDR Test_string, OFFSET AppName, MB_OK .ELSEIF eax=IDM_HELLO

invoke MessageBox, NULL, ADDR Hello_string, OFFSET AppName,MB_OK .ELSEIF eax=IDM_GOODBYE

invoke MessageBox,NULL,

ADDR Goodbye_string, OFFSET AppName, MB_OK .ELSE

invoke DestroyWindow,hWnd .ENDIF .ELSE

invoke DefWindowProc, hWnd, uMsg, wParam,

lParam ret .ENDIF xor eax,eax ret WndProc endp

Для работы с плавающим меню используется функция Track­PopupMenu, которая выводит плавающее меню на экран и создает собственный цикл обработки сообщений, завершающийся после выбора строки из этого меню. Управление не возвращается до тех пор, пока не будет выбрана строка или пока не будет получен отказ от выбора. Рассмотрим параметры функции:

-  дескриптор плавающего меню. Формируется функцией Create-PopupMenu или GetSubMenu;

-  целое беззнаковое число, биты которого задают параметры для меню (размещение меню по горизонтали и вертикали относительно соответственно координат х и у, задаваемых 3 и 4 параметрами функ­ции TrackPopupMenu, наличие или отсутствие посылки сообщений при выборе строк меню, по правой или левой кнопке мыши выводится плавающее меню);

-  х и у-координаты относительно левого верхнего угла экрана;

-  зарезервированный параметр, равный нулю при вызове;

-  дескриптор окна, которому адресованы сообщения от меню;

-  указатель на прямоугольную область экрана, в пределах которой

щелчки по пунктам меню будут обработаны. Если щелчок будет вне этой области, то плавающее меню исчезнет.

Функция TrackPopupMenu возвращает идентификатор выбранной строки или нулевое значение, если ничего не было выбрано.

Источник: Сучкова, Л.И. Win32 API: основы программирования: учебное пособие/ Л.И. Сучкова; АлтГТУ им. ИИ. Ползунова. -Барнаул, АлтГТУ, 2010. 138 с, ил.

По теме:

  • Комментарии