Так что я продолжаю возвращаться к этой статье о CodeProject:
https://www.codeproject.com/Articles/4758/How-to-customize-the-context-menus-of-a-WebBrowser
Затем я понял это утверждение в начале статьи:
В пересмотренных примерах проектов используется новый , гораздо лучший подход к настройке, который будет всесторонне обсужден в следующем обновлении этой статьи, которое, мы надеемся, будет готово через пару недель. , Я публикую этот полу-документированный и не полностью протестированный код, потому что у меня есть признаки того, что некоторым разработчикам этот код может понадобиться гораздо раньше, чем в день моего следующего обновления. Для каждого пересмотренного образца есть также файл Readme.htm, в котором кратко описывается, как работает этот пример.
Я думал, что изо всех сил пытался понять код фрагментов статьи против загруженного источника! Поэтому я прочитал readme и там было написано:
В MF C 7 CHtmlView
встроена поддержка IDocHostUIHandler
, поэтому я просто переопределяю метод CHtmlView::OnShowContextMenu
, а затем вызываю * Функция 1022 * (внутри CustomMenus. cpp), которая работает так, как описано в разделе 5 моей оригинальной статьи.
Итак, я решил добавить свою собственную функцию переопределения в свой проект:
HRESULT CChristianLifeMinistryHtmlView::OnShowContextMenu(DWORD dwID, LPPOINT ppt,
LPUNKNOWN pcmdtReserved, LPDISPATCH pdispReserved)
{
return CustomContextMenu(ppt, pcmdtReserved);
}
И я добавил аналогичную функцию пользовательского меню:
HRESULT CustomContextMenu(POINT* ppt, IUnknown* pcmdtReserved)
{
IOleWindow* oleWnd = NULL;
HWND hwnd = NULL;
HMENU hMainMenu = NULL;
HMENU hPopupMenu = NULL;
HRESULT hr = 0;
INT iSelection = 0;
if ((ppt == NULL) || (pcmdtReserved == NULL))
goto error;
hr = pcmdtReserved->QueryInterface(IID_IOleWindow, (void**)&oleWnd);
if ((hr != S_OK) || (oleWnd == NULL))
goto error;
hr = oleWnd->GetWindow(&hwnd);
if ((hr != S_OK) || (hwnd == NULL))
goto error;
hMainMenu = LoadMenu(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDR_MENU_HTML_POPUP));
if (hMainMenu == NULL)
goto error;
hPopupMenu = GetSubMenu(hMainMenu, 0);
if (hPopupMenu == NULL)
goto error;
// Show shortcut menu
iSelection = ::TrackPopupMenu(hPopupMenu,
TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD,
ppt->x,
ppt->y,
0,
hwnd,
(RECT*)NULL);
// Send selected shortcut menu item command to shell
if (iSelection != 0)
(void) ::SendMessage(hwnd, WM_COMMAND, iSelection, NULL);
error:
if (hMainMenu != NULL)
::DestroyMenu(hMainMenu);
return S_OK;
}
Наконец, я добавил ресурс меню:
IDR_MENU_HTML_POPUP MENU
BEGIN
POPUP "CustomPopup"
BEGIN
MENUITEM "View Source", 2139
MENUITEM SEPARATOR
MENUITEM "Select All", 31
END
END
Значения идентификатора меню основаны на IDM_
версий, и все они работают.
Затем я попытался добавить свой собственный пункт меню в этот список с помощью моего собственного обработчика событий, и он показывается как отключенный.
Невозможно добавить наши собственные пункты меню в контекстном меню CHtmlView?
Я хотел добавить свой собственный пункт меню «Предварительный просмотр», который, в свою очередь, просто отправлял сообщение моему родительскому «Редактору», чтобы имитировать нажатие там «Предварительного просмотра». Но кажется, что любой пользовательский элемент, который добавляется в это меню, всегда отображается серым цветом.
Если я добавлю пункт меню «Предварительный просмотр» и присвоу ему значение 2003 (IDM_PRINTPREVIEW
), он просто вызовет оригинальный механизм предварительного просмотра. И я не могу добавить свой собственный обработчик событий для того же класса в мой CChristianLifeMinistryHtmlView
класс, поскольку это не соблюдается.
Я нашел эту статью , в которой упоминается:
Если вы решите заменить стандартное меню своим собственным, вы все равно можете добавить расширения меню в свое пользовательское меню. Просто включите пустую опцию меню IDM_MENUEXT_PLACEHOLDER
в ваше определение меню, чтобы указать, куда должны быть вставлены пользовательские команды. Расширения меню вставляются непосредственно перед этим заполнителем. Вы также можете добавить свою собственную пользовательскую команду в стандартное меню, вставив параметр меню перед IDM_MENUEXT_PLACEHOLDER
, как показано в следующем примере.
#define IDM_MENUEXT_PLACEHOLDER 6047
// If the placeholder is gone or was never there, then just exit if
(GetMenuState(hMenu, IDM_MENUEXT_PLACEHOLDER, MF_BYCOMMAND) != (UINT)
-1) { InsertMenu(hMenu, // The Context Menu
IDM_MENUEXT_PLACEHOLDER, // The item to insert before
MF_BYCOMMAND|MF_STRING, // by item ID and str value
IDM_MENUEXT_FIRST__ + nExtCur, // the command ID
(LPTSTR)aOpts[nExtCur].pstrText);// The menu command text
// Remove placeholder DeleteMenu(hMenu, IDM_MENUEXT_PLACEHOLDER,
MF_BYCOMMAND); }
Идентификаторы меню для расширений находятся в диапазоне от IDM_MENUEXT_FIRST__
до IDM_MENUEXT_LAST__
для максимум 33 пользовательских команд.
Я знаю, что я не разработал это правильно, но я добавил пункт меню для заполнителя, а затем еще один для предварительного просмотра с идентификатором пункта меню из IDM_MENUEXT_FIRST__
. Затем я добавил обработчик меню. Пункт меню больше не отключен, так что это хорошо. Но щелчок по нему ничего не дает.
Этот вопрос относится к:
Обновление
Я думаю, что нашел решение и вскоре дам ответ.