Что такое код loadmenuindirect

Содержание

LoadMenuIndirectA function

Loads the specified menu template in memory.

Syntax

Parameters

Type: const MENUTEMPLATE*

A pointer to a menu template or an extended menu template. A menu template consists of a MENUITEMTEMPLATEHEADER structure followed by one or more contiguous MENUITEMTEMPLATE structures. An extended menu template consists of a MENUEX_TEMPLATE_HEADER structure followed by one or more contiguous MENUEX_TEMPLATE_ITEM structures.

Return Value

If the function succeeds, the return value is a handle to the menu.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

Remarks

For both the ANSI and the Unicode version of this function, the strings in the MENUITEMTEMPLATE structure must be Unicode strings.

Как отобразить контекстное меню?

Автор: Александр Шаргин

Опубликовано: 25.06.2001
Исправлено: 13.03.2005
Версия текста: 1.0

Создание контекстного меню

Прежде чем отображать контекстное меню, его необходимо загрузить из ресурсов приложения или создать его прямо на лету. Рассмотрим оба способа.

Вариант 1. Создание меню «на лету»

Меню создаётся с помощью функции CreatePopupMenu . Это очень простая функция, которая не принимает параметров и возвращает хэндл созданного меню. В этом меню изначально нет ни одного пункта. Добавить пункты можно, используя функции AppendMenu и InsertMenuItem . Например:

Этот код создаёт стандартное меню, содержащее пункты Undo/Cut/Copy/Paste.

Вариает 2. Загрузка меню из ресурсов

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

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

ПРИМЕЧАНИЕ
В некоторых случаях можно даже не создавать отдельного меню, а «позаимствовать» одно из подменю главного. Например, при щелчке правой кнопкой на панели инструментов или строке состояния уместно отобразить подменю View из главного меню приложения.

Вот фрагмент кода, который загружает меню из ресурсов, а затем извлекает самое первое подменю.

Отображение меню

Для отображения контекстного меню в Win32 API предусмотрена функция TrackPopupMenu(Ex) . В MFC ей соответствует функция CMenu::TrackPopupMenu . Все эти функции выполняют следующие действия: отображают контекстное меню в заданной точке экрана, запускают собственный цикл сообщений, в котором отслеживают выбор пользователя, а в конце, когда пользователь выбрал какой-то пункт или закрыл меню, уведомляют программу о его выборе.

Рассмотрим прототип функции TrackPopupMenu .

Параметр hMenu определяет всплывающее меню, которое следует отобразить. Параметры x и y задают положение меню на экране, а hWnd — окно, которое будет получать все сообщения от меню (этот параметр не может быть равен NULL ). Параметры nReserved и prcRect не используются. Что касается опций, их полный список можно найти в документации. Я хочу обратить ваше внимание только на флаг TPM_RETURNCMD . Если он не задан, программа получит уведомление о выборе пользователя в виде сообщения WM_COMMAND . Если же его задать, функция TrackPopupMenu просто вернёт в программу идентификатор выбранного пользователем пункта меню, не отправляя никаких сообщений.

Уничтожение меню

По окончании работы с меню его следует уничтожить вызовом DestroyMenu . Эта функция получает один параметр — хэндл меню, которое подлежит уничтожению. Обратите внимание, что меню, полученное с помощью GetSubMenu , уничтожать не надо. Оно будет удалено в процессе уничтожения родительского меню, которое вы загрузили с помощью LoadMenu .

WM_CONTEXTMENU

Итак, мы научились отображать контекстное меню. Осталось ответить на последний вопрос: в каком месте программы вызывать рассмотренные выше функции. Первое, что приходит в голову — отобразить меню в ответ на сообщение WM_RBUTTONUP . Но предпочтительнее делать это в обработчике другого сообщения — WM_CONTEXTMENU . У этого сообщения есть целый ряд преимуществ перед WM_RBUTTONUP .

  • Координаты курсора мыши передаются обработчику сразу в экранных координатах и их не придётся конвертировать для передачи в TrackPopupMenu .
  • Дочерние окна, у которых нет собственного контекстного меню, автоматически пересылают WM_CONTEXTMENU родительскому окну. Благодаря этому вы можете, к примеру, написать контекстное меню для диалога, и оно будет вызываться также для всех контролов в этом диалоге (кроме контролов, имеющих собственное меню, таких как edit box).
  • Не будем забывать о клавиатуре. Стандартной комбинацией для вызова контекстного меню является Shift+F10. Когда пользователь нажимает эти клавиши, окно получает WM_CONTEXTMENU (в этом случае координаты курсора устанавливаются равными -1). Благодаря этому вам не придётся отслеживать отдельно вызов контекстного меню с помощью мыши и с помощью клавиатуры.

Вот полный пример обработчика WM_CONTEXTMENU .

В этом примере для извлечения координат курсора мыши используются макросы GET_X_LPARAM и GET_Y_LPARAM . Эти и многие другие полезные макросы описаны в заголовочном файле windowsx.h .

В MFC можно использовать этот код без изменений или переписать его через класс CMenu .

Автоматическое добавление контекстного меню

Если вы программируете с использованием MFC, у вас есть счастливая возможность переложить работу по созданию контекстного меню на среду Visual C++. Для этого откройте окно Project->Add To Project->Components and Controls , а затем выберите компонент Pop-up Menu из папки Visual C++ Components . Появится ещё одно окно, в котором вам предложат выбрать, к какому окну вы хотите добавить контекстное меню, а также идентификатор ресурса меню. Вводите нужные параметры, жмите ОК, и в выбранный класс добавится готовый обработчик OnContextMenu . Кроме этого, в ресурсы вашего приложения добавится новое меню, и вам останется только подредактировать его.

Что такое код loadmenuindirect

I’m using MENUEX_TEMPLATE_HEADER and MENUEX_TEMPLATE_ITEM structures to create a menu with LoadMenuIndirect function

setting header’s or item’s dwHelpId, then passing it to a window class with MAKEINTRESOURCE doesn’t seem to work, so does setting item’s menuId and passing it to the class in the same manner

how in this situation, getting or setting the identifier can be accomplished, so that this identifier can be passed to the window class successfully?

Ответы

setting header’s or item’s dwHelpId, then passing it to a window class with*MAKEINTRESOURCE* doesn’t seem to work

Of course not. dwHelpId has nothing to do with menu resource ID.

You won’t be able to register this custom menu with a window class. When creating a window, the system calls LoadMenu(WNDCLASS::lpszMenuName), which only works for menus statically bound to the application’s resources.

You would have to attach your custom menu to each window with SetMenu.

how in this situation, getting or setting the identifier can be accomplished, so that this identifier can be passed to the window
class successfully?

Создание меню без файла описания ресурсов на основе функции LoadMenuIndirect.

Министерство образования Российской Федерации

Институт переподготовки кадров

Уральского государственного технического университета

Кафедра микропроцессорной техники

ТЕМА: Создание меню без файла описания ресурсов на основе функции

Руководитель доц., к.т.н. В.П.Кулюкин

Слушатель гр. СП-923 И.Г.

Известно, что к программированию на языке ассемблера обращаются тогда, когда от программы требуется максимальная скорость исполнения, когда необходимо обеспечить взаимодействие с нестандартными внешними устройствами, когда необходимо полностью использовать возможности процессора и операционной системы. На языке ассемблера можно запрограммировать все, на что способна соответствующая вычислительная машина, то есть ассемблер является машинно-ориентированным языком программирования. Программируя на ассемблере иногда в силу привычки, иногда в силу необходимости, особенно при организации интерфейса пользователя, приходится многократно программировать одни и те же элементарные задачи. В языках высокого уровня эта проблема решена применением стандартных функций и процедур. В ассемблере эта проблема могла бы быть решена за счет библиотек стандартных функций как на уровне исходных текстов, так и объектных кодов, но такие библиотеки не стандартизованы и не распространяются вместе с компиляторами. С появлением Windows 95 ситуация несколько изменилась. Создание приложений на языке ассемблера представляет собой весьма сложную задачу в связи с высоким уровнем интеграции прикладной программы и операционной системы, но теперь нет необходимости многократно решать проблемы пользовательского интерфейса и управления исполнением команд на уровне машинных команд [I]. Они решаются теперь с помощью операционной системы за счет обращения к функциям интерфейса прикладного программирования – Application Programming Interface (API).
Программирование пользовательского интерфейса с применением функций Win32
API основано на использовании так называемых ресурсов. Ресурсами являются соответствующим образом оформленные данные, используемые операционной системой для создания внешнего отображения органов управления приложением, и средства, обеспечивающие ввод данных в процессе исполнения программы в режиме диалога. Ресурсы описываются в текстовом файле с расширением rc. Файл ресурсов после обработки компилятора ресурсов и получения двоичного файла с расширением res с помощью компоновщика объединяется с исполняемым файлом.

Наиболее очевидным средством управления приложением является меню. Строкаа меню выводится на экран непосредственно под строкой заголовка. Это меню называется главным. Выбор элемента меню влечет за собой выдачу приложения сообщения WD_COMMAND, содержащего идентификатор пункта меню. Идентификаторы анализируются в оконной процедуре приложения, что обеспечивает соответствующую реакцию на полученное сообщение. Каждый пунк меню определяется тремя характеристиками. Первая определяет то, что будет отображаться в данном пункте меню – это либо строка текста, либо картинка.
Вторая характеристика определяет либо константу, посылаемую оконной процедуре сообщении WM_COMMAND, либо всплывающее меню, которое выводится на экран, когда пользователь выбирает данный пункт меню. Третья характеристика указывает, является ли данный пункт меню разрешенным (enabled), запрешенным
(disabled), недоступным (grayed) или помеченным (checked). Эта характеристика пункта меню не является обязательной.
Для того, чтобы включить меню в приложение, необходимо реализовать следующую последовательность шагов:
. разработать сценарий меню. Перед тем как приступить к процессу включения меню в конкретное приложение, разработаем логическую схему. Этот шаг необходим для того, чтобы уже на стадии проектирования обеспечить эргономические свойства приложения. Ведь меню – это один из немногих элементов интерфейса, с которым пользователь постоянно будет иметь дело.

Поэтому схема меню должна иметь наглядную иерархическую структуру, с логически увязанными между собой пунктами этой иерархии, что поможет пользователю эффективно использовать все возможности приложения. Для того, чтобы вести предметный разговор, поставим себе задачу разработать для окна нашего приложения главное меню. При этом мы исследуем возможности вывода в окно приложения текста и графики, а также покажем способы решения общих проблем, связанных с разработкой приложения. Наше меню достаточно простое и состоит из трех элементов: “Текст”,”Графика”,”О приложении”. Иерархическая структура меню представлена.

