⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shellcontextmenu.cpp

📁 vc座的资源管理器源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                    if (SUCCEEDED(hr) && dwEffect) 
                    {
                        hr = pDT->Drop(pDO, MK_LBUTTON, pt, &dwEffect);
                    } 
                    else 
                    {
                        hr = pDT->DragLeave();
                    }

                    pDT->Release();
                }

                pidlDrop.m_pidl = NULL;
            }
        }
        else
        {
			DWORD dwItemData=0;
			CMenu *pMenu=NULL;
			STL_FOR_ITERATOR(vecODMenu,m_OwnerDrawMenus)
			{
				pMenu = STL_GET_CURRENT(m_OwnerDrawMenus);
				if (pMenu && pMenu->GetMenuItemCount() > 0)
				{
					// switch to original item data
					if ((UINT)iCmd >= pMenu->GetMenuItemID(0) && (UINT)iCmd <= pMenu->GetMenuItemID(pMenu->GetMenuItemCount()-1))
					{
						dwItemData = g_CoolMenuManager.SwitchContextItemData(pMenu,iCmd,0,FALSE);
						break;
					}
				}
			}
			CWaitCursor w;
            // Shell command
            CMINVOKECOMMANDINFO cmi;
            cmi.cbSize       = sizeof(cmi);
            cmi.fMask        = 0;
            cmi.hwnd         = m_hWnd;
            cmi.lpVerb       = T2CA(MAKEINTRESOURCE(iCmd - IDM_SHELLCTXFIRST));
            cmi.lpParameters = NULL;
            cmi.lpDirectory  = NULL;
            cmi.nShow        = SW_SHOWNORMAL;
            cmi.dwHotKey     = 0;
            cmi.hIcon        = NULL;
            m_lpcm->InvokeCommand(&cmi);
			// switch back to our item data
			if (dwItemData)
			{
				g_CoolMenuManager.SwitchContextItemData(pMenu,iCmd,dwItemData,FALSE);
			}
        }
}

// retrieves the shell context menu for a file
void CShellContextMenu::SetMenu(CMenu *pMenu)
{
    if (m_sAbsPath.IsEmpty())
		return;
	ASSERT(m_psfParent);
    HRESULT hr = m_psfParent->GetUIObjectOf(m_hWnd, m_cidl, (LPCITEMIDLIST*)m_ppidl, IID_IContextMenu, NULL, (LPVOID *)&m_lpcm);
// NOTE: Slight change to return here but change it back if you want: PO
    if (FAILED(hr))
		return;
	
    g_CoolMenuManager.UnconvertMenu(pMenu);
	g_CoolMenuManager.SetShellContextMenu(m_lpcm,IDM_SHELLCTXFIRST,IDM_SHELLCTXLAST);

    pMenu->DeleteMenu(0, MF_BYPOSITION);
    hr = m_lpcm->QueryContextMenu(*pMenu, 0, IDM_SHELLCTXFIRST, 
        IDM_SHELLCTXLAST, CMF_EXPLORE);
	/////////////////////////////
	// Additions Philip Oldaker 
	// Check for IContextMenu2 used by owner draw menus
    CMenu *pSubMenu;
    int count = pMenu->GetMenuItemCount();
    for (int i = 0; i < count; i++)
    {
		CMenuItemInfo mii;
		mii.fMask = MIIM_TYPE | MIIM_ID;
		pMenu->GetMenuItemInfo(i,&mii,TRUE);
		if (mii.fType & MFT_OWNERDRAW)
		{
			TRACE(_T("OwnerDraw menu item found in CShellContextMenu\n"));
            g_CoolMenuManager.AddShellContextMenu(pMenu,m_lpcm,i);
			STL_ADD_ITEM(m_OwnerDrawMenus,pMenu);
		}
        pSubMenu = pMenu->GetSubMenu(i);
		/////////////////////////////
		// Additions Philip Oldaker 
		// Search for owner draw menus and add the ICM2 pointer
		if (pSubMenu)
		{
			// NOTE: Remove the TRACE statements if not needed
			UINT nSubCount = pSubMenu->GetMenuItemCount();
			TRACE(_T("Count=%u\n"),nSubCount);
			for(UINT m=0;m < nSubCount;m++)
			{
				CMenuItemInfo mii;
				mii.fMask = MIIM_TYPE;
				pSubMenu->GetMenuItemInfo(m,&mii,TRUE);
				if (mii.fType & MFT_OWNERDRAW)
				{
					TRACE(_T("OwnerDraw submenu found in CShellContextMenu\n"));
                    g_CoolMenuManager.AddShellContextMenu(pSubMenu,m_lpcm,m);
					STL_ADD_ITEM(m_OwnerDrawMenus,pSubMenu);
				}
			}
		}
		/////////////////////////////
	    // find the "Send To" and the new "Open With" submenu: look for a defined menu item id
        if (pSubMenu && pSubMenu->GetMenuItemCount() == 1)
        {
		    CString str;
			pSubMenu->GetMenuString(0,str,MF_BYPOSITION);
            UINT idmFirst = pSubMenu->GetMenuItemID(0);
			TRACE(_T("Menu Item %s=%d\n"),str,idmFirst);
			/////////////////////////////
			// Additions Philip Oldaker 
			// Populate the OpenWith menu
			if (idmFirst == IDM_OPENWITHID1 || idmFirst == IDM_OPENWITHID2)
			{
				// ok - found it.  now populate it
				IContextMenu2 *lpcm2=NULL;
				HRESULT hr = m_lpcm->QueryInterface(IID_IContextMenu2,(LPVOID*)&lpcm2);
				if (SUCCEEDED(hr))
				{
					hr = lpcm2->HandleMenuMsg(WM_INITMENUPOPUP,(WPARAM)pSubMenu->GetSafeHmenu(),0);
					lpcm2->Release();
					// We need the extension to search the registry for valid applications
					CString sExt(GetExt(m_sAbsPath));
					// No extension then there's nothing to do
					if (sExt.IsEmpty())
						continue;
					FillOpenWithMenu(pSubMenu,sExt);
					STL_ADD_ITEM(m_OwnerDrawMenus,pSubMenu);
				}
			}
            else if (idmFirst == IDM_SENDTOID)
            {
	            UINT idm = IDM_SENDTOFIRST;
                // ok - found it.  now populate it
                m_pSendToMenu = CMenu::FromHandle(::CreatePopupMenu());
                ASSERT_VALID(m_pSendToMenu);
                pSubMenu->DestroyMenu();
                pMenu->ModifyMenu(i, MF_BYPOSITION | MF_POPUP, 
                    (UINT)m_pSendToMenu->m_hMenu, str);
                FillSendToMenu(m_pSendToMenu, stat_data.m_sfSendTo, idm);
            }
			/////////////////////////////
        }
    }
// Not needed I think :PO
    return;
}

