IContextMenu::QueryContextMenu gibt ein falsches Menü zurückC++

Programme in C++. Entwicklerforum
Guest
 IContextMenu::QueryContextMenu gibt ein falsches Menü zurück

Post by Guest »

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 angezeigt wird in meinem Fall ist es der aktuelle Benutzer.
Angenommen, der Administrator-Benutzername ist „Admin“, dann tritt das Problem auf, wenn versucht wird, das Kontextmenü für den Ordner C:\Benutzer\Admin anzuzeigen die folgende Probleme:
  • Fehlendes Menü „Eigenschaften“ (Warum? Wenn Sie das Kontextmenü über den Explorer überprüfen, ist der Eintrag „Eigenschaften“ für diesen Ordner , aber QueryContextMenu gibt es nicht zurück)
  • Menüelement „Vorherige Versionen wiederherstellen“ konnte nicht ausgeführt werden (Wenn Sie versuchen, auf dieses Element zu klicken, Es tritt ein Fehler auf. In der MessageBox wird „Unspezifizierter Fehler“ angezeigt. aber dieses Menü funktioniert, wenn es über „Explorer“ ausgewählt wird und GetLastError()
    den Fehlercode 1223 zurückgibt („Der Vorgang wurde vom Benutzer abgebrochen“: aber ich breche nichts ab)
    < /li>
    Das Menü „Teilen“ funktioniert nicht
Sie können sehen mein Code unten. Um diesen Code auszuführen und das Menü anzuzeigen, müssen Sie Folgendes tun:
  • Ersetzen Sie den filePath-Wert durch den Pfad zum Ordner
  • Drücken Sie die Schaltfläche „Kontextmenü“, um das Kontextmenü anzuzeigen

Code: Select all

#include 
#include 
#include 
#include 
#include 

HINSTANCE hInst;
LPCSTR szTitle = "WinAPI";
LPCSTR szWindowClass = "MYWINDOWCLASS";
const wchar_t* filePath = L"C:\\Users\\Admin";

class ContextMenu
{
public:
IContextMenu2* getIContextMenu2()
{
return m_contextMenu2;
}
IContextMenu3* getIContextMenu3()
{
return m_contextMenu3;
}

void showContextMenu(const std::wstring& path, HWND hwnd, UINT xPos, UINT yPos)
{
IContextMenu* pcm = nullptr;
IContextMenu* outPcm = nullptr;

if (SUCCEEDED(GetUIObjectOfFile(hwnd, path.c_str(), IID_IContextMenu, (void**)&pcm))) {

if (GetContextMenu(pcm, (void**)&outPcm)) {

HMENU hmenu = CreatePopupMenu();

if (hmenu) {

if (SUCCEEDED(outPcm->QueryContextMenu(hmenu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_CANRENAME))) {
int idCmd = TrackPopupMenuEx(hmenu, TPM_RETURNCMD, xPos, yPos, (HWND)hwnd, NULL);
InvokeCommand(outPcm, idCmd);

if (m_contextMenu2) {
m_contextMenu2 = nullptr;
}

if (m_contextMenu3) {
m_contextMenu3 = nullptr;
}

outPcm->Release();
}
}
}
}
}

void showFolderBackgroundContextMenu(const std::wstring&  path, HWND hwnd, UINT xPos, UINT yPos)
{
IContextMenu* pcm = nullptr;
IContextMenu* outPcm = nullptr;

if (SUCCEEDED(GetUIObjectOfFolder(hwnd, path.c_str(), IID_IContextMenu, (void**)&pcm))) {

if (GetContextMenu(pcm, (void**)&outPcm)) {

HMENU hmenu = CreatePopupMenu();

if (hmenu) {

if (SUCCEEDED(outPcm->QueryContextMenu(hmenu, 0, SCRATCH_QCM_FIRST, SCRATCH_QCM_LAST, CMF_NORMAL))) {
int idCmd = TrackPopupMenuEx(hmenu, TPM_RETURNCMD, xPos, yPos, (HWND)hwnd, NULL);

if (m_contextMenu2) {
m_contextMenu2 = nullptr;
}

if (m_contextMenu3) {
m_contextMenu3 = nullptr;
}
}
}

outPcm->Release();
}
}
}

private:
const int SCRATCH_QCM_FIRST = 1;
const int SCRATCH_QCM_LAST = 0x7FFF;
IContextMenu2* m_contextMenu2 = nullptr;
IContextMenu3* m_contextMenu3 = nullptr;

HRESULT GetUIObjectOfFile(HWND hwnd, LPCWSTR pszPath, REFIID riid, void** ppv)
{
*ppv = NULL;
HRESULT hr;
LPITEMIDLIST pidl;
SFGAOF sfgao;
if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, &sfgao))) {
IShellFolder* psf;
LPCITEMIDLIST pidlChild;
if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&psf, &pidlChild))) {
hr = psf->GetUIObjectOf(hwnd, 1, &pidlChild, riid, NULL, ppv);
psf->Release();
}
CoTaskMemFree(pidl);
}

