You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
4.7 KiB
210 lines
4.7 KiB
// menucmd.cpp - Context menu command class
|
|
|
|
#include "stdafx.h"
|
|
#include "menucmd.h"
|
|
#include "streamio.h"
|
|
#include "qryitem.h"
|
|
#include "resource.h"
|
|
#include <shellapi.h>
|
|
#include <algorithm>
|
|
#include <atlgdi.h>
|
|
|
|
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<long>(vMenus.size());
|
|
|
|
menucmd_vector::iterator itMenu;
|
|
for (itMenu = vMenus.begin(); itMenu != vMenus.end(); ++itMenu)
|
|
{
|
|
stm << static_cast<int>((*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<MENUTYPE>(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;
|
|
}
|
|
|
|
|
|
|
|
|