. описать схему меню в файле ресурсов. Для выполнения этого описания используются специальные операторы.
. составить текст включаемого файла, необходимого для компиляции ресурсного файла
. компилировать ресурсный файл.
. подключить меню на стадии регистрации того окна приложения, для работы с которым оно будет использоваться.
Меню можно создать тремя способами. Можно определить меню в файле описания ресурсов, создать меню без файла описания ресурсов непосредственно в программе с помощью функций CreatMenu, AppendMenu и InsertMenu или с помощью функции LoadMenuIndirect, создав предварительно структуру
MENUITEMPLATE. Наиболее простым и понятным при программировании под
Windows95 на языке ассемблера является определение меню в файле описания ресурсов с помощью любого текстового редактора.

Моя задача заключается в том, чтобы написать программу на тему: “Создать меню без файла описания ресурсов на основе функций LoadMenuIndirect”.
Одним из средств создания меню без использования файла описания ресурсов является функция LoadMenuIndirect. Для применения этой функции необходимо создать шаблон меню, определяемый структурами
MENUITEMTEMPLATEHEADER и MENUITEMTEMPLATE.
Полный шаблон меню состоит из заголовка и хотя бы одного описания пункта меню. Заголовок – структура MENUITEMTEMPLATEHEADER – cостоит из двух полей размером в слово. В первом слове содержится номер версии функции. Для
Windows NT и Win16 это 0, для Windows95-1. Во втором слове содержится смещение до первой структуры MENUITEMTEMPLATE. Если между заголовком и описанием первого пункта меню нет дополнительной информации, это поле содержит 0.
Описания пунктов меню, следущие за заголовком, должны быть выравнены на границе двойного слова. Структура MENUITEMTEMPLATE имеет, как правило, пять полей. Шестое поле имеет смысл для пункта меню, указывающего на всплывающее меню.
В качестве примера приводится окно с главными и всплывающими меню, созданными с помощью функции LoadMenuIndirect.

p386 jumps model flat,STDCALL include win32.inc ;файл описания структур и констант
L equ
IDM_QUIT equ 100
IDM_ABOUT equ 101
MF_ENABLED equ 0
MF_POPUP equ 1h
;Функции Win32 API, используемые программой extrn BeginPaint:PROC extrn CreateWindowExA:PROC extrn DefWindowProcA:PROC extrn DispatchMessageA:PROC extrn EndPaint:PROC extrn ExitProcess:PROC extrn GetMessageA:PROC extrn GetModuleHandleA:PROC extrn LoadCursorA:PROC extrn LoadIconA:PROC extrn RegisterClassA:PROC extrn PostQuitMessage:PROC extrn ShowWindow:PROC extrn TranslateMessage:PROC extrn UpdateWindow:PROC extrn LoadMenuIndirectA:PROC extrn MessageBoxA:PROC

.data newhwnd dd 0 lppaint PAINTSTRUCT msg MSGSTRUCT wc WNDCLASS hInst dd 0 fl dw 0 szTitleName db ‘Это наше окно’,0 szClassName db ‘ASMCLASS32’,0 szHello db ‘Привет!’,0 szAppName db ‘Сообщение’,0 hMenu dd 0 align 4
MenuTemplate dw 1,0 ;Заголовок меню. 1 — признак

;структуры для функции Windows95 align 4 dd 0 ;тип пункта dd 0,MF_ENABLED,0;IDM_ABOUT ; dw 81h dw ‘&’,’M’,’e’,’n’,’u’,’1′,0

align 4 dd 0,0,0,IDM_QUIT dw 0 dw ‘E’,’&’,’x’,’i’,’t’,0,0

align 4 dd 0,0,IDM_ABOUT dw 0 dw ‘&’,’Q’,’u’,’i’,’t’,’1′,0

align 4 dd 0,0,0;IDM_QUIT dw 81h ;Признак вспл. меню dw ‘Q’,’u’,’i’,’t’,’2′,0,0,0

align 4 dd 0,0,IDM_ABOUT dw 0 dw ‘Q’,’u’,’i’,’t’,’3′,0,0

align 4 dd 0,0,IDM_QUIT dw 80h dw ‘E’,’&’,’x’,’i’,’t’,0,0
.code start: push L 0 call GetModuleHandleA mov [hInst], eax
;инициализация структуры WndClass mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW + CS_GLOBALCLASS mov [wc.clsLpfnWndProc], offset WndProc mov [wc.clsCbClsExtra], 0 mov [wc.clsCbWndExtra], 0 mov eax, [hInst] mov [wc.clsHInstance], eax push L IDI_APPLICATION push L 0 call LoadIconA mov [wc.clsHIcon], eax push L IDC_ARROW push L 0 call LoadCursorA mov [wc.clsHCursor], eax mov [wc.clsHbrBackground], COLOR_WINDOW + 1 mov dword ptr [wc.clsLpszMenuName],0 mov dword ptr [wc.clsLpszClassName], offset szClassName push offset wc call RegisterClassA push offset MenuTemplate call LoadMenuIndirectA mov [hMenu],eax push L 0 ; lpParam push [hInst] ; hInstance push [hMenu] ; menu push L 0 ; parent hwnd push L CW_USEDEFAULT ; height push L CW_USEDEFAULT ; width push L CW_USEDEFAULT ; y push L CW_USEDEFAULT ; x push L WS_OVERLAPPEDWINDOW ; Style push offset szTitleName ; Title string push offset szClassName ; Class name push L 0 ; extra style

mov [newhwnd], eax push L SW_SHOWNORMAL push [newhwnd] call ShowWindow

push [newhwnd] call UpdateWindow

msg_loop: push L 0 push L 0 push L 0 push offset msg call GetMessageA cmp ax, 0 je end_loop

push offset msg call TranslateMessage

push offset msg call DispatchMessageA

end_loop: push [msg.msWPARAM] call ExitProcess

; we never get to here

;—-Оконная процедура—-
WndProc proc uses ebx edi esi, hwnd:DWORD, wmsg:DWORD, wparam:DWORD, lparam:DWORD

cmp [wmsg], WM_DESTROY je wmdestroy cmp [wmsg], WM_SIZE je wmsize cmp [wmsg], WM_CREATE je wmcreate cmp [wmsg],WM_PAINT je wmpaint

wmcommand: mov eax,lparam cmp ax,0 jne m1 mov eax,wparam cmp ax,IDM_ABOUT jne m2 call MessageBoxA,0,offset szHello,offset szAppName,MB_OK jmp m1 m2: cmp ax,IDM_QUIT jne m1 push 0 call PostQuitMessage m1: mov eax,0 jmp finish

wmcreate: mov eax, 0 jmp finish

defwndproc: push [lparam] push [wparam] push [wmsg] push [hwnd] call DefWindowProcA jmp finish

wmdestroy: push L 0 call PostQuitMessage mov eax, 0 jmp finish

wmsize: mov eax, 0 jmp finish

wmpaint: push offset lppaint push [hwnd] call BeginPaint mov [hDC],eax push offset lppaint push [hwnd] call EndPaint mov eax,0 jmp finish

finish: ret
WndProc endp
;——————————— public WndProc end start

CMenu::LoadMenuIndirect

Nonzero if the menu resource was loaded successfully; otherwise 0.

Points to a menu template (which is a single structure and a collection of one or more structures). For more information on these two structures, see the Win32 SDK documentation.

Loads a resource from a menu template in memory and attaches it to the CMenu object. A menu template is a header followed by a collection of one or more structures, each of which may contain one or more menu items and pop-up menus.

The version number should be 0.

The mtOption flags should include MF_END for the last item in a pop-up list and for the last item in the main list. See the AppendMenu member function for other flags. The mtId member must be omitted from the MENUITEMTEMPLATE structure when MF_POPUP is specified in mtOption.

The space allocated for the MENUITEMTEMPLATE structure must be large enough for mtString to contain the name of the menu item as a null-terminated string.

Before exiting, an application must free system resources associated with a menu if the menu is not assigned to a window. An application frees a menu by calling the DestroyMenu member function.

Прочитайте онлайн СПРАВОЧНИК ПО WinAPI | LoadMenuIndirect

Описание: function LoadMenuIndirect(var MenuTemplate): HMenu;

Загpужает меню, опpеделенное паpаметpом MenuTemplate.

Паpаметpы:

MenuTemplate: Массив стpуктуp TMenuTemplate.

Возвpащаемое значение:

В случае успешного завеpшения — идентификатоp меню; 0 — в пpотивном случае. функция находится в файле user32.dll

Внимание!

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

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

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

Все права на исходные материалы принадлежат соответствующим
организациям и частным лицам.

Win32 API. Меню

Written on 17 Февраля 2007 . Posted in Win32

ОГЛАВЛЕНИЕ

Строки меню и меню

Меню выстраивается иерархически. На верхнем уровне иерархии стоит строка горизонтальное меню (menu bar); вертикальные или просто меню (menus) выскакивают вниз из строки меню, а в нижних уровнях – подменю (submenus). Строка меню иногда называется меню верхнего уровня (top-level menu), а меню и подменю также известны как всплывающие меню (pop-up menus).

Пункт меню может или выполнить команду или открыть подменю. Пункт, который выполняет команду, называется командным пунктом (command item) или командой (command).

Пункт в горизонтальном меню почти всегда открывает меню. Строки меню редко содержат командные пункты. Меню, открытое из строки меню выскакивает вниз из нее и иногда называется выскакивающее меню (drop-down menu). Когда выскакивающее меню показывается на экране, оно связано со строкой меню. Пункт меню в строке меню, который открывает выскакивающее меню, называется также именем меню (menu name).

Имена меню в строке меню представляют основные категории команд, которые обеспечивает прикладная программа. Выбор имени меню из строки меню обычно открывает меню, пункты которого соответствуют командам в данной категории. Например, строка меню может содержать имя меню Файл (File) которое, когда выбрано пользователем, активизирует меню с пунктами такими как Создать (New), Открыть (Open) и Сохранить (Save).

Только перекрывающее или выскакивающее окно может содержать строку меню; дочернее окно не может содержать её. Если окно имеет область заголовка, Windows устанавливает строку меню прямо под ней. Строка меню всегда видима. Подменю не видимо, но только до тех пор, пока пользователь не выберет пункт меню, который активизирует его. Для получения дополнительной информации о перекрывающих и выскакивающих окнах, см. Общие стили окна.

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

Вспомогательное меню

Windows к тому же предоставляет и вспомогательное меню (shortcut menus). Вспомогательное меню не связано со строкой меню; оно может появляться где угодно на экране. Прикладная программа обычно связывает вспомогательное меню с частями окна, такими как рабочая область или с конкретным объектом, типа пиктограммы. По этой причине, эти меню также называются «контекстные меню».

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