////////////////////////////
// Additions: Philip Oldaker
// Scan the registry looking for a OpenWithList key in this format
// Entry MRUList contains the alphabetical order eg. afgrde for each entry
// each of these entries points to the application name which in turn
// has the command and display name
////////////////////////////
void CShellContextMenu::FillOpenWithMenu(CMenu *pMenu,const CString &sExt)
{
	HKEY hKey;
	CString sFileExtKey(szFileExtKey);
	AddKey(sFileExtKey,sExt);
	AddKey(sFileExtKey,szOpenWithListKey);
	if (RegOpenKeyEx(HKEY_CURRENT_USER,sFileExtKey,0,KEY_READ,&hKey) != ERROR_SUCCESS)
		return;
	BYTE szMRUList[_MAX_PATH];
	szMRUList[0] = 0;
	DWORD dwSize=sizeof(szMRUList);
	DWORD dwType=REG_SZ;
	RegQueryValueEx(hKey,szMRUListEntry,NULL,&dwType,szMRUList,&dwSize);
	int nLen = _tcslen((LPCTSTR)szMRUList);
	TCHAR szOpenWithItemEntry[sizeof(TCHAR)*2];
	ZeroMemory(szOpenWithItemEntry,sizeof(szOpenWithItemEntry));
	BYTE szOpenWithItem[_MAX_PATH];
	CString sDisplayName;
	HICON hIconApp;
	CString sCommand;
	CString sMenuText;
	for(int i=0;i < nLen;i++)
	{
		szOpenWithItemEntry[0] = szMRUList[i];
		dwSize = sizeof(szOpenWithItem);
		RegQueryValueEx(hKey,szOpenWithItemEntry,NULL,&dwType,szOpenWithItem,&dwSize);
		GetAppDetails(szOpenWithItem, sDisplayName, sCommand, hIconApp);
		if (!sCommand.IsEmpty())
		{
			for(UINT idm=0;idm < pMenu->GetMenuItemCount();idm++)
			{
				pMenu->GetMenuString(idm,sMenuText,MF_BYPOSITION);
				if (sMenuText == sDisplayName)
				{
					g_CoolMenuManager.ConvertMenuItem(pMenu, idm);
					CCoolMenuManager::SetItemIcon(*pMenu, hIconApp, idm, TRUE);
					break;
				}
			}
		}
	}
	RegCloseKey(hKey);
}