return hr;
}

HRESULT GetUIObjectOfFolder(HWND hwnd, LPCWSTR pszPath, REFIID riid, void** ppv)
{
*ppv = NULL;
HRESULT hr;
LPITEMIDLIST pidl;
SFGAOF sfgao;
if (SUCCEEDED(hr = SHParseDisplayName(pszPath, NULL, &pidl, 0, &sfgao))) {
IShellFolder2* psf;
LPCITEMIDLIST pidlChild;
if (SUCCEEDED(hr = SHBindToParent(pidl, IID_IShellFolder2, (void**)&psf, &pidlChild))) {
hr = psf->CreateViewObject(hwnd, riid, ppv);
psf->Release();
}
CoTaskMemFree(pidl);
}

return hr;
}

void InvokeCommand(IContextMenu* pContextMenu, UINT idCommand)
{
CMINVOKECOMMANDINFO cmi = { 0 };
cmi.cbSize = sizeof(CMINVOKECOMMANDINFO);
cmi.lpVerb = (LPSTR)MAKEINTRESOURCE(idCommand - 1);
cmi.nShow = SW_SHOWNORMAL;

if (!SUCCEEDED(pContextMenu->InvokeCommand(&cmi))) {

std::stringstream ss;
ss QueryInterface(IID_IContextMenu2, ppContextMenu))) {
m_contextMenu2 = (LPCONTEXTMENU2)*ppContextMenu;
}

if (*ppContextMenu)
icm1->Release();     // we can now release version 1 interface,
// cause we got a higher one
else
{
*ppContextMenu = icm1;    // since no higher versions were found
}  // redirect ppContextMenu to version 1 interface
}
else
return (FALSE);    // something went wrong

return (TRUE);  // success
}

};

ContextMenu contextMenu;

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
HMODULE hmod = LoadLibraryW(L"shell32.dll");
BOOL(WINAPI * FileIconInit)(_In_ BOOL fRestoreCache);
FileIconInit = (BOOL(WINAPI*)(BOOL)) GetProcAddress(hmod, MAKEINTRESOURCEA(660));
if (FileIconInit) {
FileIconInit(TRUE);
}

hInst = hInstance;

WNDCLASSA wc = {};
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.lpszClassName = szWindowClass;

RegisterClassA(&wc);

HWND hWnd = CreateWindowExA(
0, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
nullptr, nullptr, hInstance, nullptr
);

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

//SHELLEXECUTEINFO shellInfo;
//ZeroMemory(&shellInfo, sizeof(SHELLEXECUTEINFO));
//shellInfo.cbSize = sizeof(SHELLEXECUTEINFO);
//shellInfo.fMask = SEE_MASK_INVOKEIDLIST;
//shellInfo.hwnd = hWnd;
//shellInfo.lpVerb = L"PreviousVersions";
//shellInfo.lpFile = filePath;

//ShellExecuteEx(&shellInfo);

//std::stringstream ss;
//ss HandleMenuMsg(message, wParam, lParam))) {
return 0;
}
}

switch (message) {

case WM_CREATE: {
CreateWindowA(
"BUTTON", "Context menu",
WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,
100, 100, 100, 30,
hWnd, (HMENU)1, hInst, nullptr);
break;
}
case WM_COMMAND: {
if (LOWORD(wParam) == 1) {
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
contextMenu.showContextMenu(filePath, hWnd, 100, 100);
}
break;
}

case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Unspezifizierter Fehler-Screenshot:
Image

Screenshot des Menüelements „Eigenschaften" fehlt
Image

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post