Меню окна

Меню окна (window menu) (известное также как Системное меню (System menu или Control menu)) — всплывающее меню, определяемое и управляемое почти исключительно операционной системой. Пользователь может открыть меню окна щелчком по пиктограмме программы в области заголовка или щелкая правой кнопкой мыши где-нибудь в области заголовка.

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

Когда пользователь выбирает команду из меню окна, Windows отправляет сообщение WM_SYSCOMMAND окну владельцу меню. В большинстве прикладных программ, оконная процедура не обрабатывает сообщения из меню окна. Вместо этого, она просто посылает сообщения в функцию DefWindowProc для обработки сообщения системой по умолчанию. Если прикладная программа добавляет команду в меню окна, оконная процедура должна обрабатывать эту команду.

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

Идентификатор справки

С каждой строкой меню, меню, подменю и вспомогательным меню связан 32-разрядный идентификатор справки. Если пользователь нажимает клавишу F1, в то время, когда меню активно, это значение оправляется окну владельцу как часть сообщения WM_HELP. Для получения дополнительной информации о идентификаторах справки, см. главу Справка.

Дескрипторы меню

Система создает уникальный дескриптор для каждого меню. Дескриптор меню (menu handle) является значением типа HMENU. Прикладная программа должна определять дескриптор меню во многих из функций меню Windows. Вы получаете дескриптор строки меню, когда создаете меню или загружаете ресурс меню. Для получения дополнительной информации о создании и загрузке меню, см. Создание меню.

Чтобы извлечь данные о дескрипторе строки меню для меню, которое было создано или загружено, используется функция GetMenu. Чтобы извлечь данные о дескрипторе подменю, связанного с пунктом меню, используйте функцию GetSubMenu или GetMenuItemInfo. Чтобы извлечь данные о дескрипторе меню окна, используйте функцию GetSystemMenu.

Пункты меню

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

Командные пункты и пункты, которые открывают подменю

Когда пользователь выбирает командный пункт, Windows отправляет сообщение о команде окну, которое владеет меню. Если командный пункт находится в меню окна, Windows отправляет сообщение WM_SYSCOMMAND. Иначе, она посылает сообщение WM_COMMAND.

Дескриптор соответствующего подменю связан с каждым пунктом меню, который его открывает. Когда пользователь указывает на такой пункт, Windows открывает подменю. Окну владельцу никакого сообщения о команде не посылается. Однако Windows отправляет сообщение WM_INITMENUPOPUP окну владельцу меню перед показом на экране подменю. Вы можете получить дескриптор подменю, связанного с пунктом меню при помощи использования функции GetSubMenu или GetMenuItemInfo.

Строка меню обычно содержит имена меню, но она может содержать также и командные пункты. Подменю обычно содержит командные пункты, но оно может содержать также и пункты, которые открывают вложенные подменю. Добавляя такие пункты в подменю, Вы можете вкладывать меню на любую глубину. Чтобы обеспечить пользователя визуальным сигналом, Windows автоматически показывает на экране маленькую стрелку справа от текста пункта меню, который открывает подменю.

Идентификатор пункта меню.

Уникальное, определяемое программой целое число, связанное с каждым пунктом меню, называется идентификатором пункта меню (menu-item identifier). Когда пользователь выбирает командный пункт из меню, Windows отправляет идентификатор пункта окну владельцу как часть сообщения WM_COMMAND. Оконная процедура проверяет идентификатор, чтобы установить источник сообщения и обрабатывает сообщение соответственно. Кроме того, Вы можете определить пункт меню, используя его идентификатор, когда вызываете функции меню; например, чтобы включить или отключить пункт меню.

Идентификатор пункта меню должен быть значением от 0 до 65,535, даже притом, что это — 32-разрядное целое число. Это так потому, что сообщение WM_COMMAND посылает идентификатор пункта меню как младшее слово параметра wParam.

Пункты меню, которые открывают подменю, имеют идентификаторы, точно такие же, что и командные пункты. Однако Windows не отправляет сообщение о команде, когда такой пункт выбран из меню. Вместо этого, Windows открывает подменю, связанное с пунктом меню.

Чтобы извлечь данные об идентификаторе пункта меню в заданной позиции, используйте функцию GetMenuItemID или GetMenuItemInfo.

Позиция пункта меню

В дополнение к наличию уникального идентификатора, каждый пункт меню в строке меню или меню имеет уникальное значение позиции. Самый крайний левый пункт в горизонтальном меню или верхний пункт в меню, имеет позицию нуль. Значение позиции увеличивается на единицу для последующих пунктов меню. Windows присваивает значение позиции всем пунктам в меню, включая разделители.

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

Заданные по умолчанию пункты меню

Подменю может содержать один заданный по умолчанию пункт меню. Когда пользователь открывает подменю, дважды щелкая мышью, Windows отправляет сообщение о команде окну владельцу меню и закрывает меню, как будто был выбран заданный по умолчанию командный пункт. Если нет никакого заданного по умолчанию командного пункта, подменю остается открытым. Чтобы извлечь данные и установить заданный по умолчанию пункт для подменю, используйте функции GetMenuDefaultItem и SetMenuDefaultItem.

Пункты меню с галочкой и без галочки

Пункт меню может быть или отмечен «галочкой» или без «галочки». Windows показывает на экране точечный рисунок рядом с отмеченными пунктами меню, чтобы обозначить их отмеченное состояние с «галочкой». Windows не показывает на экране точечный рисунок рядом с пунктами без «галочки», если определяемый программой точечный рисунок «без «галочки»» не определен. В меню только пункты могут быть отмечены «галочкой»; в строке меню командные пункты не могут быть отмечены «галочкой».

Прикладные программы обычно отмечают «галочкой» или снимают отметку «галочкой» в пункте меню, чтобы указать, который из нескольких параметров действует. Например, предположим, что прикладная программа имеет инструментальную панель, которую пользователь может показывать или скрывать при помощи использования команды Toolbar в меню. Когда инструментальная панель скрыта, у пункта меню Toolbar нет отметки «галочкой». Когда пользователь выбирает команду, прикладная программа отмечает «галочкой» пункт меню и показывает инструментальную панель.

Атрибут метки «галочкой » проверяет, отмечен ли пункт меню «галочкой». Вы можете установить атрибут отметки «галочкой » пункта меню при помощи использования функции CheckMenuItem. Вы можете использовать функцию GetMenuState, чтобы установить, отмечен или не отмечен в настоящее время пункт меню «галочкой».

Вместо CheckMenuItem и GetMenuState, Вы можете использовать функции GetMenuItemInfo и SetMenuItemInfo, чтобы извлекать данные и устанавливать наличие отметки «галочкой» в пункте меню.

Иногда, группа пунктов меню соответствует набору взаимоисключающих параметров. В этом случае, Вы можете обозначать выбранный параметр при помощи использования отметки пункта меню «радиоселектором» («радиоселектор» аналогичен органу управления «радио-кнопке»). Отметки пунктов меню «радиоселектором» отображаются точечным рисунком маркера вместо точечного рисунка отметки «галочкой». Чтобы отметить пункт меню и сделать его пунктом с «радиоселектором», используйте функцию CheckMenuRadioItem.

По умолчанию, Windows показывает на экране отметку «галочкой» или точечный рисунок «радиоселектора» рядом с отмеченными пунктами меню и без точечного рисунка рядом со снятыми отметками «галочкой» пунктами меню. Тем не менее, Вы можете использовать функцию SetMenuItemBitmaps, чтобы ассоциировать определяемые программой точечные рисунки отметки и снятие отметки «галочкой» с пунктом меню. Windows затем использует заданные точечные рисунки, чтобы указать состояние пункта меню с «галочкой» или без отметки «галочкой».

Определяемые программой точечные рисунки, связанные с пунктом меню, должны быть того же самого размера, как и заданный по умолчанию точечный рисунок «галочки», габариты которого могут изменяться в зависимости от разрешающей способности экрана. Чтобы извлечь данные о правильных размерах, используйте функцию GetMenuCheckMarkDimensions. Вы можете создавать многокомпонентные растровые ресурсы для различных разрешений экрана; создайте один растровый ресурс, и, в случае необходимости, масштабируйте его; или создайте точечный рисунок во время выполнения программы и рисуйте изображение в нем. Точечные рисунки могут быть или одноцветные или цветные. Однако, поскольку пункты меню, когда выделяются, инвертируются, внешний вид некоторых инвертированных цветных точечных рисунков может быть не самый лучший. Для получения дополнительной информации, см. Точечные рисунки.

Включенные, недоступные и заблокированные пункты меню

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

Когда пункты меню не доступны пользователю, они должны быть серыми или заблокированными. Недоступные и заблокированные пункты меню не могут быть выбраны. Заблокированный пункт выглядит точно так же как включенный пункт. Когда пользователь нажимает на заблокированный пункт, он не выбирается и ничего не происходит. Заблокированные пункты могут быть полезны, например, в руководстве, показывающем меню, которое выглядит активным, но (в учебных целях) не является таковым.

Прикладная программа окрашивает в серый цвет недоступный пункт меню, чтобы обеспечить визуальный сигнал пользователю, что команда не доступна. Вы можете использовать недоступный пункт, когда действие не соответствующе (например, Вы можете окрашивать в серый цвет команду Печать (Print) в меню Файл (File), когда в системе принтер не установлен).

Функция EnableMenuItem включает, окрашенный в серый цвет или отключенный пункт меню. Чтобы установить, каким является пункт меню включенным, недоступным или заблокированным, используйте функцию GetMenuItemInfo.

Вместо GetMenuItemInfo, Вы можете использовать также и функцию GetMenuState, чтобы установить включен, недоступен или заблокирован пункт меню.

Выделенные пункты меню

Windows автоматически выделяет пункты меню, когда пользователь выбирает их. Тем не менее, выделение может быть явно добавлено или удалено с имени пункта в строке меню при помощи использования функция HiliteMenuItem. Эта функция не имеет никакого влияния на пункты в меню. Когда HiliteMenuItem используется, чтобы выделить название меню, несмотря на это, имя появляется только тогда, когда оно выбрано. Если пользователь нажимает клавишу ENTER, подсвеченный пункт не выбирается. Эта функция может быть полезной, например, в прикладной программе подготовки, которая показывает использование меню.

Нарисованные пользователем (собственные) пункты меню