void CShellContextMenu::FillSendToMenu(CMenu *pMenu, LPSHELLFOLDER pSF, 
                                       UINT &idm)
{
    if (pSF == NULL) 
		return;
    USES_CONVERSION;
    CPIDL           pidl, abspidl;
    LPENUMIDLIST    peidl;
    HRESULT         hr;
    STRRET          str;
    UINT            idmStart = idm;
    LPSHELLFOLDER   pSubSF;
    SHFILEINFO      sfi;
	vecCMSort vMenuItems;

    int idx_folder = 0; // folder insertion index

    hr = pSF->EnumObjects(m_hWnd, 
        SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &peidl);
    if (FAILED(hr))
		return;
    g_CoolMenuManager.ConvertMenu(pMenu);
    while (peidl->Next(1, pidl, NULL) == S_OK  &&
           idm < IDM_SENDTOLAST) 
    {
        hr = pSF->GetDisplayNameOf(pidl, SHGDN_NORMAL, &str);
        if (SUCCEEDED(hr)) 
        {
            ULONG ulAttrs = (unsigned)-1;
            pSF->GetAttributesOf(1, pidl, &ulAttrs);
            abspidl.MakeAbsPIDLOf(pSF, pidl);
            SHGetFileInfo((LPCTSTR)abspidl.m_pidl, 0, &sfi, sizeof(sfi),
                SHGFI_PIDL | SHGFI_ICON | SHGFI_SMALLICON);
            pidl.ExtractCStr(str);
            if (ulAttrs & SFGAO_FOLDER) // folder?
            {
                // create new submenu & recurse
                HMENU hSubMenu = ::CreateMenu();
                pMenu->InsertMenu(idx_folder, 
                    MF_POPUP | MF_BYPOSITION | MF_STRING, 
                    (UINT)hSubMenu, A2T(str.cStr));
                g_CoolMenuManager.ConvertMenuItem(pMenu, 
                    idx_folder);
                CCoolMenuManager::SetItemIcon(*pMenu, 
                    sfi.hIcon, idx_folder, TRUE);
                idx_folder++;
                hr = pSF->BindToObject(pidl, NULL, 
                    IID_IShellFolder, (LPVOID *)&pSubSF);
                if (!SUCCEEDED(hr)) pSubSF = NULL;
                FillSendToMenu(CMenu::FromHandle(hSubMenu), pSubSF, 
                    idm);
                if (pSubSF) pSubSF->Release();
                abspidl.Free();
            }
            else
            {
				CShCMSort *pSMI = new CShCMSort(idm,pidl.m_pidl,sfi.hIcon,A2T(str.cStr),(DWORD)abspidl.m_pidl);
				STL_ADD_ITEM(vMenuItems,pSMI);
                idm++;
            }
            abspidl.m_pidl = NULL;
        }
    }
    peidl->Release();
// Addition: Philip Oldaker
// To keep it familiar the SendTo menu is sorted
	STL_SORT(vMenuItems,pSF,STL_SORT_FUNC);
	CShCMSort *pItem=NULL;
	STL_FOR_ITERATOR(vecCMSort,vMenuItems)
	{
		pItem = STL_GET_CURRENT(vMenuItems);
		pMenu->AppendMenu(MF_STRING, pItem->GetItemID(), pItem->GetText());
		g_CoolMenuManager.ConvertMenuItem(pMenu, 
			pMenu->GetMenuItemCount() - 1);
		CCoolMenuManager::SetItemIcon(*pMenu, 
			pItem->GetIcon(), pItem->GetItemID());
		CCoolMenuManager::SetItemData(*pMenu, 
			(void*)pItem->GetItemData(), pItem->GetItemID());
        CPIDL toFree(pItem->GetPidl());
		delete pItem;
	}
	STL_ERASE_ALL(vMenuItems);
//////////////////////////////////
    // If the menu is still empty (the user has an empty SendTo folder),
    // then add a disabled "(empty)" item so we have at least something
    // to display.
    if (idm == idmStart) 
    {
        pMenu->AppendMenu(MF_GRAYED | MF_DISABLED | MF_STRING, idm, 
            _T("(empty)"));
        idm++;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -