Что такое код appendmenu
function AppendMenu(Menu: HMenu; Flags, IDNewItem: PChar): Bool;
Пpисоединяет в конец меню новый элемент, состояние котоpого опpеделяется Flags.
Menu: Изменяемое меню.
Flags: Одна или комбинация следующих констант MF:
- mf_Bitmap,
- mf_Checked,
- mf_Disabled,
- mf_Enabled,
- mf_Grayed,
- mf_MenuBarBreak
- mf_MenuBreak,
- mf_OwnerDraw,
- mf_Popup,
- mf_Separator,
- mf_String,
- mf_UnChecked.
(См. pаздел «Флаги меню mf_» в главе 1).
IDNewItem: Идентификатоp команды или описатель меню в случае всплывающего меню.
Не нуль в случае успешного завеpшения; нуль — в пpотивном случае.
InsertMenu/AppendMenu — Как добавить значки в меню и подменю с помощью С++ и win32
Я написал программу контекстного меню dll расширения оболочки с использованием программирования С++ и win32. Среда разработки — Visual Studio 2008 и 2010. В приведенном ниже примере кода я пытаюсь добавить значок меню только для главного меню. Значок меню не отображается в главном меню. (Мне нужно добавить значки для всех пунктов меню.).
Пожалуйста, исправьте приведенный ниже код.
CreatePopUpMenu также работает. Вам просто нужно было использовать InsertMenu вместо AppendMenu.
Возможные варианты: MF_BYCOMMAND и MF_BYPOSITION. Похоже, что вы пытаетесь использовать MF_BYCOMMAND, но должны использовать те же значения, которые уже заданы для MenuItens.
Вы также должны проверить формат BITMAP. SetMenuItemBitmaps просто поддерживает монохромный режим. Я гуглил, чтобы сделать то же самое и добился успеха здесь. Спасибо за указание пути.
Что такое код appendmenu
Добавляет новый пункт в конец указанного главного меню, выпадающего меню, подменю или контекстного меню
#include
_GUICtrlMenu_AppendMenu ( $hMenu , $iFlags , $iNewItem , $pNewItem )
$hMenu | Дескриптор меню |
$iFlags | Specifies flags to control the appearance and behavior of the new menu item: $MF_BITMAP — Uses a bitmap as the menu item $MF_CHECKED — Устанавливает галочку рядом с пунктом меню. Если приложение предоставляет галочку в виде bitmap, то флаг отображает галочку в виде bitmap рядом с пунктом меню. $MF_DISABLED — Отключает пункт меню и он не может быть выбран, но флаг не делает его серым. $MF_ENABLED — Enables the menu item so that it can be selected, and restores it from its grayed state. $MF_GRAYED — Disables the menu item and grays it so that it cannot be selected. $MF_MENUBARBREAK — Functions the same as $MF_MENUBREAK for a menu bar. For a drop down menu, submenu, or shortcut menu, the new column is separated from the old column by a vertical line. $MF_MENUBREAK — Places the item on a new line (for a menu bar) or in a new column (for a drop down menu, submenu, or shortcut menu) without separating columns. $MF_OWNERDRAW — Specifies that the item is an owner drawn item. Before the menu is displayed for the first time, the window that owns the menu receives a $WM_MEASUREITEM message to retrieve the w >$WM_DRAWITEM message is then sent to the window procedure of the owner window whenever the appearance of the menu item must be updated. $MF_POPUP — Specifies that the menu item opens a drop down menu or submenu. The iNewItem parameter specifies a handle to the drop down menu or submenu. This flag is used to add a menu name to a menu bar, or a menu item that opens a submenu to a drop down menu, submenu, or shortcut menu. $MF_SEPARATOR — Рисует горизонтальную разделительную линию. Этот флаг используется только в раскрывающемся меню, подменю или контекстное меню. Линия не может быть серой, отключенной или выделенной. Параметры pNewItem и iNewItem игнорируются. $MF_STRING — Указывает, что пункт меню является текстовой строкой. Параметр pNewItem является строкой. $MF_UNCHECKED — Не устанавливает галочку рядом с пунктом. Если приложение предоставляет галочку в виде bitmap, то флаг отображает очищенный bitmap рядом с пунктом меню. |
$iNewItem | Specifies either the >$iFlags parameter is set to a popup, a handle to the drop down menu or submenu. |
$pNewItem | Определяет содержание нового пункта меню. Интерпретация параметра $pNewItem зависит от того, включает ли в себя параметр $iFlags флаги $MF_BITMAP , $MF_OWNERDRAW или $MF_STRING : $MF_BITMAP — Содержит дескриптор bitmap $MF_OWNERDRAW — Contains an application supplied value that can be used to maintain additional data related to the menu item. The value is in the ItemData member of the structure pointed to by the lParam parameter of the $WM_MEASUREITEM or $WM_DRAWITEM message sent when the menu is created or its appearance is updated. $MF_STRING — Содержит строку |
Успех: | Возвращает True |
Ошибка: | Возвращает False |
Искать AppendMenu в библиотеке MSDN
Func _Main ()
Local $hGUI , $hFile , $hEdit , $hHelp , $hMain
Local Enum $idNew = 1000 , $idOpen , $idSave , $idExit , $idCut , $idCopy , $idPaste , $idAbout
; Создаёт GUI
$hGUI = GUICreate ( «Добавляет пункт» , 400 , 300 )
; Добавляет пункт меню «О программе»
_GUICtrlMenu_AppendMenu ( $hHelp , $MF_STRING , $idAbout , ‘О программе’ )
; Цикл выполняется, пока окно не будет закрыто
Do
Until GUIGetMsg () = $GUI_EVENT_CLOSE
EndFunc ;==>_Main
Как отобразить контекстное меню?
Автор: Александр Шаргин
Опубликовано: 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 . Кроме этого, в ресурсы вашего приложения добавится новое меню, и вам останется только подредактировать его.
InsertMenu/AppendMenu — How to add Icons to menu and submenus using C++ and win32
I have written a shell extension dll context menu program using C++ and win32 programming. The development environment is Visual Studio 2008 and 2010. In the below sample code, I am trying to add menu icon for the main menu only. The menu icon is not showing for the main menu. (I need to add icons for all menu items.).
Please correct the below code.
2 Answers 2
CreatePopUpMenu also works. You just had to use InsertMenu instead of AppendMenu.
Reading the definition of SetMenuItemBitmap https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenuitembitmaps there is not such a thing as a MF_BITMAP flag.
The options are MF_BYCOMMAND and MF_BYPOSITION. Seems like that you are trying to use MF_BYCOMMAND but have to use the same values already given to the MenuItens.
You have also to check for the format of the BITMAP. SetMenuItemBitmaps just acepts monochrome. I was googling to do the same and had success here. Thanks for showing the way.
Not the answer you’re looking for? Browse other questions tagged c++ visual-c++ or ask your own question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2020 Stack Exchange Inc; user contributions licensed under cc by-sa 4.0 with attribution required. rev 2020.11.12.35412
InsertMenu / AppendMenu — Как добавить иконки в меню и подменю с помощью C ++ и win32
Я написал программу расширения оболочки контекст длла меню с помощью C ++ и win32 программирования. Среда разработки Visual Studio 2008 и 2010. В приведенном ниже примере кода, я пытаюсь добавить иконку в меню только в главном меню. Значок меню не отображается в главном меню. (Мне нужно добавить иконки для всех пунктов меню.).
Пожалуйста, исправьте код, приведенный ниже.
Варианты MF_BYCOMMAND и MF_BYPOSITION. Похоже, что вы пытаетесь использовать MF_BYCOMMAND, но должны использовать одни и те же значения, уже приведенные в MenuItens.
Вы должны также проверить формат битмапа. SetMenuItemBitmaps просто acepts монохромным. Я прибегая к помощи, чтобы сделать то же самое и имел успех здесь. Спасибо за показывая путь.
CreatePopupMenu также работает. Вы просто должны были использовать InsertMenu вместо AppendMenu.
Описание структуры меню без использования ресурсов
Вступление
Обычный способ
Win32 API для этого предлагает функции CreateMenu(), AppendMenu() и подобные. Мало-мальски сложное меню с вложенными подменю выглядит в таком описании не очень наглядно, если не сказать нечитаемо. Даже ATL не помогает:
Большое количество повторяющегося кода утомляет взор и ввергает в уныние.
Новый способ
Хочется написать кратко и ясно:
Так написать нам позволит наличие перегрузки операторов в языке C++. Мы перегрузим оператор «квадратные скобки», чтобы он делал некое действие с объектом и возвращал ссылку на сам объект:
Это позволит нам сколько угодно раз вызывать у объекта этот оператор:
Меню можно представить в виде дерева, у которого есть узлы четырех типов:
У узла EPopup может быть сколько угодно детей любого типа, у остальных узлов детей быть не может.
Ясно, что если находиться им предстоит в одном дереве, то без общего предка не обойтись. Метод append() позволит добавлять детей к узлу, метод append_to() нужен для составления реального меню при обходе нашего дерева.
Также пригодится небольшая вспомогательная структурка, чтобы не повторяться:
_ASSERT нужен для того, чтобы случайно не вызвать метод append() для узла, который не может иметь детей.
Теперь реализуем наши узлы:
Само дерево будет состоять из объектов одного и того же типа node . Используется идиома «pimpl», то есть node содержит указатель на конкретную реализацию узла. Обратите внимание на семантику копирования и присваивания:
При присваивании одного node другому происходит передача реализации (так называемая move-семантика). Объект из правой части становится пустышкой. Так же работает и конструктор копирования. (Аналогично работает std::auto_ptr ).
Так как все затевалось ради того, чтобы в виде временного объекта описать многоуровневую структуру, move-семантика экономит здесь много операций копирования.
Кстати, поскольку node_impl_ptr — это и есть std::auto_ptr , можно было не определять явно node(node & other) и operator=(node & other) , компилятор сгенерировал бы их сам.
Теперь нам остается только определить функции для создания узлов. За исключением empty() , они используют приватный конструктор и потому объявлены как friend .
Готово! В рабочем коде это используется примерно так:
Благодаря move-семантике node здесь не происходит копирования всей структуры, вместо этого она напрямую передается в SetMenuBar() .
menubar состоит из двух деревьев, потому что у приложения для Windows Mobile есть две soft key. Реализация SetMenuBar() выходит за рамки данной статьи, и так уже получилось много текста
Что такое код appendmenu
Appends a new item to the end of the specified menu bar, drop-down menu, submenu, or shortcut menu. You can use this function to specify the content, appearance, and behavior of the menu item.
Syntax
Parameters
Type: HMENU
A handle to the menu bar, drop-down menu, submenu, or shortcut menu to be changed.
Type: UINT
Controls the appearance and behavior of the new menu item. This parameter can be a combination of the following values.
Value | Meaning | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
MF_BITMAP 0x00000004L | ||||||||||||||||||
MF_CHECKED 0x00000008L | ||||||||||||||||||
MF_DISABLED 0x00000002L | ||||||||||||||||||
MF_ENABLED 0x00000000L | ||||||||||||||||||
MF_GRAYED 0x00000001L | ||||||||||||||||||
MF_MENUBARBREAK 0x00000020L | ||||||||||||||||||
MF_MENUBREAK 0x00000040L | ||||||||||||||||||
MF_OWNERDRAW 0x00000100L | ||||||||||||||||||
MF_POPUP 0x00000010L | ||||||||||||||||||
MF_SEPARATOR 0x00000800L | ||||||||||||||||||
MF_STRING 0x00000000L | ||||||||||||||||||
MF_UNCHECKED 0x00000000L |
Value | Meaning | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
MF_BITMAP 0x00000004L | |||||||||||
MF_OWNERDRAW 0x00000100L | |||||||||||
MF_STRING 0x00000000L | Winuser.h (include Windows.h) | ||||||||||
$hMenu | Дескриптор меню |
$iFlags | Specifies flags to control the appearance and behavior of the new menu item: $MF_BITMAP — Uses a bitmap as the menu item $MF_CHECKED — Устанавливает галочку рядом с пунктом меню. Если приложение предоставляет галочку в виде bitmap, то флаг отображает галочку в виде bitmap рядом с пунктом меню. $MF_DISABLED — Отключает пункт меню и он не может быть выбран, но флаг не делает его серым. $MF_ENABLED — Enables the menu item so that it can be selected, and restores it from its grayed state. $MF_GRAYED — Disables the menu item and grays it so that it cannot be selected. $MF_MENUBARBREAK — Functions the same as $MF_MENUBREAK for a menu bar. For a drop down menu, submenu, or shortcut menu, the new column is separated from the old column by a vertical line. $MF_MENUBREAK — Places the item on a new line (for a menu bar) or in a new column (for a drop down menu, submenu, or shortcut menu) without separating columns. $MF_OWNERDRAW — Specifies that the item is an owner drawn item. Before the menu is displayed for the first time, the window that owns the menu receives a $WM_MEASUREITEM message to retrieve the w >$WM_DRAWITEM message is then sent to the window procedure of the owner window whenever the appearance of the menu item must be updated. $MF_POPUP — Specifies that the menu item opens a drop down menu or submenu. The iNewItem parameter specifies a handle to the drop down menu or submenu. This flag is used to add a menu name to a menu bar, or a menu item that opens a submenu to a drop down menu, submenu, or shortcut menu. $MF_SEPARATOR — Рисует горизонтальную разделительную линию. Этот флаг используется только в раскрывающемся меню, подменю или контекстное меню. Линия не может быть серой, отключенной или выделенной. Параметры pNewItem и iNewItem игнорируются. $MF_STRING — Указывает, что пункт меню является текстовой строкой. Параметр pNewItem является строкой. $MF_UNCHECKED — Не устанавливает галочку рядом с пунктом. Если приложение предоставляет галочку в виде bitmap, то флаг отображает очищенный bitmap рядом с пунктом меню. |
$iNewItem | Specifies either the >$iFlags parameter is set to a popup, a handle to the drop down menu or submenu. |
$pNewItem | Определяет содержание нового пункта меню. Интерпретация параметра $pNewItem зависит от того, включает ли в себя параметр $iFlags флаги $MF_BITMAP , $MF_OWNERDRAW или $MF_STRING : $MF_BITMAP — Содержит дескриптор bitmap $MF_OWNERDRAW — Contains an application supplied value that can be used to maintain additional data related to the menu item. The value is in the ItemData member of the structure pointed to by the lParam parameter of the $WM_MEASUREITEM or $WM_DRAWITEM message sent when the menu is created or its appearance is updated. $MF_STRING — Содержит строку |
Успех: | Возвращает True |
Ошибка: | Возвращает False |
Искать AppendMenu в библиотеке MSDN
Func _Main ()
Local $hGUI , $hFile , $hEdit , $hHelp , $hMain
Local Enum $idNew = 1000 , $idOpen , $idSave , $idExit , $idCut , $idCopy , $idPaste , $idAbout
; Создаёт GUI
$hGUI = GUICreate ( «Добавляет пункт» , 400 , 300 )
; Добавляет пункт меню «О программе»
_GUICtrlMenu_AppendMenu ( $hHelp , $MF_STRING , $idAbout , ‘О программе’ )
; Цикл выполняется, пока окно не будет закрыто
Do
Until GUIGetMsg () = $GUI_EVENT_CLOSE
EndFunc ;==>_Main