Прикладная программа может полностью управлять внешним видом пункта меню при помощи использования нарисованного пользователем (собственного) пункта (owner-drawn item). Нарисованные пользователем пункты требуют, чтобы приложение брало всю ответственность на себя за состояние прорисовки выбора (выделения), «галочки» и снятие отметки «галочкой». Например, если прикладная программа предоставляет меню шрифта, она может прописывать каждый пункт меню при помощи использования соответствующего шрифта; пункт для Латинского шрифта будет прописан латинским, пункт для Курсива будет прописан курсивом и так далее.

Для получения дополнительной информации, см. Создание нарисованных пользователем пунктов меню.

Разделители пунктов меню и переносы строк

Windows предоставляет специальный тип пункта меню, называемый разделителем (separator), который появляется в виде горизонтальной линии. Вы можете использовать разделитель, чтобы поделить меню на группы родственных пунктов. Разделитель не может быть использован в строке меню, а пользователь не может выбрать разделитель.

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

Когда меню содержит большее количество пунктов, чем может поместиться в одном столбце, Windows автоматически разрывает меню на два или несколько столбцов. Вы можете заставить сделать разрыв столбца в конкретном пункте в меню, присваивая пункту флажок типа MFT_MENUBREAK. Windows размещает этот пункт и все последующие пункты в новом столбце. Флажок типа MFT_MENUBARBREAK имеет то же самое влияние, за исключением того, что между новым и старым столбцом появляется вертикальная линия.

Если Вы используете функции AppendMenu, InsertMenu или ModifyMenu, чтобы назначить переносы строк, Вы должны присвоить типовые флажки MF_MENUBREAK или MF_MENUBARBREAK.

Доступ к меню с клавиатуры

Windows для меню предоставляет стандартный интерфейс с клавиатурой. Вы можете расширять этот интерфейс, предоставляя мнемонические клавиши доступа и клавиши — ускорители для ваших пунктов меню. Ниже следующие темы описывают стандартный интерфейс клавиатуры, клавиши доступа и сочетание быстрых клавиш.

Стандартный (общепринятый) интерфейс клавиатуры

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

  • Буквенный символ — Выбирает первый пункт меню с заданным символом как клавиша доступа. Если выбранный пункт вызывает меню, меню отображается, а первый пункт выделяется. Иначе, пункт меню выбирается.
  • ALT — Переключает в режим или из режима строки меню.
  • ALT+SPACEBAR — Показывает на экране меню окна.
  • ENTER — Активизирует меню и выбирает его первый пункт, если пункт связан с этим меню. Иначе, это нажатие клавиши выбирает пункт, как будто пользователь отпустил кнопку мыши, в то время когда пункт был выбран.
  • ESC — Выход из режима меню.
  • LEFT ARROW (стрелка влево) — Циклически передвигается к предыдущему пункту меню верхнего уровня. Пункты меню верхнего уровня включают в себя имена меню и меню окна. Если выбранный пункт находится в меню, выбирается предыдущий столбец в меню или предыдущий пункт меню верхнего уровня.
  • RIGHT ARROW (стрелка вправо) — Работает подобно клавише СТРЕЛКА ВЛЕВО, за исключением того, что действует в противоположном направлении. В меню, это нажатие клавиши перемещает вперед на один столбец; когда текущий выбранный пункт находится в крайне правом столбце, выбранным является следующее меню.
  • UP или DOWN ARROWS (стрелки вверх или вниз) — Активизирует меню, когда нажимается на имени меню. Когда нажимается в меню, нажатие клавиши СТРЕЛКА ВВЕРХ выбирает предыдущий пункт; нажатие клавиши СТРЕЛКА ВНИЗ выбирает следующий.

Клавиши доступа к меню

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

Чтобы создать клавишу доступа для пункта меню, пред любым символом в текстовой строке пункта проставьте амперсанд. Например, текстовая строка «&Move» принуждает Windows подчеркнуть символ «M«.

Быстрые клавиши меню

В дополнение к имеемым клавишам доступа, пункт меню может иметь быструю клавишу, связанную с ним. Быстрая клавиша(сочетание клавиш) отличается от клавиши доступа тем, что меню, чтобы сработать по быстрой клавише, не должно быть активным. К тому же, клавиша доступа всегда связана с пунктом меню, в то время как быстрая клавиша — обычно (но не обязательно) связана с пунктом меню.

Текст, который идентифицирует быструю клавишу, добавляется в текстовую строку пункта меню. Текст клавишной комбинации быстрого вызова появляется справа от названия пункта меню, после наклонной черты влево (обратного слэша) и символа табуляции (\t). Например, «&Close\tAlt+F4» представляет команду Закрыть (Close) с комбинацией клавиш ALT+F4 как быстрой клавиши и с символом «C» как клавишей доступа. Для получения дополнительной информации, см. Ускорители клавиатуры.

Создание меню

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

Ресурсы шаблона меню

Большинство прикладных программ создает меню, используя ресурсы шаблона меню. Шаблон меню (menu template) определяет меню, включая в себя пункты в строке меню и всех меню. За информацией о создании ресурса шаблона меню, см. документацию, включенную в ваши инструментальные средства разработки.

После того, как Вы создадите ресурс шаблона меню и добавите его к исполняемому (.EXE) файлу вашего приложения, Вы можете использовать функцию LoadMenu, чтобы загрузить этот ресурс в память. Эта функция возвращает значение дескриптора меню, который Вы можете затем присваивать окну при помощи использования функции SetMenu.

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

Шаблон меню в памяти

Меню может быть создано из шаблона меню, который формируется в памяти во время выполнения программы. Например, прикладная программа, которая позволяет пользователю настраивать свое меню, может создать шаблон меню в памяти, основанной на стандартных установках пользователя. Приложение может затем сохранить шаблон в файле или в системном реестре для будущего использования. Чтобы создать меню из шаблона в памяти, используйте функцию LoadMenuIndirect. За описаниями форматов шаблона меню, обратись к статье Использование ресурса шаблона меню.

Стандартный шаблон меню состоит из структуры MENUITEMTEMPLATEHEADER, сопровождаемой одной или несколькими структурами MENUITEMTEMPLATE.

Расширенный шаблон меню состоит из структуры MENUEX_TEMPLATE_HEADER, сопровождаемой одной или несколькими структурами MENUEX_TEMPLATE_ITEM.

Функции создания меню

Используя функции создания меню, Вы можете создавать меню во время выполнения программы или добавлять пункты меню к существующим меню. Вы можете использовать функцию CreateMenu, чтобы создать пустую строку меню и функцию CreatePopupMenu, чтобы создать пустое меню. Чтобы добавлять пункты к меню, используйте функцию InsertMenuItem. Устаревшие функции AppendMenu и InsertMenu все еще поддерживаются, но для новых прикладных программ должна быть использована функция InsertMenuItem.

Показ меню на экране

После того, как меню было загружено или создано, оно должно быть связано с окном до того, как Windows сможет показать его на экране. Вы можете предназначить меню, при помощи определения меню класса. Для получения дополнительной информации о меню класса, см. Меню класса окна. Вы можете также предназначить меню для окна, при помощи определения дескриптора меню как параметра hMenu функции CreateWindow или CreateWindowEx или путем вызова функции SetMenu.

Чтобы показать на экране вспомогательное меню используют функцию TrackPopupMenuEx. Вспомогательное меню, также называемое плавающим, выскакивающим или контекстным меню, обычно показывается на экране, когда обрабатывается сообщение WM_CONTEXTMENU.

Устаревшая функция TrackPopupMenu все еще поддерживается, но новые прикладные программы должны использовать функцию TrackPopupMenuEx.

Меню класса окна

Вы можете определить заданное по умолчанию меню, называемое меню класса (class menu), когда регистрируете класс окна. Чтобы сделать так, присвойте имя ресурса шаблона меню элементу lpszMenuName структуры WNDCLASS, используемой для регистрации класса.

По умолчанию, каждому окну назначается меню класса для класса окна, так что вам не нужно явно загружать меню и присваивать его каждому окну. Вы можете заменять меню класса, при помощи определения другого дескриптора меню при вызове функции CreateWindowEx. Вы можете также изменить меню окна после того, как оно создано при помощи использования функция SetMenu. Для получения дополнительной информации, см. Классы окна.

Разрушение Меню

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

Сообщения, используемые меню

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

Когда пользователь активизирует пункт в горизонтальном меню, окно владелец сначала получает сообщение WM_SYSCOMMAND. Это сообщение включает в себя флажок, который указывает, активизировал ли пользователь меню при помощи использования клавиатуры (SC_KEYMENU) или мыши (SC_MOUSEMENU). Для получения дополнительной информации об интерфейсе клавиатуры для меню, см. Доступ к меню через клавиатуру.

Затем, перед показом на экране любых меню, Windows посылает сообщение WM_INITMENU оконной процедуре так, чтобы прикладная программа могла изменить меню до того, как пользователь увидит их. Windows отправляет сообщение WM_INITMENU только однажды для активизации меню.

Когда пользователь указывает на пункт меню, который открывает подменю, Windows, отправляет окну владельцу сообщение WM_INITMENUPOPUP перед отображением на экране подменю. Это сообщение дает прикладной программе возможность изменить подменю прежде, чем оно покажется на экране.

Каждый раз, когда пользователь перемещает выделение от одного пункта меню к другому, Windows отправляет сообщение WM_MENUSELECT оконной процедуре окна владельца меню. Это сообщение идентифицирует текущий выбранный пункт меню. Многие из прикладных программ предоставляют информационную область внизу своих основных окон и используют это сообщение, чтобы показать на экране дополнительную информацию о выбранном пункте меню.

Когда пользователь выбирает командный пункт из меню, Windows отправляет оконной процедуре сообщение WM_COMMAND. Младшее слово параметра wParam сообщения WM_COMMAND содержит идентификатор выбранного пункта. Оконная процедура должна проверить идентификатор и обработать сообщение соответственно.

Не все меню являются доступными через строку меню окна. Многие из прикладных программ показывают на экране вспомогательное меню, когда пользователь щелкает мышью по правой кнопке мыши в конкретном месте. Такие прикладные программы, если это им свойственно, должны обрабатывать сообщение WM_CONTEXTMENU и показывать на экране вспомогательное меню. Если прикладная программа не показывает на экране вспомогательное меню, она должна передать сообщение WM_CONTEXTMENU функции DefWindowProc для обработки по умолчанию.

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

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

Чтобы добавить пункт меню, используйте функцию InsertMenuItem. Вы можете использовать функцию SetMenuItemInfo, чтобы изменить атрибуты существующего пункта меню. Параметр lpmii указывает на структуру MENUITEMINFO, которая содержит новые атрибуты и определяет, какие атрибуты изменяются. Атрибуты пункта меню включают в себя тип, состояние, идентификатор, подменю, точечные рисунки, данные пункта и текст.

