Ich versuche, mit IContextMenu::QueryContextMenu das Menü abzurufen, das angezeigt wird, wenn ich mit der rechten Maustaste auf einen leeren Bereich in einem Ordner klicke (Hintergrundmenü). Ich kann das Menü aufrufen, alle Elemente funktionieren einwandfrei, mit Ausnahme der Elemente, die hier in der Registrierung HKEY_CLASSES_ROOT\Directory\Background\shell registriert sind. Wenn ich versuche, einen Menüpunkt aus diesem Abschnitt auszuwählen, passiert nichts.
Eine der möglichen Lösungen, die ich gefunden habe, ist diese
Befehle aus der Registrierung analysieren
Verfolgen Sie das Verb des ausgewählten Befehls
Wenn das Verb des ausgewählten Befehls mit einem der Befehle übereinstimmt von hier HKEY_CLASSES_ROOT\Directory\Background\shell\verb\command, dann führen Sie diesen Befehl manuell mit dem Befehl aus, der in der Befehlstaste aufgezeichnet ist
Ich möchte jedoch, dass die Befehle aus dem Abschnitt HKEY_CLASSES_ROOT\Directory\Background\shell funktionieren, ohne solche Hacks zu verwenden. Wie kann ich das machen?
Um meinen Code auszuführen, ersetzen Sie den Wert der Pfadvariablen durch den Pfad zu Ihrem Ordner und klicken Sie auf die Kontextmenütaste.
Ich versuche, mit IContextMenu::QueryContextMenu das Menü abzurufen, das angezeigt wird, wenn ich mit der rechten Maustaste auf einen leeren Bereich in einem Ordner klicke (Hintergrundmenü). Ich kann das Menü aufrufen, alle Elemente funktionieren einwandfrei, mit Ausnahme der Elemente, die hier in der Registrierung HKEY_CLASSES_ROOT\Directory\Background\shell registriert sind. Wenn ich versuche, einen Menüpunkt aus diesem Abschnitt auszuwählen, passiert nichts. Eine der möglichen Lösungen, die ich gefunden habe, ist diese [list] [*]Befehle aus der Registrierung analysieren [*]Verfolgen Sie das Verb des ausgewählten Befehls [*]Wenn das Verb des ausgewählten Befehls mit einem der Befehle übereinstimmt von hier HKEY_CLASSES_ROOT\Directory\Background\shell\verb\command, dann führen Sie diesen Befehl manuell mit dem Befehl aus, der in der Befehlstaste aufgezeichnet ist [/list] Ich möchte jedoch, dass die Befehle aus dem Abschnitt HKEY_CLASSES_ROOT\Directory\Background\shell funktionieren, ohne solche Hacks zu verwenden. Wie kann ich das machen? Um meinen Code auszuführen, ersetzen Sie den Wert der Pfadvariablen durch den Pfad zu Ihrem Ordner und klicken Sie auf die Kontextmenütaste. [code]#include #include #include #include #include
class Site : public IServiceProvider, public IFolderView, IOleWindow { HWND _hwnd; IShellItem* _item;
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { if (_cm3) { LRESULT lr = 0; if (SUCCEEDED(_cm3->HandleMenuMsg2(message, wParam, lParam, &lr))) return lr; } else if (_cm2) { if (SUCCEEDED(_cm2->HandleMenuMsg(message, wParam, lParam))) return 0; }
const int buttonId = 1; const int buttonX = 10; const int buttonY = 10; switch (message) { case WM_CREATE: CreateWindow(L"BUTTON", L"Show Context menu", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, buttonX, buttonY, 200, 30, hwnd, (HMENU)(long)buttonId, nullptr, nullptr); break;
case WM_COMMAND: if (LOWORD(wParam) == buttonId) { IShellItem* item; IBindCtx* ctx; CreateBindCtx(0, &ctx); // use a binding context to avoid the shell to be too smart and get back wrong items SHCreateItemFromParsingName(path, ctx, IID_PPV_ARGS(&item)); //ctx->Release(); if (item) { IContextMenu* cm; item->BindToHandler(ctx, BHID_SFViewObject, IID_PPV_ARGS(&cm)); if (cm) { if (FAILED(cm->QueryInterface(&_cm3))) { cm->QueryInterface(&_cm2); }
// pass site to enable some menu items properly like "share" Site site{ hwnd, item }; IObjectWithSite* ows; cm->QueryInterface(&ows); if (ows) { ows->SetSite(static_cast(&site)); }
auto menu = CreatePopupMenu(); const int firstId = 1;
cm->QueryContextMenu(menu, 0, firstId, 0x7FFF, CMF_NORMAL); // remove some flags if not needed POINT pt{ buttonX, buttonY }; ClientToScreen(hwnd, &pt); auto cmd = TrackPopupMenu(menu, TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, nullptr); if (cmd) { CMINVOKECOMMANDINFO cmi{}; cmi.cbSize = sizeof(CMINVOKECOMMANDINFO); cmi.lpVerb = (LPSTR)MAKEINTRESOURCE(cmd - firstId); cmi.nShow = SW_SHOWNORMAL; cm->InvokeCommand(&cmi); }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { auto hmod = LoadLibrary(L"shell32.dll"); auto fileIconInit = (BOOL(WINAPI*)(BOOL))GetProcAddress(hmod, MAKEINTRESOURCEA(660)); if (fileIconInit) { fileIconInit(TRUE); }
Ich versuche, mit IContextMenu::QueryContextMenu das Menü abzurufen, das angezeigt wird, wenn ich mit der rechten Maustaste auf einen leeren Bereich in einem Ordner klicke (Hintergrundmenü). Ich kann...
Ich versuche, mit IContextMenu::QueryContextMenu das Menü abzurufen, das angezeigt wird, wenn ich mit der rechten Maustaste auf einen leeren Bereich in einem Ordner klicke (Hintergrundmenü). Ich kann...
Ich erstelle ein Kontextmenü, indem ich IContextMenu::QueryContextMenu aufrufe.
Bis auf zwei Dinge ist alles in Ordnung und beide Probleme treten auf, wenn das Kontextmenü für den Admin-Ordner...
Ich erstelle ein Kontextmenü, indem ich IContextMenu::QueryContextMenu aufrufe.
Bis auf zwei Dinge ist alles in Ordnung und beide Probleme treten auf, wenn das Kontextmenü für den Admin-Ordner...
Ich erstelle ein Kontextmenü, indem ich IContextMenu::QueryContextMenu aufrufe.
Bis auf zwei Dinge ist alles in Ordnung und beide Probleme treten auf, wenn das Kontextmenü für den Admin-Ordner...