Мотивация: Создание собственного файлового диалогового окна, которое выглядит и действует так же, как стандартный стандартный диалог.
Проблема: как получить раскрывающееся меню для текущей папки или контейнера оболочки.
Очевидные Тупики:
- Запросить у IShellFolder его IContextMenu ‹NULL указатель интерфейса.
- Запросить у IShellView его IContextMenu ‹NULL указатель интерфейса.
- IShellFolder :: CreateViewObject (IID_IContextMenu ...) ‹очень ограниченное контекстное меню (новое).
- IShellFolder :: GetUIObjectOf (IID_IContextMenu ...) ‹ограниченное контекстное меню (открыть, изучить, ...).
- Реализуйте IShellBrowser InsertMenusSB, RemoveMenusSB и SetMenuSB ‹Меню никогда не заполняется сверх того, чем я его заполняю
Я потратил некоторое время на чтение Реализация представления папки и Как разместить IContextMenu. Похоже, это указывает на то, что последний подход, описанный выше (реализация InsertMenuSB, ...), должен работать. IShellView должен заполнять общее меню для IShellBrowser, включая его подменю View, соответствующими элементами. Однако пока все, что я получаю от этого, - это пустое меню (если я не заполняю его элементами - в этом случае я просто получаю элементы, которыми заполняю его).
Конечно, есть способ сделать это. Проводник Windows попадает в меню, которое он отображает (если вы нажмете ALT в Vista или более поздних версиях) откуда-то. И я не могу представить, что это меню статически создается самим проводником - оно наверняка динамически создается каким-то образом вместе с отображаемым в данный момент IShellView, чтобы расширения оболочки отображали правильный список параметров просмотра (и других параметров меню).
Но документация по InsertMenuSB, RemoveMenuSB и SetMenuSB сбивает с толку. Кажется, это указывает на то, что как сервер контейнера я должен заполнить предоставленные OLEMENUGROUPWIDTHS, "элементами 0, 2 и 4, чтобы отразить количество элементов меню, которые он предоставил в файле, Группы меню "Просмотр" и "Окно" "
Я реализовал следующее, чтобы попытаться должным образом выполнить этот контракт:
HRESULT STDMETHODCALLTYPE ShellBrowserDlgImpl::InsertMenusSB(__RPC__in HMENU hmenuShared, /* [out][in] */ __RPC__inout LPOLEMENUGROUPWIDTHS lpMenuWidths)
{
TRACE("IShellBrowser::InsertMenusSB\n");
// insert our main pull-downs
struct
{
UINT id;
LPCTSTR label;
} pull_downs[] = {
{ FCIDM_MENU_FILE, "File" },
{ FCIDM_MENU_EDIT, "Edit" },
{ FCIDM_MENU_VIEW, "View" },
{ FCIDM_MENU_TOOLS, "Tools" },
{ FCIDM_MENU_HELP, "Help" },
};
for (size_t i = 0; i < countof(pull_downs); ++i)
{
VERIFY(AppendMenu(hmenuShared, MF_POPUP, pull_downs[i].id, pull_downs[i].label));
ASSERT(GetMenuItemID(hmenuShared, i) == pull_downs[i].id);
}
// set the count of menu items we've inserted into each *group*
lpMenuWidths->width[0] = 2; // FILE: File, Edit
lpMenuWidths->width[2] = 2; // VIEW: View, Tools
lpMenuWidths->width[4] = 1; // WINDOW: Help
return S_OK;
}
Кто-нибудь реализовал проект, подобный проводнику, который должным образом предоставляет конечному пользователю текущие меню IShellView?
Есть ли документация / примеры по реализациям IOLEInPlaceFrame, которые могут пролить свет на эту непонятную тему?
Ух! @ - Мне кажется, я должен быть близко - но недостаточно близко!