Устаревшие функции AppendMenu и InsertMenu могут быть также использованы, чтобы добавить пункты меню, но новые прикладные программы должны использовать InsertMenuItem. Функция AppendMenu добавляет в конец пункт меню или подменю; функция InsertMenu вставляет пункт меню в заданной позиции в меню или подменю. Обе функции дают возможность атрибутам пункта меню быть определяемыми, включая в себя в любом случае, включение, блокирование, недоступность, отметку «галочкой или снятие отметки «галочкой» пункта меню.

Чтобы изменить внешний вид или атрибуты существующего пункта меню, используйте функцию ModifyMenu. Например, текстовая строка или точечный рисунок пункта меню могут быть включены, заблокированы, недоступны, отмечены «галочкой» или со снятой «галочкой». Функция ModifyMenu заменяет определяемый пункт меню на новый пункт.

Чтобы извлечь информацию о пункте меню, используйте функцию GetMenuItemInfo. Параметр lpmii указывает на структуру MENUITEMINFO, которая определяет извлекаемые атрибуты и принимает их текущие значения.

Чтобы удалить пункт меню из меню, используйте функцию DeleteMenu или RemoveMenu. Если удаляемый пункт тот, который открывает подменю, DeleteMenu удаляет связанное подменю, сбрасывая дескриптор меню и освобождая память, использованную подменю. Функция RemoveMenu удаляет пункт меню, но если пункт открывает подменю, функция не уничтожает подменю или дескриптор, позволяя подменю многократно использоваться.

Чтобы перерисовывать строку меню, после того как строка меню была изменена, используйте функцию DrawMenuBar. Иначе, изменения не появятся до тех пор, пока Windows не перерисует окно владельца.

Использование меню

Использование ресурса шаблона меню
Создание вспомогательного (контекстного) меню
Использование точечных рисунков пунктов меню
Создание нарисованных пользователем пунктов меню
Использование пользовательских точечных рисунков «галочки «

Использование ресурса шаблона меню

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

Расширенный формат шаблона меню

Расширенный формат шаблона меню поддерживает функциональные возможности меню, выполненные для версий Windows 95 и Windows NT 4.0. Подобно ресурсам шаблона меню, использованным с более ранними версиями Windows, расширенные ресурсы шаблона меню имеют тип ресурса RT_MENU. Windows различает два формата ресурса по номеру версии, который является первым элементом заголовка ресурса.

Расширенный шаблон меню состоит из структуры MENUEX_TEMPLATE_HEADER, сопровождаемой еще одной структурой MENUEX_TEMPLATE_ITEM определяющей пункты.

Старый формат шаблона меню

Старый шаблон меню (для версий Windows ранее, чем Windows 95 и Windows NT 4.0) задает меню, но не поддерживает его новые функциональные возможности. Старый ресурс шаблона меню имеет тип ресурса RT_MENU.

Старый шаблон меню состоит из структуры MENUITEMTEMPLATEHEADER, сопровождаемой одним или большим количеством структур MENUITEMTEMPLATE.

Загрузка ресурса шаблона меню

Чтобы загрузить ресурс шаблона меню, используйте функцию LoadMenu, определяя дескриптор модуля, который содержит ресурс и идентификатор шаблона меню. Функция LoadMenu возвращает дескриптор меню, который Вы можете использовать для привязки меню к окну. Это окно становится окном владельцем меню, принимая все сообщения, созданные меню.

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

Чтобы привязать меню к окну, используйте функцию SetMenu, или определите дескриптор меню в параметре hMenu функции CreateWindowEx при создании окна. Другим способом, которым Вы можете привязать меню к окну, является определение шаблона меню, когда Вы регистрируете класс окна; шаблон идентифицирует определяемое меню как меню класса для этого класса окна.

Чтобы Windows автоматически связал конкретное меню с окном, определите шаблон меню, когда Вы регистрируете класс окна. Шаблон идентифицирует определяемое меню как меню класса для этого класса окна. Тогда, когда Вы создаете окно данного класса, Windows автоматически связывает заданное меню с окном.

Чтобы создать меню класса, включите идентификатор ресурса шаблона меню как член lpszMenuName структуры WNDCLASS, а затем передайте адрес структуры в функцию RegisterClass.

Создание меню класса

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

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

Ниже следует важная часть самого приложения:

Создание вспомогательного (контекстного) меню

Чтобы использовать контекстное меню в прикладной программе, передайте ее дескриптор в функцию TrackPopupMenuEx. Приложение обычно вызывает TrackPopupMenuEx в оконной процедуре в ответ на сгенерированное пользователем сообщение, типа WM_LBUTTONDOWN или WM_KEYDOWN.

В дополнение к дескриптору выскакивающего меню, TrackPopupMenuEx требует, чтобы вы определили дескриптор окна владельца, позицию контекстного меню (в экранной системе координат) и кнопку мыши, которую пользователь может использовать, чтобы выбрать пункт.

Устаревшая функция TrackPopupMenu все еще поддерживается, но новые прикладные программы должны использовать функцию TrackPopupMenuEx. Функция TrackPopupMenuEx требует тех же самых параметров, что и TrackPopupMenu и, к тому же, позволяет вам определить часть экрана, которое меню не должно закрывать. Прикладная программа обычно вызывает эти функции в оконной процедуре при обработке сообщения WM_CONTEXTMENU.

Вы можете определить позицию контекстного меню, предоставляя x- и y-координаты вместе с флажком TPM_CENTERALIGN, TPM_LEFTALIGN или TPM_RIGHTALIGN. Флажок определяет позицию контекстного меню относительно x- и y-координат.

Вы должны дать возможность пользователю выбирать пункт из контекстного меню при помощи использования той же самая кнопки мыши, которая использовалась, чтобы показать на экране меню. Чтобы делать это, определите или флажок TPM_LEFTBUTTON или TPM_RIGHTBUTTON, чтобы указать, которую кнопку мыши пользователь может использовать, чтобы выбрать пункт меню.

Обработка сообщения WM_CONTEXTMENU

Сообщение WM_CONTEXTMENU создается тогда, когда оконная процедура прикладной программы посылает функции DefWindowProc сообщение WM_RBUTTONUP или WM_NCRBUTTONUP. Приложение может обработать это сообщение, чтобы показать на экране контекстное меню, в соответствующей конкретной части экрана. Если прикладная программа не показывает на экране контекстное меню, она должна передать это сообщение в DefWindowProc для обработки по умолчанию.

Ниже следует пример обработки сообщения WM_CONTEXTMENU, как оно может фигурировать в оконной процедуре прикладной программы. Младшие и старшие слова параметра lParam определяют экранную систему координат мыши, когда отпускается правая кнопка мыши. Определяемая программой функция OnContextMenu возвращает значение ИСТИНА (TRUE), если она показывает на экране контекстное меню или ЛОЖЬ (FALSE) если она этого не делает.

Следующая определяемая программой функция OnContextMenu показывает на экране контекстное меню, если определяемая позиция мыши внутри рабочей области окна. Более сложная функция могла бы показывать на экране одно из нескольких различных меню, в зависимости оттого, которая часть рабочей области определена. Чтобы фактически показывать на экране контекстное меню, этот пример вызывает определяемую программой функцию по имени DisplayContextMenu. За описанием этой функции, обратитесь к статье Отображение на экране контекстного меню.

Создание контекстного меню Атрибуты Шрифта (Font-Attributes)

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

Здесь шаблон меню для контекстного меню, который дается в файле определения ресурса прикладной программы.

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

Отображение на экране контекстного меню

Функция, приведенная в следующем примере, показывает на экране контекстное меню.

Прикладная программа включает в себя ресурс меню, идентифицированный строкой «ShortcutExample«. Строка меню просто содержит название меню. Прикладная программа использует функцию TrackPopupMenu, чтобы показать на экране меню, связанное с этим пунктом меню. (Сама строка меню не отображается, потому что TrackPopupMenu требует дескриптора меню, подменю или контекстного меню.)

Использование в пунктах меню точечных рисунков (значков)

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

Прикладные программы, написанные в более ранних версиях Windows, могут устанавливать флажок MF_BITMAP со старыми наборами функций.

Установка флажка типа значка

Флажок MFT_BITMAP или MF_BITMAP сообщают, чтобы Windows преимущественно использовал точечный рисунок (значок), а не текстовую строку, чтобы показать на экране пункт меню. Флажок пункта меню MFT_BITMAP или MF_BITMAP должен быть установлен во время выполнения программы; Вы не можете установить его в файле определения ресурса.

Для новых прикладных программ, Вы можете использовать функцию SetMenuItemInfo или InsertMenuItem, чтобы установить флажок типа MFT_BITMAP. Чтобы заменить текстовый пункт меню на значок пункта меню, используйте SetMenuItemInfo. Чтобы добавить новый значок пункта к меню, используйте функцию InsertMenuItem.

Прикладные программы, написанные для более ранних версиий Windows, чтобы установить флажок MF_BITMAP, могут продолжать использовать функции ModifyMenu, InsertMenu или AppendMenu. Чтобы заменить текстовую строку пункта меню на значок пункта меню, используйте ModifyMenu. Чтобы добавить новый значок пункта меню, используйте флажок MF_BITMAP с функцией InsertMenu или AppendMenu.

Создание точечного рисунка (значка)

Когда Вы устанавливаете флажок типа MFT_BITMAP или MF_BITMAP для пункта меню, Вы должны также определить и дескриптор точечного рисунка (значка), который Windows должен отобразить для пункта меню. Вы можете представить значок как растровый ресурс или создавать точечный рисунок во время выполнения программы. Если Вы используете растровый ресурс, Вы можете использовать функцию LoadBitmap, чтобы загрузить значок и получить его дескриптор.

Чтобы создать значок во время выполнения программы, используйте функции графического интерфейса устройства (GDI). GDI предоставляет несколько способов, чтобы создать значок во время выполнения программы, но разработчики обычно используют следующий метод:

  1. Использовать функцию CreateCompatibleDC, чтобы создать контекст устройства, совместимый с контекстом устройства, использованным основным окном прикладной программы.
  2. Использовать функцию CreateCompatibleBitmap, чтобы создать значок, совместимый с основным окном прикладной программы или использовать функцию CreateBitmap, чтобы создать одноцветный значок.
  3. Использовать функцию SelectObject, чтобы выбрать значок в совместимом контексте устройства.
  4. Использовать рисующие функции GDI, типа Ellipse (Эллипс) и LineTo (Линия), чтобы нарисовать изображение в значок.

Для получения дополнительной информации, см. статью Точечные рисунки.

Добавление меню Линии и Диаграммы

