// menucmd.cpp - Context menu command class #include "stdafx.h" #include "menucmd.h" #include "streamio.h" #include "qryitem.h" #include "resource.h" #include #include #include extern DWORD g_dwFileVer; // Current console file version (from compdata.cpp) // Table of standard menu command parameters // Gives order for parameter menu and maps ID to resource string // Zero entry indicates menu separator const MENU_PARAM_ENTRY MenuParamTable[MENU_PARAM_TABLE_LEN] = { { MENU_PARAM_SCOPE, IDS_QUERY_SCOPE }, { MENU_PARAM_FILTER, IDS_QUERY_FILTER }, { MENU_PARAM_ID(0), 0 }, { MENU_PARAM_NAME, IDS_NAME }, { MENU_PARAM_TYPE, IDS_TYPE }, }; ///////////////////////////////////////////////////////////////////////////////////////// // CShellMenuCmd HRESULT CShellMenuCmd::Save(IStream& stm) { stm << m_menuID; stm << m_dwFlags; stm << m_strProgPath; stm << m_strCmdLine; stm << m_strStartDir; stm << m_guidNoLocMenu; return S_OK; } HRESULT CShellMenuCmd::Load(IStream& stm) { stm >> m_menuID; if (g_dwFileVer >= 101) stm >> m_dwFlags; stm >> m_strProgPath; stm >> m_strCmdLine; stm >> m_strStartDir; if( g_dwFileVer >= 150 ) { stm >> m_guidNoLocMenu; } return S_OK; } HRESULT CShellMenuCmd::Execute(CParamLookup* pLookup, HANDLE* phProcess) { ASSERT(pLookup != NULL && phProcess != NULL); *phProcess = NULL; // Substitue parameter values in the command line tstring strParam = m_strCmdLine; HRESULT hr = ReplaceParameters(strParam, *pLookup, FALSE); RETURN_ON_FAILURE(hr); // Expand any environment variables tstring strLocProgPath; hr = ExpandEnvironmentParams(m_strProgPath, strLocProgPath); RETURN_ON_FAILURE(hr); tstring strLocStartDir; hr = ExpandEnvironmentParams(m_strStartDir, strLocStartDir); RETURN_ON_FAILURE(hr); tstring strLocParam; ExpandEnvironmentParams(strParam, strLocParam); RETURN_ON_FAILURE(hr); // Execute the command SHELLEXECUTEINFO info; info.cbSize = sizeof(info); info.fMask = SEE_MASK_NOCLOSEPROCESS; info.hwnd = NULL; info.lpVerb = NULL; info.lpFile = strLocProgPath.c_str(); info.lpParameters = strLocParam.c_str(); info.lpDirectory = strLocStartDir.c_str(); info.nShow = SW_SHOWNORMAL; info. hInstApp = 0; info.hProcess = 0; *phProcess = info.hProcess; BOOL bStat = ShellExecuteEx(&info); if (!bStat) return E_FAIL; *phProcess = info.hProcess; return S_OK; } ///////////////////////////////////////////////////////////////////////////////////////// // CActDirMenuCmd HRESULT CActDirMenuCmd::Save(IStream& stm) { stm << m_menuID; stm << m_dwFlags; stm << m_strADName; stm << m_guidNoLocMenu; stm << m_strADNoLocName; return S_OK; } HRESULT CActDirMenuCmd::Load(IStream& stm) { stm >> m_menuID; if (g_dwFileVer >= 101) stm >> m_dwFlags; stm >> m_strADName; if( g_dwFileVer >= 150 ) { stm >> m_guidNoLocMenu; stm >> m_strADNoLocName; } return S_OK; } ////////////////////////////////////////////////////////////////////// // menu vector stream i/o IStream& operator<< (IStream& stm, menucmd_vector& vMenus) { stm << static_cast(vMenus.size()); menucmd_vector::iterator itMenu; for (itMenu = vMenus.begin(); itMenu != vMenus.end(); ++itMenu) { stm << static_cast((*itMenu)->MenuType()); HRESULT hr = (*itMenu)->Save(stm); THROW_ON_FAILURE(hr); } return stm; } IStream& operator>> (IStream& stm, menucmd_vector& vMenus) { long nItems; stm >> nItems; vMenus.reserve(nItems); for (long lItem = 0; lItem < nItems; ++lItem) { CMenuCmd* pMenu = NULL; int iType; stm >> iType; MENUTYPE type = static_cast(iType); switch (type) { case MENUTYPE_SHELL: pMenu = new CShellMenuCmd(); ASSERT(pMenu != NULL); break; case MENUTYPE_ACTDIR: pMenu = new CActDirMenuCmd(); ASSERT(pMenu != NULL); break; default: THROW_ON_FAILURE(E_FAIL); } if( pMenu ) { HRESULT hr = pMenu->Load(stm); THROW_ON_FAILURE(hr); vMenus.push_back(CMenuCmdPtr(pMenu)); } } return stm; }