Hi,

I've written a namespace extension (c++). What I want to do now is to copy the windows explorers 'open with' menu. I've implemented my context menu using IContextMenu, IContextMenu2 and IContextMenu3. I build a standard context menu for a dummy file and put the open with submenu into my own menu. What I've done so far is the following:

Code:
int AddStdOpenWithMenu(HMENU hmenu, UINT& indexMenu, UINT& idCmdFirst, UINT& idCmdLast, UINT uFlags, CItem* i){

int items = 0;

if(i != 0){

    CString filePath = i->GetTempFileDir();
    CString fileName = i->getFileName();

    if(PathFileExists(filePath)){

        if(filePath.Right(1).CompareNoCase(TEXT("\\")) != 0) filePath += TEXT("\\");
        filePath += fileName;

        // Dumm yerzeugen
        wofstream fStream;
        fStream.open(filePath, ios::out | ios::app);
        fStream.close();

        if(PathFileExists(filePath)){

            void* ppv = 0;
            HRESULT hr;
            LPITEMIDLIST pidl;
            SFGAOF sfgao;
            LPCITEMIDLIST pidlChild;

            hr = ::SHParseDisplayName(filePath, NULL, &pidl, 0, &sfgao);
            this->stdContextTmpDir = filePath;

            if(hr == S_OK){
                hr = SHBindToParent(pidl, IID_IShellFolder, (void**)&m_stdPSF, &pidlChild);
                if(hr == S_OK){    
                    hr = m_stdPSF->GetUIObjectOf(GetForegroundWindow(), 1, &pidlChild, IID_IContextMenu, NULL, &ppv);
                    if(hr == S_OK){

                        this->m_stdCTM = (IContextMenu*)ppv;

                        IContextMenu2* ctm2 = 0;
                        hr = this->m_stdCTM->QueryInterface(IID_IContextMenu2,(LPVOID*)&ctm2);   

                        if(hr == S_OK){

                            HMODULE g = GetModuleHandle(TEXT("shell32.dll"));

                            if(g != 0){
                                // "Öffnen mit" Schriftzug ermitteln
                                int maxBuffer = 1000;
                                LPTSTR pStr = new TCHAR[maxBuffer];
                                CString owStr1, owStr2;

                                int res = LoadString(g, 5376, pStr, maxBuffer);
                                if(res > 0) owStr1 = pStr;

                                res = LoadString(g, 5377, pStr, maxBuffer);
                                if(res > 0) owStr2 = pStr;

                                if(!owStr1.IsEmpty() || !owStr2.IsEmpty()){

                                    HMENU stdMenu = CreatePopupMenu();  

                                    int subIdCmdFirst = idCmdFirst + LASTMI + 1; // hier wird der maximale offset der Items addiert
                                    int ret = ctm2->QueryContextMenu(stdMenu, indexMenu, subIdCmdFirst, idCmdLast, uFlags);

                                    if(HRESULT_SEVERITY(ret) == SEVERITY_SUCCESS){

                                        int count = GetMenuItemCount(stdMenu);

                                        for(int i = 0; i < count; i++){

                                            res = GetMenuString(stdMenu, i, pStr, maxBuffer, MF_BYPOSITION);

                                            if(res > 0){

                                                if(_tcscmp(pStr, owStr1) == 0 || _tcscmp(pStr, owStr2) == 0){
                                                    //Öffnen mit Element gefunden

                                                    HMENU subMenu = GetSubMenu(stdMenu, i);                                                 

                                                    if(subMenu != 0){

                                                        hr = ctm2->HandleMenuMsg(WM_INITMENUPOPUP, (WPARAM)GetSubMenu(stdMenu,i) , i);

                                                        subMenu = GetSubMenu(stdMenu, i);

                                                        if(subMenu != 0){

                                                            MENUITEMINFO   mii;
                                                            TCHAR          szText[MAX_PATH];

                                                            ZeroMemory(&mii, sizeof(mii));
                                                            mii.cbSize = sizeof(mii);

                                                            _tcscpy(szText, pStr);
                                                            mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | MIIM_SUBMENU ;
                                                            mii.wID = idCmdFirst + MI_OPENWITH;
                                                            mii.fType = MFT_STRING;
                                                            mii.dwTypeData = szText;
                                                            mii.fState = MFS_ENABLED;
                                                            mii.hSubMenu = subMenu;

                                                            InsertMenuItem( hmenu, indexMenu++, TRUE, &mii);

                                                            items = HRESULT_CODE(ret);

                                                        }
                                                    }else{

                                                        MENUITEMINFO stdMi;
                                                        stdMi.cbSize = sizeof(stdMi);
                                                        stdMi.fMask =  MIIM_ID | MIIM_STATE;
                                                        stdMi.dwTypeData = 0;
                                                        GetMenuItemInfo(stdMenu, i, true, &stdMi);

                                                        MENUITEMINFO   mii;
                                                        TCHAR          szText[MAX_PATH];

                                                        ZeroMemory(&mii, sizeof(mii));
                                                        mii.cbSize = sizeof(mii);

                                                        _tcscpy(szText, pStr); 
                                                        mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
                                                        mii.wID = stdMi.wID;
                                                        mii.fType = MFT_STRING;
                                                        mii.dwTypeData = szText;
                                                        mii.fState = MFS_ENABLED;

                                                        InsertMenuItem( hmenu, indexMenu++, TRUE, &mii);

                                                        items = HRESULT_CODE(ret);

                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                delete[] pStr;
                            }
                            ctm2->Release();
                        }
                    }
                }
                ILFree(pidl);

            }
            DeleteFile(filePath);
        }
    }
}

return items;
}
In the handleMenuMsg functions I pass everything to the standard interface and also XP is drawing icons and texts without any problem. In the 'InvokeCommand' I then know if a command for myself is executed or if it came from the standard context menu. So let's say you open a txt file with explorer everything works fine. The problem is as soon as

Code:
this->m_stdCMT->InvokeCommand(pici);
is executed and you close the explorer (Win7, x64), it won't close the process anymore. Does anybody know why?

What I've found out is, that as soon as I do not release a IContextMenu interface properly the whole explorer.exe process won't quit. It simply hangs... So I think InvokeCommand is allocating something which is not freed properly?! Any suggestions?

Kind regards, Michael