Нижеследующий пример кода показывает, как создать меню, которое содержит значки пунктов меню. Он создает два меню. Первое — меню Chart (Диаграммы), которое содержит три значка пунктов меню: круговая диаграмма, линейная диаграмма и гистограмма. Пример показывает, как загрузить эти значки из файла ресурса прикладной программы, а затем использовать функции CreatePopupMenu и AppendMenu, чтобы создать меню и пункты меню.

Второе меню — меню Lines (Линии). Оно содержит значки, показывая типы линий, предоставляемые предопределенным пером в Windows. Значки типа линий созданы во время выполнения программы при помощи использования функций GDI.

Здесь определения растровых ресурсов в файле определения ресурса прикладной программы.

Здесь находятся необходимые части заголовочного файла прикладной программы.

Пример значков пунктов меню

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

Первое меню содержит пункты меню, которые показывают каждую из трех типов диаграмм: круговую, линейную и гистограмму. Значки для этих пунктов меню определены как ресурсы и загружаются при помощи использования функции LoadBitmap. С этим меню, в горизонтальном меню, связано имя меню «Chart» (Диаграммы).

Второе меню содержит пункты меню, которые показывают каждый из пяти типов линии, использованных с функцией CreatePen: PS_SOLID, PS_DASH, PS_DOT, PS_DASHDOT и PS_DASHDOTDOT. Прикладная программа создает значки для этих пунктов меню во время выполнения программы, используя, рисующие функции GDI. С этим меню, в горизонтальном меню, связано имя меню «Lines» (Линии).

В оконной процедуре прикладной программы заданы два статических массива дескрипторов значков. Один массив содержит дескрипторы трех значков, использованных для меню Chart, другой содержит дескрипторы из пяти значков, использованных для меню Lines. При обработке сообщения WM_CREATE, оконная процедура загружает значки диаграмм, создает значки линий, а затем добавляет соответствующие пункты меню. При обработке WM_DESTROY сообщения, оконная процедура удаляет все значки.

Ниже следуют необходимые части заголовочного файла приложения.

Ниже следуют необходимые части оконной процедуры. Оконная процедура выполняет большинство инициализаций путем вызова определяемой программой функции LoadChartBitmaps, CreateLineBitmaps и AddBitmapMenu, описанные ниже в этом разделе.

Определяемая программой функция LoadChartBitmaps загружает ресурсы значков для меню диаграмм путем вызова функция LoadBitmap, как ниже указано.

Определяемая программой функция CreateLineBitmaps создает значки для меню Lines при помощи использования, рисующих функций GDI. Функция создает контекст устройства в памяти (DC) с теми же самыми свойствами, что и DC главного окна программы. Для каждого типа линии, функция создает значок, выбирает его в DC в памяти и рисует в нем.

Определяемая программой функция AddBitmapMenu создает меню и добавляет заданное число значков меню к его пунктам. Затем она добавляет соответствующее название меню к строке меню определяемого окна.

Создание нарисованных пользователем пунктов меню

Если Вы нуждаетесь в полном контроле над внешним видом пункта меню, Вы можете использовать в вашей прикладной программе нарисованный пользователем пункт меню. Этот раздел описывает шаги, которые приведут к созданию и использованию нарисованного пользователем пункта меню.

Установка флажков при рисовании пользователем пунктов меню

Вы не можете задать нарисованный пользователем пункт меню в файле определения ресурса вашей прикладной программы. Вместо этого, Вы должны создать новый пункт меню или изменить существующий при помощи использования флажка меню MFT_OWNERDRAW.

Вы можете использовать функцию InsertMenuItem или SetMenuItemInfo, чтобы определить нарисованный пользователем пункт меню. Используйте InsertMenuItem, чтобы вставить новый пункт меню в заданной позиции в строке меню или меню. Используйте SetMenuItemInfo, чтобы изменить состав меню.

При вызове этих двух функций, Вы должны определить адрес структуры MENUITEMINFO, которая описывает свойства нового пункта меню или свойства, которые Вы желаете изменить для существующего пункта меню. Чтобы сделать пункт меню, пунктом нарисованным пользователем, определите значение MIIM_TYPE для члена fMask и значение MFT_OWNERDRAW для члена fType структуры.

Устанавливая соответствующие члены структуры MENUITEMINFO, Вы можете связывать определяемое программой значение, которое называется данными пункта (item data), с каждым пунктом меню. Поступая таким образом, определите значение MIIM_DATA для члена fMask и определяемого программой значения для члена dwItemData структуры.

Вы можете использовать данные пункта с любым типом пункта меню, но это особенно полезно для нарисованных пользователем пунктов. Например, предположим, что структура содержит информацию, используемую, чтобы нарисовать пункт меню. Прикладная программа могла бы использовать эти данные пункта для пункта меню, чтобы сохранить указатель на структуру. Данные пункта пересылаются в окно владельца меню с сообщениями WM_DRAWITEM и WM_MEASUREITEM. Чтобы в любое время извлечь данные о пункте для меню, используйте функцию GetMenuItemInfo.

Прикладные программы, написанные в более ранних версиях Windows, могут продолжать вызывать функции AppendMenu, InsertMenu или ModifyMenu, чтобы назначить флажок MF_OWNERDRAW нарисованному пользователем пункту меню.

Когда Вы вызываете любую из этих трех функций, Вы можете передавать 32-разрядное значение как параметр lpNewItem. Это значение может представлять любую информацию, которая является значимой для вашей прикладной программы, и она будет доступна вашему приложению, когда пункт должен отобразиться. Например, значение могло бы содержать указатель на структуру; структура, в свою очередь, могла бы содержать текстовую строку и дескриптор логического шрифта, который ваша прикладная программа будет использовать, чтобы рисовать строку.

Нарисованные пользователем меню и сообщение WM_MEASUREITEM

Прежде, чем Windows покажет на экране нарисованный пользователем пункт меню впервые, она передает сообщение WM_MEASUREITEM оконной процедуре окна, которое владеет пунктами меню. Это сообщение содержит указатель на структуру MEASUREITEMSTRUCT, которая идентифицирует пункт и содержит данные пункта, которые прикладная программа, возможно, присвоила ему. Оконная процедура должна заполнить члены itemWidth и itemHeight структуры перед возвращением из обработки сообщения. Windows использует информацию в этих элементах при создании ограничительного прямоугольника, в котором прикладная программа рисует пункт меню. К тому же она использует эту информацию, чтобы определить, когда пользователь выбирает пункт.

Нарисованные пользователем меню и сообщение WM_DRAWITEM

Всякий раз, когда пункт должен быть прорисован (например, когда он первоначально отображается или когда пользователь выбирается его), Windows отправляет сообщение WM_DRAWITEM оконной процедуре окна владельца меню. Это сообщение содержит указатель на структуру DRAWITEMSTRUCT содержащую информацию о пункте, включая данные о пункте, которые прикладная программа, возможно, присвоила ему. Кроме того, DRAWITEMSTRUCT содержит флажки, которые обозначают состояние пункта (типа того, является ли он недоступным или выбираемым с отметкой галочкой), а также ограничительный прямоугольник и контекст устройства, которые прикладная программа использует, чтобы рисовать пункт.

Прикладная программа должна делать следующее при обработке сообщения WM_DRAWITEM:

  1. Установить тип рисунка, который является необходимым. Чтобы сделать это, проверьте член itemAction структуры DRAWITEMSTRUCT.
  2. Нарисовать соответствующий пункт меню, используя ограничительный прямоугольник и контекст устройства, полученный из структуры DRAWITEMSTRUCT. Прикладная программа должна рисовать только внутри ограничительного прямоугольника. По причинам производительности, Windows не обрезает части изображения, которые прорисованы снаружи прямоугольника.
  3. Восстановить все объекты GDI, выбранные для пунктов меню в контексте устройства.

Если пользователь выбирает пункт меню, Windows устанавливает член itemAction структуры DRAWITEMSTRUCT в значение ODA_SELECT и устанавливает значение ODS_SELECTED в элементе itemState. Это — команда вызова подпрограммы приложения, которая перерисует пункт меню, чтобы указать, что он выбран.

Настройка шрифтов для текстовых строк пункта меню

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

Здесь меню, заданное в файле определения ресурса. Обратите внимание, что строки для пунктов меню Regular (Обычный), Bold (Полужирный), Italic (Курсив) и Underline (Подчеркнутый) назначены во время выполнения программы, так что их строки пусты в файле определения ресурса.

Оконная процедура прикладной программы обрабатывает сообщения, включающие использование нарисованных пользователем пунктов меню. Приложение использует сообщение WM_CREATE, чтобы сделать следующее:

Установить флажок MF_OWNERDRAW для пунктов меню.

Установить строки текста для пунктов меню.

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

Получить значения цвета текста и фона для выбранных пунктов меню.

Дескрипторы текстовых строк и шрифта сохраняются в массиве определяемых программой структур MYITEM. Определяемая программой функция GetAFont создает шрифт, который соответствует атрибутам данного шрифта и возвращает значение дескриптора шрифта. Дескрипторы разрушаются в ходе обработки сообщения WM_DESTROY.

В ходе обработки сообщения WM_MEASUREITEM, пример получает ширину и высоту строки пункта меню и копирует эти значения в структуру MEASUREITEMSTRUCT. Windows использует значения ширины и высоты, чтобы вычислить размер меню.

В ходе обработки сообщения WM_DRAWITEM, строка пункта меню рисуется, оставляя место рядом со строкой для значка «галочки «. Если пользователь выбирает пункт, цвет выбранного текста и фона используются, чтобы прорисовать пункт.

Пример «собственных» пунктов меню

Пример в этой теме использует в меню «собственные» пункты. Пункты меню выбирают конкретные атрибуты шрифта, а прикладная программа показывает на экране каждый пункт меню, используя шрифт, который имеет соответствующий атрибут. Например, пункт меню Italic (Курсив) отображается в курсивном шрифте. Название меню Character (Шрифт) в строке меню открывает меню.

Строка меню и раскрывающееся меню определены вначале расширенным ресурсом шаблона меню. Поскольку шаблон меню не может определять «собственные» пункты, меню вначале содержит четыре текстовых пункта меню со следующими строками: «Regular» («Обычный»), «Bold» («Полужирный»), «Italic» («Курсив») и «UnderlineWM_CREATE. Когда процедура получает сообщение WM_CREATE, она вызывает определяемую программой функцию OnCreate, которая выполняет следующие шаги для каждого пункта меню:

  1. Распределяет в памяти определяемую программой структуру MYITEM.
  2. Получает текст пункта меню и сохраняет его в определяемой программой структуре MYITEM.
  3. Создает шрифт, использованный, чтобы показать на экране пункт меню и сохраняет дескриптор в определяемой программой структуре MYITEM.
  4. Изменяет тип пункта меню на MFT_OWNERDRAW и сохраняет указатель на определяемую программой структуру MYITEM, как на данные пункта.

