Click here to Skip to main content
15,895,740 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
My program displays a list of folders and files

I would like to have the option of showing the same context menus on a folder or file as the user sees in Windows Explorer - for left click & right click drag/drop.

Just looking for some hints on where I should start - prefer no .NET

Thanks
Posted
Comments
urbane.tiger 21-Oct-12 1:56am    
I think that's 'more or less' what I have, which works - up to a point. Its the 3rd party stuff that's giving me the grief, they're fine in native windows but... I have an alternative approach to do what I want - I might take that track for now and move on.

1 solution

You can use Windows shell to create context menus same as that of windows for folders and files.

Following code prepares context menu same as that of Windows created for My Documents folder.
Please call CMyTestDlg::ShowContextMenu() from your dialog class.

HRESULT GetSHContextMenu(LPSHELLFOLDER psfFolder, LPCITEMIDLIST localPidl,
                         void** ppCM, int* pcmType)
{
    *ppCM = NULL;
    LPCONTEXTMENU pICv1 = NULL; // plain version
    // try to obtain the lowest possible IContextMenu
    HRESULT hr = psfFolder->GetUIObjectOf(NULL, 1, &localPidl, 
        IID_IContextMenu, NULL, (void**)&pICv1);
    if(pICv1) { // try to obtain a higher level pointer, first 3 then 2
        hr = pICv1->QueryInterface(IID_IContextMenu3, ppCM);
        if(NOERROR == hr) *pcmType = 3;
        else {
            hr = pICv1->QueryInterface(IID_IContextMenu2, ppCM);
            if(NOERROR == hr) *pcmType = 2;
        }

        if(*ppCM) pICv1->Release(); // free initial "v1.0" interface
        else { // no higher version supported
            *pcmType = 1;
            *ppCM = pICv1;
            hr = NOERROR; // never mind the query failures, this'll do
        }
    }

    return hr;
}

void CMyTestDlg::ShowContextMenu()
{
    #define MIN_SHELL_ID 1
    #define MAX_SHELL_ID 30000

    CMenu menu;
    menu.CreatePopupMenu();
    int cmType; // we don't need this here
    LPCONTEXTMENU pCM;

    IShellFolder *psfParent = NULL;
    LPITEMIDLIST pidlSystem = NULL;
    LPCITEMIDLIST pidlRelative = NULL;
    STRRET strDispName;
    TCHAR szDisplayName[MAX_PATH];
    HRESULT hr;

    hr = SHGetFolderLocation(NULL, CSIDL_MYDOCUMENTS, NULL, NULL, &pidlSystem);
    hr = SHBindToParent(pidlSystem, IID_IShellFolder, (void **) &psfParent, &pidlRelative);

    // assume that psfFolder and pidl are valid
    HRESULT hr1 = GetSHContextMenu(psfParent, pidlRelative, (void**)&pCM, &cmType);

    // fill the menu with the standard shell items
    hr = pCM->QueryContextMenu(menu, 0, MIN_SHELL_ID, MAX_SHELL_ID, CMF_EXPLORE);
    // show the menu and retrieve the selected command ID
    int cmdID = menu.TrackPopupMenu(TPM_RETURNCMD | TPM_LEFTALIGN, 0, 0, this);
}



Here is an example in MSDN, same as that of your application:
http://www.microsoft.com/msj/0497/wicked/wicked0497.aspx

MSDN link to get Information About the Contents of a Folder
http://msdn.microsoft.com/en-us/library/windows/desktop/bb776885(v=vs.85).aspx

Shell context menu support:
http://netez.com/2xExplorer/shellFAQ/bas_context.html#getmenu
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900