Контекстное меню iexploreCommand с подменем возвращает пустой ishelliTemarray для справочного фона щелкнутьC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Контекстное меню iexploreCommand с подменем возвращает пустой ishelliTemarray для справочного фона щелкнуть

Сообщение Anonymous »

Я реализовал обработчик контекстных меню, основанный на примере Microsoft здесь, в котором используется iexploreCommand .
Код отображает контекстное меню, с подменом, просто отлично с Windows 11 Контекстное меню. Таким образом, нет проблем с моим пакетом MSIX или с моим файлом appxmanifest.xml. < /P>
Моя проблема связана с кодом C ++. Проблема в том, что iShelliTemarray пуст, когда пользователь щелкнет правой кнопкой мыши на фоне каталога. Путь папки с фоном каталога щелкните. Это только пусто, когда в контекстном меню есть одна или несколько подменга. Также обратите внимание, что щелкните правой кнопкой мыши по файлам и папкам по-прежнему популярны IshelliTemarray, как и ожидалось, независимо от того, есть ли подменга />#include "pch.h"
#include
#include
#include
#include

using namespace Microsoft::WRL;

HMODULE g_hModule = nullptr;

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
g_hModule = hModule;
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

class SubCommand : public RuntimeClass
{
public:
SubCommand(PCWSTR title, PCWSTR icon, PCWSTR command) :
m_title(title), m_icon(icon), m_command(command) {
}

IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
{
*name = nullptr;
auto title = wil::make_cotaskmem_string_nothrow(m_title);
RETURN_IF_NULL_ALLOC(title);
*name = title.release();
return S_OK;
}

IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* iconPath)
{
*iconPath = nullptr;
return E_NOTIMPL;
}

IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip) { *infoTip = nullptr; return E_NOTIMPL; }
IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName) { *guidCommandName = GUID_NULL; return S_OK; }
IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState)
{
*cmdState = ECS_ENABLED;
return S_OK;
}

IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept
{
// If user right-clicks a file or folder, the selected item is in the array
// If user right-clicks the background, the array is empty
try
{
DWORD count = 0;
if (selection)
{
RETURN_IF_FAILED(selection->GetCount(&count));
}

if (count > 0)
{
ComPtr item;
RETURN_IF_FAILED(selection->GetItemAt(0, &item));

PWSTR filePath;
RETURN_IF_FAILED(item->GetDisplayName(SIGDN_FILESYSPATH, &filePath));
wil::unique_cotaskmem_string filePathCleanup(filePath);

WCHAR message[100];
StringCchPrintfW(message, ARRAYSIZE(message), L"First item: %s", filePath);
MessageBox(nullptr, message, L"Debug", MB_OK);
}
else
{
MessageBox(nullptr, L"No items selected", L"Debug", MB_OK);
}

return S_OK;
}
catch (...)
{
return E_FAIL;
}
}

IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags) { *flags = ECF_DEFAULT; return S_OK; }
IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands) { *enumCommands = nullptr; return E_NOTIMPL; }

private:
PCWSTR m_title;
PCWSTR m_icon;
PCWSTR m_command;
};

class SubCommandEnum : public RuntimeClass
{
public:
SubCommandEnum()
{
m_commands.push_back(Make(L"SubmenuTest", L"SubmenuTest.ico", L"SubmenuTest"));
}

IFACEMETHODIMP Next(ULONG celt, IExplorerCommand** pUICommand, ULONG* pceltFetched)
{
ULONG fetched = 0;
while (fetched < celt && m_index < m_commands.size())
{
pUICommand[fetched] = m_commands[m_index].Get();
pUICommand[fetched]->AddRef();
++fetched;
++m_index;
}

if (pceltFetched)
{
*pceltFetched = fetched;
}

return (fetched == celt) ? S_OK : S_FALSE;
}

IFACEMETHODIMP Skip(ULONG celt)
{
m_index += celt;
return (m_index < m_commands.size()) ? S_OK : S_FALSE;
}

IFACEMETHODIMP Reset()
{
m_index = 0;
return S_OK;
}

IFACEMETHODIMP Clone(IEnumExplorerCommand** ppenum)
{
auto clone = Make();
clone->m_index = m_index;
*ppenum = clone.Detach();
return S_OK;
}

private:
std::vector m_commands;
size_t m_index = 0;
};

class __declspec(uuid("8A0E292E-E857-424B-9457-EC5377D0DCFD")) ContextMenuHandler : public RuntimeClass
{
public:
IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)
{
*name = nullptr;
auto title = wil::make_cotaskmem_string_nothrow(L"ExplorerHelper");
RETURN_IF_NULL_ALLOC(title);
*name = title.release();
return S_OK;
}

IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* iconPath)
{
*iconPath = nullptr;
return E_NOTIMPL;
}

IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip) { *infoTip = nullptr; return E_NOTIMPL; }
IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName) { *guidCommandName = GUID_NULL; return S_OK; }
IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState)
{
*cmdState = ECS_ENABLED;
return S_OK;
}

IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept
{
// Any code added here no longer runs now that we have a submenu
return S_OK;
}

IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags) { *flags = ECF_HASSUBCOMMANDS; return S_OK; }
IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands)
{
*enumCommands = Make().Detach();
return S_OK;
}

IFACEMETHODIMP SetSite(_In_ IUnknown* site) noexcept { m_site = site; return S_OK; }
IFACEMETHODIMP GetSite(_In_ REFIID riid, _COM_Outptr_ void** site) noexcept { return m_site.CopyTo(riid, site); }

protected:
ComPtr m_site;
};

CoCreatableClass(ContextMenuHandler)

STDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory)
{
return Module::GetModule().GetActivationFactory(activatableClassId, factory);
}

_Use_decl_annotations_
STDAPI DllCanUnloadNow(void)
{
return Module::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE;
}

_Use_decl_annotations_
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** instance)
{
return Module::GetModule().GetClassObject(rclsid, riid, instance);
}


Подробнее здесь: https://stackoverflow.com/questions/794 ... ay-for-dir
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»