648 lines
14 KiB
C++
648 lines
14 KiB
C++
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1995 - 1996.
|
||
|
//
|
||
|
// File: ShellEx.cxx
|
||
|
//
|
||
|
// Contents:
|
||
|
//
|
||
|
// Classes:
|
||
|
//
|
||
|
// Functions:
|
||
|
//
|
||
|
// History: 4/25/1996 RaviR Created
|
||
|
//
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
#include "..\pch\headers.hxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <mstask.h>
|
||
|
#include "..\folderui\dbg.h"
|
||
|
#include "..\folderui\macros.h"
|
||
|
|
||
|
#include "dll.hxx"
|
||
|
#include "..\folderui\jobicons.hxx"
|
||
|
#include "..\folderui\util.hxx"
|
||
|
#include "schedui.hxx"
|
||
|
|
||
|
|
||
|
extern "C" const GUID IID_IShellExtInit;
|
||
|
extern "C" const GUID IID_IShellPropSheetExt;
|
||
|
|
||
|
|
||
|
TCHAR const c_szTask[] = TEXT("task!");
|
||
|
|
||
|
|
||
|
class CSchedObjExt : public IShellExtInit,
|
||
|
//public IContextMenu,
|
||
|
public IShellPropSheetExt
|
||
|
{
|
||
|
public:
|
||
|
CSchedObjExt();
|
||
|
~CSchedObjExt();
|
||
|
|
||
|
// IUnknown methods
|
||
|
DECLARE_STANDARD_IUNKNOWN;
|
||
|
|
||
|
// IShellExtInit methods
|
||
|
STDMETHOD(Initialize)(LPCITEMIDLIST pidlFolder, LPDATAOBJECT pdtobj,
|
||
|
HKEY hkeyProgID);
|
||
|
|
||
|
// IShellPropSheetExt methods
|
||
|
STDMETHOD(AddPages)(LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam);
|
||
|
STDMETHOD(ReplacePage)(UINT uPageID,
|
||
|
LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam);
|
||
|
|
||
|
private:
|
||
|
CDllRef m_DllRef;
|
||
|
LPDATAOBJECT m_pdtobj; // data object
|
||
|
HKEY m_hkeyProgID; // reg. database key to ProgID
|
||
|
|
||
|
}; // CSchedObjExt
|
||
|
|
||
|
|
||
|
inline
|
||
|
CSchedObjExt::CSchedObjExt()
|
||
|
:
|
||
|
m_ulRefs(1),
|
||
|
m_pdtobj(NULL),
|
||
|
m_hkeyProgID(NULL)
|
||
|
{
|
||
|
TRACE(CSchedObjExt, CSchedObjExt);
|
||
|
}
|
||
|
|
||
|
|
||
|
CSchedObjExt::~CSchedObjExt()
|
||
|
{
|
||
|
TRACE(CSchedObjExt, ~CSchedObjExt);
|
||
|
|
||
|
if (m_pdtobj)
|
||
|
{
|
||
|
m_pdtobj->Release();
|
||
|
}
|
||
|
|
||
|
if (m_hkeyProgID)
|
||
|
{
|
||
|
RegCloseKey(m_hkeyProgID);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// IUnknown implementation
|
||
|
//
|
||
|
IMPLEMENT_STANDARD_IUNKNOWN(CSchedObjExt);
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CSchedObjExt::QueryInterface(REFIID riid, void **ppvObject)
|
||
|
{
|
||
|
IUnknown *pUnkTemp = NULL;
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (ppvObject == NULL)
|
||
|
{
|
||
|
return(E_INVALIDARG);
|
||
|
}
|
||
|
|
||
|
*ppvObject = NULL; // in case of error.
|
||
|
|
||
|
if (IsEqualIID(IID_IUnknown, riid) ||
|
||
|
IsEqualIID(IID_IShellExtInit, riid))
|
||
|
{
|
||
|
pUnkTemp = (IUnknown *)(IShellExtInit *)this;
|
||
|
}
|
||
|
else if (IsEqualIID(IID_IShellPropSheetExt, riid))
|
||
|
{
|
||
|
pUnkTemp = (IUnknown *)(IShellPropSheetExt *)this;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
if ((pUnkTemp != NULL) && (SUCCEEDED(hr)))
|
||
|
{
|
||
|
*ppvObject = (void*)pUnkTemp;
|
||
|
pUnkTemp->AddRef();
|
||
|
}
|
||
|
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Member: CSchedObjExt::Initialize
|
||
|
//
|
||
|
// Synopsis: S
|
||
|
//
|
||
|
// Arguments: [pidlFolder] -- IN
|
||
|
// [pdtobj] -- IN
|
||
|
// [hkeyProgID] -- IN
|
||
|
//
|
||
|
// Returns: HRESULT.
|
||
|
//
|
||
|
// History: 4/25/1996 RaviR Created
|
||
|
//
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CSchedObjExt::Initialize(
|
||
|
LPCITEMIDLIST pidlFolder,
|
||
|
LPDATAOBJECT pdtobj,
|
||
|
HKEY hkeyProgID)
|
||
|
{
|
||
|
TRACE(CSchedObjExt, Initialize);
|
||
|
|
||
|
// Initialize can be called more than once.
|
||
|
if (m_pdtobj)
|
||
|
{
|
||
|
m_pdtobj->Release();
|
||
|
}
|
||
|
|
||
|
if (m_hkeyProgID)
|
||
|
{
|
||
|
RegCloseKey(m_hkeyProgID);
|
||
|
m_hkeyProgID = NULL;
|
||
|
}
|
||
|
|
||
|
// Duplicate the pdtobj pointer
|
||
|
m_pdtobj = pdtobj;
|
||
|
|
||
|
if (pdtobj)
|
||
|
{
|
||
|
pdtobj->AddRef();
|
||
|
}
|
||
|
|
||
|
// Duplicate the handle
|
||
|
if (hkeyProgID)
|
||
|
{
|
||
|
RegOpenKeyEx(hkeyProgID, NULL, 0, KEY_ALL_ACCESS, &m_hkeyProgID);
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CSchedObjExt::IShellPropSheetExt::AddPages
|
||
|
//
|
||
|
// Synopsis: (from shlobj.h)
|
||
|
// "The explorer calls this member function when it finds a
|
||
|
// registered property sheet extension for a particular type
|
||
|
// of object. For each additional page, the extension creates
|
||
|
// a page object by calling CreatePropertySheetPage API and
|
||
|
// calls lpfnAddPage.
|
||
|
//
|
||
|
// Arguments: lpfnAddPage -- Specifies the callback function.
|
||
|
// lParam -- Specifies the opaque handle to be passed to the
|
||
|
// callback function.
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 12-Oct-94 RaviR
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CSchedObjExt::AddPages(
|
||
|
LPFNADDPROPSHEETPAGE lpfnAddPage,
|
||
|
LPARAM lParam)
|
||
|
{
|
||
|
TRACE(CSchedObjExt, AddPages);
|
||
|
|
||
|
//
|
||
|
// Call IDataObject::GetData asking for a CF_HDROP (i.e., HDROP).
|
||
|
//
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
STGMEDIUM medium;
|
||
|
FORMATETC fmte = {CF_HDROP, (DVTARGETDEVICE *)NULL, DVASPECT_CONTENT,
|
||
|
-1, TYMED_HGLOBAL };
|
||
|
|
||
|
hr = m_pdtobj->GetData(&fmte, &medium);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
CHECK_HRESULT(hr);
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
do
|
||
|
{
|
||
|
//
|
||
|
// Ensure it is only a single selection.
|
||
|
//
|
||
|
|
||
|
UINT cObjects = DragQueryFile((HDROP)medium.hGlobal,
|
||
|
(UINT)-1, NULL, 0);
|
||
|
if (cObjects != 1)
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create shared info for all pages
|
||
|
//
|
||
|
|
||
|
TCHAR szFile[MAX_PATH + 1];
|
||
|
UINT cchRet = DragQueryFile((HDROP)medium.hGlobal, 0, szFile,
|
||
|
ARRAYLEN(szFile));
|
||
|
|
||
|
//
|
||
|
// Bind to the ITask interface.
|
||
|
//
|
||
|
|
||
|
ITask * pIJob = NULL;
|
||
|
|
||
|
hr = JFCreateAndLoadTask(NULL, szFile, &pIJob);
|
||
|
|
||
|
BREAK_ON_FAIL(hr);
|
||
|
|
||
|
// Add the tasks page
|
||
|
hr = AddGeneralPage(lpfnAddPage, lParam, pIJob);
|
||
|
CHECK_HRESULT(hr);
|
||
|
|
||
|
// Add the schedule page
|
||
|
hr = AddSchedulePage(lpfnAddPage, lParam, pIJob);
|
||
|
CHECK_HRESULT(hr);
|
||
|
|
||
|
// Add the settings page
|
||
|
hr = AddSettingsPage(lpfnAddPage, lParam, pIJob);
|
||
|
CHECK_HRESULT(hr);
|
||
|
|
||
|
pIJob->Release();
|
||
|
|
||
|
} while (0);
|
||
|
|
||
|
ReleaseStgMedium(&medium);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CSchedObjExt::IShellPropSheetExt::ReplacePages
|
||
|
//
|
||
|
// Synopsis: (From shlobj.h)
|
||
|
// "The explorer never calls this member of property sheet
|
||
|
// extensions. The explorer calls this member of control panel
|
||
|
// extensions, so that they can replace some of default control
|
||
|
// panel pages (such as a page of mouse control panel)."
|
||
|
//
|
||
|
// Arguments: uPageID -- Specifies the page to be replaced.
|
||
|
// lpfnReplace -- Specifies the callback function.
|
||
|
// lParam -- Specifies the opaque handle to be passed to the
|
||
|
// callback function.
|
||
|
//
|
||
|
// Returns:
|
||
|
//
|
||
|
// History: 12-Oct-94 RaviR
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CSchedObjExt::ReplacePage(
|
||
|
UINT uPageID,
|
||
|
LPFNADDPROPSHEETPAGE lpfnReplaceWith,
|
||
|
LPARAM lParam)
|
||
|
{
|
||
|
TRACE(CSchedObjExt, ReplacePage);
|
||
|
|
||
|
Win4Assert(!"CSchedObjExt::ReplacePage called, not implemented");
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Function: JFGetSchedObjExt
|
||
|
//
|
||
|
// Synopsis: Create an instance of CSchedObjExt and return the requested
|
||
|
// interface.
|
||
|
//
|
||
|
// Arguments: [riid] -- IN interface needed.
|
||
|
// [ppvObj] -- OUT place to store the interface.
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// History: 1/24/1996 RaviR Created
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
HRESULT
|
||
|
JFGetSchedObjExt(
|
||
|
REFIID riid,
|
||
|
LPVOID* ppvObj)
|
||
|
{
|
||
|
CSchedObjExt * pSchedObjExt = new CSchedObjExt();
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (pSchedObjExt != NULL)
|
||
|
{
|
||
|
hr = pSchedObjExt->QueryInterface(riid, ppvObj);
|
||
|
|
||
|
CHECK_HRESULT(hr);
|
||
|
|
||
|
pSchedObjExt->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
CHECK_HRESULT(hr);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
class CTaskIconExt : public IExtractIcon,
|
||
|
public IPersistFile
|
||
|
{
|
||
|
public:
|
||
|
CTaskIconExt(void);
|
||
|
~CTaskIconExt(void);
|
||
|
|
||
|
// IUnknown methods
|
||
|
DECLARE_STANDARD_IUNKNOWN;
|
||
|
|
||
|
// IExtractIcon methods
|
||
|
STDMETHOD(GetIconLocation)(UINT uFlags, LPTSTR szIconFile, UINT cchMax,
|
||
|
int *piIndex, UINT *pwFlags);
|
||
|
STDMETHOD(Extract)(LPCTSTR pszFile, UINT nIconIndex, HICON *phiconLarge,
|
||
|
HICON *phiconSmall, UINT nIconSize);
|
||
|
|
||
|
// IPersistFile methods
|
||
|
STDMETHOD(GetClassID)(LPCLSID lpClsID);
|
||
|
STDMETHOD(IsDirty)();
|
||
|
STDMETHOD(Load)(LPCOLESTR pszFile, DWORD grfMode);
|
||
|
STDMETHOD(Save)(LPCOLESTR pszFile, BOOL fRemember);
|
||
|
STDMETHOD(SaveCompleted)(LPCOLESTR pszFile);
|
||
|
STDMETHOD(GetCurFile)(LPOLESTR FAR *ppszFile);
|
||
|
|
||
|
private:
|
||
|
TCHAR m_szTask[MAX_PATH + 1];
|
||
|
|
||
|
}; // CTaskIconExt
|
||
|
|
||
|
|
||
|
inline
|
||
|
CTaskIconExt::CTaskIconExt(void)
|
||
|
:
|
||
|
m_ulRefs(1)
|
||
|
{
|
||
|
TRACE(CTaskIconExt, CTaskIconExt);
|
||
|
|
||
|
m_szTask[0] = TEXT('\0');
|
||
|
}
|
||
|
|
||
|
inline
|
||
|
CTaskIconExt::~CTaskIconExt(void)
|
||
|
{
|
||
|
TRACE(CTaskIconExt, ~CTaskIconExt);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// IUnknown implementation
|
||
|
//
|
||
|
IMPLEMENT_STANDARD_IUNKNOWN(CTaskIconExt);
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTaskIconExt::QueryInterface(REFIID riid, LPVOID* ppvObj)
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (IsEqualIID(IID_IUnknown, riid) ||
|
||
|
IsEqualIID(IID_IPersistFile, riid))
|
||
|
{
|
||
|
*ppvObj = (IUnknown*)(IPersistFile*) this;
|
||
|
}
|
||
|
else if (IsEqualIID(IID_IExtractIcon, riid))
|
||
|
{
|
||
|
*ppvObj = (IUnknown*)(IExtractIcon*) this;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppvObj = NULL;
|
||
|
hr = E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
this->AddRef();
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Member: CTaskIconExt::IExtractIcon::GetIconLocation
|
||
|
//
|
||
|
// Arguments: [uFlags] -- IN
|
||
|
// [szIconFile] -- IN
|
||
|
// [cchMax] -- IN
|
||
|
// [piIndex] -- IN
|
||
|
// [pwFlags] -- IN
|
||
|
//
|
||
|
// Returns: HTRESULT
|
||
|
//
|
||
|
// History: 1/5/1996 RaviR Created
|
||
|
//
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTaskIconExt::GetIconLocation(
|
||
|
UINT uFlags,
|
||
|
LPTSTR szIconFile,
|
||
|
UINT cchMax,
|
||
|
int * piIndex,
|
||
|
UINT * pwFlags)
|
||
|
{
|
||
|
TRACE(CTaskIconExt, GetIconLocation);
|
||
|
|
||
|
if (uFlags & GIL_OPENICON)
|
||
|
{
|
||
|
return S_FALSE;
|
||
|
}
|
||
|
|
||
|
*pwFlags = GIL_NOTFILENAME | GIL_PERINSTANCE;
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
UINT len = lstrlen(c_szTask);
|
||
|
|
||
|
lstrcpy(szIconFile, c_szTask);
|
||
|
|
||
|
hr = JFGetAppNameForTask(m_szTask, &szIconFile[len], cchMax - len);
|
||
|
|
||
|
*piIndex = FALSE;
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Member: CTaskIconExt::Extract
|
||
|
//
|
||
|
// Arguments: [pszFile] -- IN
|
||
|
// [nIconIndex] -- IN
|
||
|
// [phiconLarge] -- IN
|
||
|
// [phiconSmall] -- IN
|
||
|
// [nIconSize] -- IN
|
||
|
//
|
||
|
// Returns: STDMETHODIMP
|
||
|
//
|
||
|
// History: 1/5/1996 RaviR Created
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTaskIconExt::Extract(
|
||
|
LPCTSTR pszFile,
|
||
|
UINT nIconIndex,
|
||
|
HICON * phiconLarge,
|
||
|
HICON * phiconSmall,
|
||
|
UINT nIconSize)
|
||
|
{
|
||
|
TRACE(CTaskIconExt, Extract);
|
||
|
|
||
|
LPTSTR pszApp = (LPTSTR)(pszFile + lstrlen(c_szTask));
|
||
|
|
||
|
CJobIcon ji;
|
||
|
|
||
|
ji.GetIcons(pszApp, FALSE, phiconLarge, phiconSmall);
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Member: CTaskIconExt::Load
|
||
|
//
|
||
|
// Synopsis: S
|
||
|
//
|
||
|
// Arguments: [pszFile] -- IN
|
||
|
// [grfMode] -- IN
|
||
|
//
|
||
|
// Returns: HRESULT.
|
||
|
//
|
||
|
// History: 4/25/1996 RaviR Created
|
||
|
//
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTaskIconExt::Load(
|
||
|
LPCOLESTR pszFile,
|
||
|
DWORD grfMode)
|
||
|
{
|
||
|
TRACE(CTaskIconExt, Load);
|
||
|
|
||
|
#ifdef UNICODE
|
||
|
lstrcpy(m_szTask, pszFile);
|
||
|
#else
|
||
|
UnicodeToAnsi(m_szTask, pszFile, MAX_PATH+1);
|
||
|
#endif
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
|
||
|
// The following functions, which are part of the OLE IPersistFile interface,
|
||
|
// are not required for shell extensions. In the unlikely event that they are
|
||
|
// called, they return the error code E_FAIL.
|
||
|
//
|
||
|
|
||
|
STDMETHODIMP CTaskIconExt::GetClassID(LPCLSID lpClsID)
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTaskIconExt::IsDirty()
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTaskIconExt::Save(LPCOLESTR pszFile, BOOL fRemember)
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTaskIconExt::SaveCompleted(LPCOLESTR pszFile)
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CTaskIconExt::GetCurFile(LPOLESTR FAR *ppszFile)
|
||
|
{
|
||
|
return E_FAIL;
|
||
|
}
|
||
|
|
||
|
|
||
|
//____________________________________________________________________________
|
||
|
//
|
||
|
// Function: JFGetTaskIconExt
|
||
|
//
|
||
|
// Synopsis: Create an instance of CTaskIconExt and return the requested
|
||
|
// interface.
|
||
|
//
|
||
|
// Arguments: [riid] -- IN interface needed.
|
||
|
// [ppvObj] -- OUT place to store the interface.
|
||
|
//
|
||
|
// Returns: HRESULT
|
||
|
//
|
||
|
// History: 1/24/1996 RaviR Created
|
||
|
//____________________________________________________________________________
|
||
|
|
||
|
HRESULT
|
||
|
JFGetTaskIconExt(
|
||
|
REFIID riid,
|
||
|
LPVOID* ppvObj)
|
||
|
{
|
||
|
TRACE_FUNCTION(JFGetTaskIconExt);
|
||
|
|
||
|
CTaskIconExt * pTaskIconExt = new CTaskIconExt();
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if (pTaskIconExt != NULL)
|
||
|
{
|
||
|
hr = pTaskIconExt->QueryInterface(riid, ppvObj);
|
||
|
|
||
|
CHECK_HRESULT(hr);
|
||
|
|
||
|
pTaskIconExt->Release();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
CHECK_HRESULT(hr);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|