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:
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
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
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;
}Code:
this->m_stdCMT->InvokeCommand(pici);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