Search code examples
c++shellmfcguidclsid

C++ MFC create IShellItem from CLSID (GUID)


I have to create a ShellItem to Windows Help and Windows Run...

I have this

Help and Support    {2559a1f1-21d7-11d4-bdaf-00c04f60b9f0}
Run {2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}

from http://www.sevenforums.com/tutorials/110919-clsid-key-list-windows-7-a.html

I've tried

IShellFolder* desk = NULL;
HRESULT hr =SHGetDesktopFolder(&desk);
LPITEMIDLIST pidl2=NULL;
            ULONG cbEaten;
            DWORD dwAttribs = 0 ;

            hr = desk->ParseDisplayName(NULL,
                                         NULL,
                                         L"::{2559A1F1-21D7-11D4-BDAF-00C04F60B9F0}",
                                     &cbEaten,  // This can be NULL
                                         &pidl2,
                                         &dwAttribs);

It returns OK but Null as pidl2

could you guys give me some help?


Solution

  • ParseDisplayName should be able to parse it if you pass "shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}" but I guess that is not really what you want.

    ParseDisplayName is able to parse some ::{clsid} paths but I think it is restricted to a very limited set of CSIDL_* special folders. SHSimpleIDListFromPath was able to parse it.

    If you really want to parse it with ParseDisplayName you can try to emulate SHSimpleIDListFromPath:

    class EmptyFileSystemBindData : public IFileSystemBindData {
    public:
        STDMETHODIMP QueryInterface(REFIID riid, void **ppv)
        {
            if (riid == IID_IUnknown || riid == IID_IFileSystemBindData) {
                *ppv = static_cast<IUnknown*>(this);
                AddRef();
                return S_OK;
            }
            *ppv = NULL; return E_NOINTERFACE;
        }
        STDMETHODIMP_(ULONG) AddRef() { return 2; }
        STDMETHODIMP_(ULONG) Release() { return 1; }
        STDMETHODIMP SetFindData(const WIN32_FIND_DATAW *pfd) 
        {
            return S_OK;
        }
        STDMETHODIMP GetFindData(WIN32_FIND_DATAW *pfd)
        {
            ZeroMemory(pfd,sizeof(WIN32_FIND_DATAW));
            return S_OK;
        }
    };
    
    LPITEMIDLIST pidl2=NULL;
    HRESULT hr;
    IShellFolder*psf;
    IBindCtx*pbc;
    hr = CreateBindCtx(0,&pbc);
    EmptyFileSystemBindData efsbd;
    if (SUCCEEDED(hr))
    {
        BIND_OPTS bo = {sizeof(bo)};
        bo.grfMode = STGM_CREATE;
        hr = pbc->RegisterObjectParam(STR_FILE_SYS_BIND_DATA,&efsbd);
        if (SUCCEEDED(hr) && 0==pbc->SetBindOptions(&bo))
        {
            hr = SHGetDesktopFolder(&psf);
            if (SUCCEEDED(hr))
            {
                hr = psf->ParseDisplayName(0,pbc,L"::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0}",0,&pidl2,0);
                if (SUCCEEDED(hr))
                {
                    OutputDebugStringA("parsed ok\n");
                    ILFree(pidl2);
                }
                psf->Release();
            }
        }
        pbc->Release();
    }