Поскольку указатель на каждую определяемую программой структуру MYITEM сохраняется как данные пункта, он переходит в оконную процедуру вместе с сообщениями WM_MEASUREITEM и WM_DRAWITEM для соответствующего пункта меню. Указатель содержится в члене itemData и структуры MEASUREITEMSTRUCT и структуры DRAWITEMSTRUCT.

Сообщение WM_MEASUREITEM отправляется для каждого «собственного» пункта меню, когда он впервые отображается на экране. Приложение обрабатывает это сообщение, выбирая шрифт для пункта меню в контекст устройства, а затем устанавливает пространство, требуемое, чтобы показать на экране текст пункта меню этим шрифтом. Шрифт и текст пункта меню оба определены структурой пункта меню MYITEM (структура, определенная прикладной программой). Приложение устанавливает размер текста при помощи использования функции GetTextExtentPoint32.

Оконная процедура обрабатывает сообщение WM_DRAWITEM, показывая на экране текст пункта меню в соответствующем шрифте. Шрифт и текст пункта меню оба определены структурой пункта меню MYITEM. Прикладная программа выбирает текст и цвета фона, соответствующие состоянию пункта меню.

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

Ниже следуют необходимые части заголовочного файла прикладной программы.

Ниже следуют необходимые части оконной процедуры прикладной программы и связанных функций.

Использование индивидуальных значков типа «галочки»

Windows предоставляет заданный по умолчанию значок «галочки » для отображения на экране рядом с пунктом меню, который отмечается ею. Вы можете настроить индивидуальный пункт меню, при помощи предоставления пары точечных рисунков (значков), чтобы заменить заданный по умолчанию значок «галочки «. Windows показывает на экране один значок, когда пункт отмечен «галочкой», а другой, когда у него отметка «галочкой» снята. Этот раздел описывает шаги, приводящие к созданию и использованию пользовательских точечных рисунков (значков) типа «галочки «.

Создание пользовательских точечных рисунков (значков) типа «галочки»

Пользовательский точечный рисунок (значок) «галочки» должен быть такого же самого размера как и заданный по умолчанию значок «галочки». Вы можете получить заданный по умолчанию размер значка «галочки» путем вызова функции GetMenuCheckMarkDimensions. Младшее слово величины возвращаемого значения этой функции определяет ширину; старшее слово — высоту.

Вы можете использовать растровые ресурсы, чтобы обеспечить программу значками типа «галочки». Однако, поскольку требуемый размер точечного рисунка изменяется в зависимости от типа дисплея, вам видимо придется по необходимости изменить размеры значка во время выполнения программы при помощи использования функции StretchBlt. Зависимость от значка, искажение, вызываемое изменением размеров, может привести к неприятному результату.

Вместо того, чтобы использовать растровый ресурс, Вы можете создать точечный рисунок (значок) во время выполнения программы при помощи использования функций GDI.

Чтобы создать значок во время выполнения программы:

  1. Используйте функцию CreateCompatibleDC, чтобы создать контекст устройства, совместимый с тем, который используется основным окном прикладной программы. Параметр функции hdc может установить или значение ПУСТО (NULL) или величину возвращаемого значения из функции GetDC. CreateCompatibleDC возвращает значение дескриптора совместимого контекста устройства.
  2. Используйте функцию CreateCompatibleBitmap, чтобы создать точечный рисунок (значок), совместимый с основным окном приложения. Параметры nWidth и nHeight этой функции устанавливают размеры значка; они должны определить информацию о ширине и высоте, возвращаемую функцией GetMenuCheckMarkDimensions. Вы можете также использовать и функцию CreateBitmap, чтобы создать одноцветный значок.
  3. Используйте функцию SelectObject для выбора значка в совместимом контексте устройства.
  4. Используйте рисующие функции GDI, такие как Ellipse (Эллипс) и LineTo, (Линия), чтобы нарисовать изображение внутри значка, или функции типа BitBlt и StretchBlt, чтобы копировать изображение в точечный рисунок (значок).

За большей информацией обратитесь к статье Bitmaps.

Связывание пункта меню с точечным рисунком (значком)

Вы связываете пару точечных рисунков (значков) «галочки» с пунктом меню, передавая дескрипторы значков функции SetMenuItemBitmaps. Параметр hBitmapUnchecked идентифицирует значок снятия «галочки», а параметр hBitmapChecked идентифицирует установку значка. Если Вы хотите удалить один или оба значка «галочки» из пункта меню, Вы можете установить или параметр hBitmapUnchecked или параметр hBitmapChecked, или оба в значение ПУСТО (NULL).

Настройка атрибута «галочка»

Функция CheckMenuItem устанавливает атрибут «галочки» пункта меню, либо в установленное, либо в снятое состояние. Вы можете определить значение MF_CHECKED, чтобы установить атрибут «галочку » для отметки и значение MF_UNCHECKED, чтобы установить его в снятое состояние.

Вы можете также устанавливать состояние «галочки» пункта меню при помощи использования функция SetMenuItemInfo.

Время от времени группа пунктов меню обозначает набор взаимоисключающих параметров. При помощи использования функция CheckMenuRadioItem, Вы можете отмечать «точкой» один пункт меню при одновременном удалении отметки из всех других пунктов меню в группе.

Моделирование окошек для флажка «галочкой» в меню

Эта тема содержит пример, который показывает, как моделировать окошки для флажка «галочкой» в меню. Пример содержит меню Character (Символ), пункты которого позволяют пользователю устанавливать атрибуты текущего шрифта, такие как полужирный, курсивный и подчеркнутый. Когда атрибут шрифта действует, галочка отображается в окошке для флажка рядом с соответствующим пунктом меню; иначе, рядом с этим пунктом отображается пустое окошко для флажка.

Пример заменяет заданный по умолчанию точечный рисунок «галочки » на два точечных рисунка (значка): точечный рисунок с установленным в окне маркером и точечным рисунком с пустым окном (без маркера). Точечный рисунок окошка для маркера отображается рядом с пунктом меню Bold (Полужирный), Italic (Курсивный) или Underline (Подчеркнутый), когда атрибут «галочки » пункта установлен в значение MF_CHECKED. Снятый маркер «галочки» или пустой точечный рисунок окошка для маркера отображается тогда, когда атрибут «галочки » установлен в значение MF_UNCHECKED.

Windows предоставляет предопределенный точечный рисунок (значок), который содержит изображения, используемые для окошек с маркером «галочка» и радио-кнопок. Пример разделяет пустые окошки для «галочки» и с маркером, копирует их в два отдельных точечных рисунка (значки), а затем использует их как значки установки и снятия отметки «галочкой» для пунктов в меню Character. (Символ).

Чтобы получить дескриптор заданного системой точечного рисунка (значка) окошка для флажка, пример вызывает функцию LoadBitmap, устанавливая значение ПУСТО (NULL) в параметре hInstance и OBM_CHECKBOXES в параметре lpBitmapName. Поскольку все изображения значков одного и того же размера, пример может разделять их, поделив ширину и высоту точечного рисунка на число изображений в строках и столбцах.

Нижеследующая часть файла определения ресурса показывает, как определены пункты меню в меню Character. Обратите внимание!, что сначала атрибуты шрифта не действуют, так как атрибут «галочки » для пункта Обычный (Regular) установлен в отмеченное «галочкой» состояние, а, по умолчанию, атрибут «галочки » оставшихся пунктов установлен в состояние без «галочки».

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

Следующий пример показывает части оконной процедуры, которые создают точечные рисунки (значки) «галочки «; устанавливает атрибут «галочки» пунктов меню Bold (Полужирный), Italic (Курсивный) и Underline(Подчеркнутый); и уничтожает значки «галочки».

Пример использования пользовательских точечных рисунков значков «галочки «.

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

Пункты меню во втором меню определяют параметры настройки выравнивания параграфа: слева, по центру и справа. Только один из этих пунктов меню в одно и тоже данное время может быть отмечен «галочкой». Для этих пунктов меню, пример использует значки, которые похожи на установленную и снятую метки типа радио-кнопки органа управления.

Оконная процедура обрабатывает сообщение WM_CREATE путем вызова определяемой программой функции OnCreate. OnCreate создает четыре значка «галочки», а затем связывает их со своими соответствующими пунктами меню при помощи использования функции SetMenuItemBitmaps.

Чтобы создать каждый значок, OnCreate вызывает определяемую программой функцию CreateMenuBitmaps, устанавливая указатель на конкретную функцию рисования для значка. Функция CreateMenuBitmaps создает одноцветный значок требуемого размера, выбирает его в памяти контекста устройства и стирает фон. Затем она вызывает заданную функцию рисования, чтобы заполнить передний план картинки.

Имеется четыре определяемые программой функции рисования — DrawCheck, DrawUncheck, DrawRadioCheck и DrawRadioUncheck. Они рисуют прямоугольник с X (крестиком), пустой прямоугольник, эллипс, содержащий меньший затемненный эллипс и, соответственно, пустой эллипс.

Оконная процедура обрабатывает сообщение WM_DESTROY, удаляя значки типа «галочки». Она получает дескриптор каждый картинки при помощи использования функции GetMenuItemInfo, а затем переправляет дескриптор функции DeleteObject.

Когда пользователь выбирает пункт меню, окну владельцу отправляется сообщение WM_COMMAND. Для пунктов меню в меню Character, оконная процедура вызывает определяемую программой функцию CheckCharacterItem. Для пунктов в меню Paragraph, оконная процедура вызывает определяемую программой функцию CheckParagraphItem.

Каждый пункт в меню Character, независимо друг от друга, может быть отмечен или не отмечен значком типа «галочки». Следовательно, CheckCharacterItem просто включает состояние проверки («галочки») определяемого пункта меню. Сначала функция вызывает функцию GetMenuItemInfo, чтобы получить текущее состояние пункта меню. Затем она включает флажок состояния MFS_CHECKED и устанавливает новое состояние путем вызова функции SetMenuItemInfo.

В отличие от атрибутов символа, одновременно может быть выбрано только одно выравнивание абзаца. Следовательно, CheckParagraphItem отмечает «галочкой» определяемый пункт меню и удаляет галочку из всех других пунктов в меню. Чтобы сделать это, она вызывает функцию CheckMenuRadioItem.

Ниже следуют необходимые части заголовочного файла прикладной программы.

Ниже следуют необходимые части оконной процедуры прикладной программы и зависимых функций.

Что такое код loadmenuindirect

пришлось поменять существующий MENU в ресурсе на MENUEX, что бы была возможность поставить ID для POPUP. А CMenu::LoadMenu ну или ::LoadMenu не хочет загружать такую меню. что делать, подскажите пожалуйста

От: SchweinDeBurg http://zarezky.spb.ru/
Дата: 21.09.07 11:39
Оценка:

Здравствуйте, Аноним, Вы писали:

А>пришлось поменять существующий MENU в ресурсе на MENUEX, что бы была возможность поставить ID для POPUP. А CMenu::LoadMenu ну или ::LoadMenu не хочет загружать такую меню. что делать, подскажите пожалуйста

Похоже, LoadMenuIndirect() придется использовать.

ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia

От: Аноним
Дата: 21.09.07 14:07
Оценка:

Здравствуйте, SchweinDeBurg, Вы писали:

SDB>Здравствуйте, Аноним, Вы писали:

А>>пришлось поменять существующий MENU в ресурсе на MENUEX, что бы была возможность поставить ID для POPUP. А CMenu::LoadMenu ну или ::LoadMenu не хочет загружать такую меню. что делать, подскажите пожалуйста

SDB>Похоже, LoadMenuIndirect() придется использовать.

Почему-то не работает.

Не загружает из ресурс из exe в строчке, помеченной (*), хотя XN Resource Editor видит его его и правильно отображает из exe.
Да и pMenuExRes указывает на память очень похожую на валидные структуры MENUEX_TEMPLATE_HEADER и MENUEX_TEMPLATE_ITEM.

Создание меню без файла описания ресурсов на основе функции LoadMenuIndirect

Министерство образования Российской Федерации

Институт переподготовки кадров

Уральского государственного технического

Кафедра микропроцессорной техники

ТЕМА: Создание меню без файла описания ресурсов на основе функции LoadMenuIndirect.

Руководитель доц., к.т.н.В.П.Кулюкин

Слушатель гр. СП-923 И.Г.

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

возможности процессора и операционной системы. На языке ассемблера можно запрограммировать все, на что способна соответствующая вычислительная машина, то есть ассемблер является машинно-ориентированным языком программирования. Программируя на ассемблере иногда в силу привычки, иногда в силу необходимости, особенно при организации интерфейса пользователя, приходится многократно программировать одни и те же элементарные задачи. В языках высокого уровня эта проблема решена применением стандартных функций и процедур. В ассемблере эта проблема могла бы быть решена за счет библиотек стандартных функций как на уровне исходных текстов, так и объектных кодов, но такие библиотеки не стандартизованы и не распространяются вместе с компиляторами. С появлением Windows 95 ситуация несколько изменилась. Создание приложений на языке ассемблера представляет собой весьма сложную задачу в связи с высоким уровнем интеграции прикладной программы и операционной системы, но теперь нет необходимости многократно решать проблемы пользовательского интерфейса и управления исполнением команд на уровне машинных команд [I]. Они решаются теперь с помощью операционной системы за счет обращения к функциям интерфейса прикладного программирования – Application Programming Interface (API).

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

rc. Файл ресурсов после обработки компилятора ресурсов и получения двоичного файла с расширением res с помощью компоновщика объединяется с исполняемым файлом.

Наиболее очевидным средством управления приложением является меню. Строкаа меню выводится на экран непосредственно под строкой заголовка. Это меню называется главным. Выбор элемента меню влечет за собой выдачу приложения сообщения WD_COMMAND, содержащего идентификатор пункта меню. Идентификаторы анализируются в оконной процедуре приложения, что обеспечивает соответствующую реакцию на полученное сообщение. Каждый пунк меню определяется тремя характеристиками. Первая определяет то, что будет отображаться в данном пункте меню – это либо строка текста, либо картинка. Вторая характеристика определяет либо константу, посылаемую оконной процедуре сообщении WM_COMMAND, либо всплывающее меню, которое выводится на экран, когда пользователь выбирает данный пункт меню. Третья характеристика указывает, является ли данный пункт меню разрешенным (enabled), запрешенным (disabled), недоступным (grayed) или помеченным (checked). Эта характеристика пункта меню не является обязательной.

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

·разработать сценарий меню. Перед тем как приступить к процессу включения меню в конкретное приложение, разработаем логическую схему. Этот шаг необходим для того, чтобы уже на стадии проектирования обеспечить эргономические свойства приложения. Ведь меню – это один из немногих элементов интерфейса, с которым пользователь постоянно будет иметь дело. Поэтому схема меню должна иметь наглядную иерархическую структуру, с логически увязанными между собой пунктами этой иерархии, что поможет пользователю эффективно использовать все возможности приложения. Для того, чтобы вести предметный разговор, поставим себе задачу разработать для окна нашего приложения главное меню. При этом мы исследуем возможности вывода в окно приложения текста и графики, а также покажем способы решения общих проблем, связанных с разработкой приложения. Наше меню достаточно простое и состоит из трех элементов: “Текст”,”Графика”,”О приложении”. Иерархическая структура меню представлена.

Создание меню без файла описания ресурсов на основе функции LoadMenuIndirect

Категория: Информатика
Тип: Курсовая
Размер: 28.3кб.
скачать

Министерство образования Российской Федерации

Институт переподготовки кадров

Уральского государственного технического

ТЕМА: Создание меню без файла описания ресурсов на основе функции LoadMenuIndirect .

Руководитель доц., к.т.н. В.П.Кулюкин

Слушатель гр. СП-923 И.Г.

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

возможности процессора и операционной системы. На языке ассемблера можно запрограммировать все, на что способна соответствующая вычислительная машина, то есть ассемблер является машинно-ориентированным языком программирования. Программируя на ассемблере иногда в силу привычки, иногда в силу необходимости, особенно при организации интерфейса пользователя, приходится многократно программировать одни и те же элементарные задачи. В языках высокого уровня эта проблема решена применением стандартных функций и процедур. В ассемблере эта проблема могла бы быть решена за счет библиотек стандартных функций как на уровне исходных текстов, так и объектных кодов, но такие библиотеки не стандартизованы и не распространяются вместе с компиляторами. С появлением Windows 95 ситуация несколько изменилась. Создание приложений на языке ассемблера представляет собой весьма сложную задачу в связи с высоким уровнем интеграции прикладной программы и операционной системы, но теперь нет необходимости многократно решать проблемы пользовательского интерфейса и управления исполнением команд на уровне машинных команд [I]. Они решаются теперь с помощью операционной системы за счет обращения к функциям интерфейса прикладного программирования – Application Programming Interface (API).

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

rc. Файл ресурсов после обработки компилятора ресурсов и получения двоичного файла с расширением res с помощью компоновщика объединяется с исполняемым файлом.

Наиболее очевидным средством управления приложением является меню. Строкаа меню выводится на экран непосредственно под строкой заголовка. Это меню называется главным. Выбор элемента меню влечет за собой выдачу приложения сообщения WD_COMMAND, содержащего идентификатор пункта меню. Идентификаторы анализируются в оконной процедуре приложения, что обеспечивает соответствующую реакцию на полученное сообщение. Каждый пунк меню определяется тремя характеристиками. Первая определяет то, что будет отображаться в данном пункте меню – это либо строка текста, либо картинка. Вторая характеристика определяет либо константу, посылаемую оконной процедуре сообщении WM_COMMAND, либо всплывающее меню, которое выводится на экран, когда пользователь выбирает данный пункт меню. Третья характеристика указывает, является ли данный пункт меню разрешенным (enabled), запрешенным (disabled), недоступным (grayed) или помеченным (checked). Эта характеристика пункта меню не является обязательной.

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

разработать сценарий меню. Перед тем как приступить к процессу включения меню в конкретное приложение, разработаем логическую схему. Этот шаг необходим для того, чтобы уже на стадии проектирования обеспечить эргономические свойства приложения. Ведь меню – это один из немногих элементов интерфейса, с которым пользователь постоянно будет иметь дело. Поэтому схема меню должна иметь наглядную иерархическую структуру, с логически увязанными между собой пунктами этой иерархии, что поможет пользователю эффективно использовать все возможности приложения. Для того, чтобы вести предметный разговор, поставим себе задачу разработать для окна нашего приложения главное меню. При этом мы исследуем возможности вывода в окно приложения текста и графики, а также покажем способы решения общих проблем, связанных с разработкой приложения. Наше меню достаточно простое и состоит из трех элементов: “Текст”,”Графика”,”О приложении”. Иерархическая структура меню представлена.

DrawText
Примитивы
Эффекты
Павлин

Текст
Графика
О приложении
TextOut
Кружева

описать схему меню в файле ресурсов. Для выполнения этого описания используются специальные операторы.

составить текст включаемого файла, необходимого для компиляции ресурсного файла

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

Меню можно создать тремя способами. Можно определить меню в файле описания ресурсов, создать меню без файла описания ресурсов непосредственно в программе с помощью функций CreatMenu, AppendMenu и InsertMenu или с помощью функции LoadMenuIndirect, создав предварительно структуру MENUITEMPLATE. Наиболее простым и понятным при программировании под Windows95 на языке ассемблера является определение меню в файле описания ресурсов с помощью любого текстового редактора.

Моя задача заключается в том, чтобы написать программу на тему: “Создать меню без файла описания ресурсов на основе функций LoadMenuIndirect”.

Одним из средств создания меню без использования файла описания ресурсов является функция LoadMenuIndirect. Для применения этой функции необходимо создать шаблон меню, определяемый структурами

MENUITEMTEMPLATEHEADER и MENUITEMTEMPLATE.

Полный шаблон меню состоит из заголовка и хотя бы одного описания пункта меню. Заголовок – структура MENUITEMTEMPLATEHEADER – cостоит из двух полей размером в слово. В первом слове содержится номер версии функции. Для Windows NT и Win16 это 0, для Windows95-1. Во втором слове содержится смещение до первой структуры MENUITEMTEMPLATE. Если между заголовком и описанием первого пункта меню нет дополнительной информации, это поле содержит 0.

Описания пунктов меню, следущие за заголовком, должны быть выравнены на границе двойного слова. Структура MENUITEMTEMPLATE имеет, как правило, пять полей. Шестое поле имеет смысл для пункта меню, указывающего на всплывающее меню.

В качестве примера приводится окно с главными и всплывающими меню, созданными с помощью функции LoadMenuIndirect.

include win32.inc ;файл описания структур и констант

IDM_QUIT equ 100

IDM_ABOUT equ 101

MF_ENABLED equ 0

MF_POPUP equ 1h

;Функции Win32 API, используемые программой

Илон Маск рекомендует:  Что такое код createdialogindirectparam
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL