Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

653 lines
16 KiB

//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 1996.
//
// File: dataobj.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 1/17/1996 RaviR Created
//
//____________________________________________________________________________
#include "..\pch\headers.hxx"
#pragma hdrstop
#include "dbg.h"
#include "macros.h"
#include "jobidl.hxx"
extern "C" UINT g_cfJobIDList;
extern "C" UINT g_cfShellIDList;
extern "C" UINT g_cfPreferredDropEffect;
//____________________________________________________________________________
//
// Class: CObjFormats
//
// Purpose: Impements IEnumFORMATETC for job objects.
//____________________________________________________________________________
class CObjFormats : public IEnumFORMATETC
{
friend HRESULT JFGetObjFormats(UINT cfmt, FORMATETC *afmt, LPVOID *ppvObj);
public:
~CObjFormats() { if (m_aFmt) delete [] m_aFmt; }
// IUnknown methods
DECLARE_STANDARD_IUNKNOWN;
// IEnumFORMATETC methods
STDMETHODIMP Next(ULONG celt, FORMATETC *rgelt, ULONG *pceltFethed);
STDMETHODIMP Skip(ULONG celt);
STDMETHODIMP Reset();
STDMETHODIMP Clone(IEnumFORMATETC ** ppenum);
private:
CObjFormats(UINT cfmt, FORMATETC * afmt)
: m_iFmt(0), m_cFmt(cfmt), m_aFmt(afmt), m_ulRefs(1) {}
UINT m_iFmt;
UINT m_cFmt;
FORMATETC * m_aFmt;
};
//____________________________________________________________________________
//
// Members: IUnknown methods
//____________________________________________________________________________
IMPLEMENT_STANDARD_IUNKNOWN(CObjFormats);
STDMETHODIMP
CObjFormats::QueryInterface(
REFIID riid,
LPVOID FAR* ppvObj)
{
if (IsEqualIID(IID_IUnknown, riid) ||
IsEqualIID(IID_IEnumFORMATETC, riid))
{
*ppvObj = (IUnknown*)(IEnumFORMATETC*) this;
this->AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
//____________________________________________________________________________
//
// Members: IEnumFORMATETC methods
//____________________________________________________________________________
STDMETHODIMP
CObjFormats::Next(
ULONG celt,
FORMATETC *rgelt,
ULONG *pceltFethed)
{
UINT cfetch = 0;
HRESULT hr = S_FALSE;
if (m_iFmt < m_cFmt)
{
cfetch = m_cFmt - m_iFmt;
if (cfetch >= celt)
{
cfetch = celt;
hr = S_OK;
}
CopyMemory(rgelt, &m_aFmt[m_iFmt], cfetch * sizeof(FORMATETC));
m_iFmt += cfetch;
}
if (pceltFethed)
{
*pceltFethed = cfetch;
}
return hr;
}
STDMETHODIMP
CObjFormats::Skip(
ULONG celt)
{
m_iFmt += celt;
if (m_iFmt > m_cFmt)
{
m_iFmt = m_cFmt;
return S_FALSE;
}
return S_OK;
}
STDMETHODIMP
CObjFormats::Reset()
{
m_iFmt = 0;
return S_OK;
}
STDMETHODIMP
CObjFormats::Clone(
IEnumFORMATETC ** ppenum)
{
return E_NOTIMPL;
}
//____________________________________________________________________________
//
// Function: Function to obtain the IEnumFORMATETC interface for jobs.
//____________________________________________________________________________
HRESULT
JFGetObjFormats(
UINT cfmt,
FORMATETC * afmt,
LPVOID * ppvObj)
{
TRACE_FUNCTION(JFGetObjFormats);
FORMATETC * pFmt = new FORMATETC[cfmt];
if (pFmt == NULL)
{
CHECK_HRESULT(E_OUTOFMEMORY);
return E_OUTOFMEMORY;
}
CopyMemory(pFmt, afmt, cfmt * sizeof(FORMATETC));
CObjFormats * pObjFormats = new CObjFormats(cfmt, pFmt);
if (pObjFormats == NULL)
{
delete [] pFmt;
CHECK_HRESULT(E_OUTOFMEMORY);
return E_OUTOFMEMORY;
}
HRESULT hr = pObjFormats->QueryInterface(IID_IEnumFORMATETC, ppvObj);
pObjFormats->Release();
DEBUG_OUT((DEB_TRACE, "RETURNING CObjFormats<%x, %d>\n",
pObjFormats, pObjFormats->m_ulRefs));
return hr;
}
//____________________________________________________________________________
//____________________________________________________________________________
//________________ _______________________________________
//________________ class CJobObject _______________________________________
//________________ _______________________________________
//____________________________________________________________________________
//____________________________________________________________________________
class CJobObject : public IDataObject
{
public:
CJobObject(
LPCTSTR pszFolderPath,
LPITEMIDLIST pidlFolder,
UINT cidl,
LPITEMIDLIST *apidl,
BOOL fCut);
~CJobObject()
{
ILA_Free(m_cidl, m_apidl);
ILFree(m_pidlFolder);
DEBUG_ASSERT(m_ulRefs == 0);
}
// Iunknown methods
DECLARE_STANDARD_IUNKNOWN;
// IDataObject
STDMETHODIMP GetData(FORMATETC *pformatetcIn, STGMEDIUM *pmedium);
STDMETHODIMP GetDataHere(FORMATETC *pformatetc, STGMEDIUM *pmedium);
STDMETHODIMP QueryGetData(FORMATETC *pformatetc);
STDMETHODIMP GetCanonicalFormatEtc(FORMATETC *pformatectIn,
FORMATETC *pformatetcOut);
STDMETHODIMP SetData(FORMATETC *pformatetc, STGMEDIUM *pmedium,
BOOL fRelease);
STDMETHODIMP EnumFormatEtc(DWORD dwDirection,
IEnumFORMATETC **ppenumFormatEtc);
STDMETHODIMP DAdvise(FORMATETC *pformatetc, DWORD advf,
IAdviseSink *pAdvSink, DWORD *pdwConnection);
STDMETHODIMP DUnadvise(DWORD dwConnection);
STDMETHODIMP EnumDAdvise(IEnumSTATDATA **ppenumAdvise);
private:
LPCTSTR m_pszFolderPath;
LPITEMIDLIST m_pidlFolder;
UINT m_cidl;
LPITEMIDLIST * m_apidl;
BOOL m_fCut; // this is for a cut operation
};
inline
CJobObject::CJobObject(
LPCTSTR pszFolderPath,
LPITEMIDLIST pidlFolder,
UINT cidl,
LPITEMIDLIST *apidl,
BOOL fCut):
m_cidl(cidl),
m_pszFolderPath(pszFolderPath),
m_pidlFolder(pidlFolder),
m_apidl(apidl),
m_ulRefs(1),
m_fCut(fCut)
{
}
//____________________________________________________________________________
//
// Members: IUnknown methods
//____________________________________________________________________________
IMPLEMENT_STANDARD_IUNKNOWN(CJobObject);
STDMETHODIMP
CJobObject::QueryInterface(
REFIID riid,
LPVOID FAR* ppvObj)
{
if (IsEqualIID(IID_IUnknown, riid) ||
IsEqualIID(IID_IDataObject, riid))
{
*ppvObj = (IUnknown*)((IDataObject*)this);
this->AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
//____________________________________________________________________________
//
// Function: DbgPrintFmt
//
// Synopsis: Function to print out the format name.
//____________________________________________________________________________
#if DBG==1
void
DbgPrintFmt(
UINT format)
{
#undef DEB_USEREX
#define DEB_USEREX DEB_USER15
TCHAR szFmtName[550];
int cchFmtName = 550;
if (format == g_cfJobIDList)
{
DEBUG_OUT((DEB_USEREX, "\t\t<Format=Job IDList Array>\n"));
return;
}
else if (format == g_cfPreferredDropEffect)
{
DEBUG_OUT((DEB_USEREX, "\t\t<Format=Preferred DropEffect>\n"));
return;
}
int iRet = GetClipboardFormatName(format, szFmtName, cchFmtName);
if (iRet == 0)
if (GetLastError() == 0)
DEBUG_OUT((DEB_USEREX, "\t\t<Predefined format=%d>\n", format));
else
DEBUG_OUT((DEB_USEREX, "\t\t<Unknown Format=%d>\n", format));
else
DEBUG_OUT((DEB_USEREX, "\t\t<Format=%ws>\n", szFmtName));
}
#define DBG_PRINT_FMT(fmt) DbgPrintFmt(fmt)
#else
#define DBG_PRINT_FMT(fmt)
#endif
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::GetData
//
// History: 1/31/1996 RaviR Created
//____________________________________________________________________________
STDMETHODIMP
CJobObject::GetData(
FORMATETC *pfmt,
STGMEDIUM *pmedium)
{
TRACE(CJobObject, GetData);
DBG_PRINT_FMT(pfmt->cfFormat);
Win4Assert(g_cfJobIDList != 0);
if (pfmt->tymed & TYMED_HGLOBAL)
{
if (pfmt->cfFormat == CF_HDROP)
{
pmedium->hGlobal = HDROPFromJobIDList(m_pszFolderPath,
m_cidl, (PJOBID *)m_apidl);
}
else if (pfmt->cfFormat == g_cfShellIDList)
{
pmedium->hGlobal = CreateIDListArray(m_pidlFolder,
m_cidl,
(PJOBID *)m_apidl);
}
else if (pfmt->cfFormat == g_cfJobIDList)
{
// Note Ole32's GetHGlobalFromILockBytes uses this
pmedium->hGlobal = HJOBIDA_Create(m_cidl, (PJOBID *)m_apidl);
}
else if (pfmt->cfFormat == g_cfPreferredDropEffect)
{
DWORD *pdw = (DWORD *)GlobalAlloc(GPTR, sizeof(DWORD));
if (pdw)
{
*pdw = m_fCut ? DROPEFFECT_MOVE : DROPEFFECT_COPY;
pmedium->hGlobal = (HGLOBAL)pdw;
}
}
else
{
pmedium->tymed = TYMED_NULL;
pmedium->hGlobal = NULL;
pmedium->pUnkForRelease = NULL;
return DATA_E_FORMATETC;
}
if (pmedium->hGlobal != NULL)
{
pmedium->tymed = TYMED_HGLOBAL;
pmedium->pUnkForRelease = NULL;
return S_OK;
}
else
{
return E_OUTOFMEMORY;
}
}
return DV_E_TYMED;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::GetDataHere
//____________________________________________________________________________
STDMETHODIMP
CJobObject::GetDataHere(
FORMATETC *pfmt,
STGMEDIUM *pmedium)
{
TRACE(CJobObject, GetDataHere);
DBG_PRINT_FMT(pfmt->cfFormat);
return E_NOTIMPL;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::QueryGetData
//
// History: 1/31/1996 RaviR Created
//____________________________________________________________________________
STDMETHODIMP
CJobObject::QueryGetData(
FORMATETC *pfmt)
{
TRACE(CJobObject, QueryGetData);
DBG_PRINT_FMT(pfmt->cfFormat);
//
// Check the aspects we support.
//
if (!(DVASPECT_CONTENT & pfmt->dwAspect))
{
return DATA_E_FORMATETC;
}
Win4Assert(g_cfJobIDList != 0);
if (pfmt->cfFormat == CF_HDROP ||
pfmt->cfFormat == g_cfJobIDList ||
pfmt->cfFormat == g_cfShellIDList ||
pfmt->cfFormat == g_cfPreferredDropEffect)
{
return S_OK;
}
return S_FALSE;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::GetCanonicalFormatEtc
//____________________________________________________________________________
STDMETHODIMP
CJobObject::GetCanonicalFormatEtc(
FORMATETC *pfmtIn,
FORMATETC *pfmtOut)
{
TRACE(CJobObject, GetCanonicalFormatEtc);
*pfmtOut = *pfmtIn;
pfmtOut->ptd = NULL;
return DATA_S_SAMEFORMATETC;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::SetData
//____________________________________________________________________________
STDMETHODIMP
CJobObject::SetData(
FORMATETC *pfmt,
STGMEDIUM *pmedium,
BOOL fRelease)
{
TRACE(CJobObject, SetData);
DBG_PRINT_FMT(pfmt->cfFormat);
return E_NOTIMPL;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::EnumFormatEtc
//
// History: 1/31/1996 RaviR Created
//____________________________________________________________________________
STDMETHODIMP
CJobObject::EnumFormatEtc(
DWORD dwDirection,
IEnumFORMATETC **ppenumFormatEtc)
{
TRACE(CJobObject, EnumFormatEtc);
if (dwDirection == DATADIR_SET)
{
return E_FAIL;
}
FORMATETC fmte[] = {
{CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
{(CLIPFORMAT)g_cfJobIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
{(CLIPFORMAT)g_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
{(CLIPFORMAT)g_cfPreferredDropEffect, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL},
};
HRESULT hr = JFGetObjFormats(ARRAYLEN(fmte), fmte, (void**)ppenumFormatEtc);
return hr;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::DAdvise
//____________________________________________________________________________
STDMETHODIMP
CJobObject::DAdvise(
FORMATETC *pformatetc,
DWORD advf,
IAdviseSink *pAdvSink,
DWORD *pdwConnection)
{
TRACE(CJobObject, DAdvise);
return E_NOTIMPL;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::DUnadvise
//____________________________________________________________________________
STDMETHODIMP
CJobObject::DUnadvise(
DWORD dwConnection)
{
TRACE(CJobObject, DUnadvise);
return E_NOTIMPL;
}
//____________________________________________________________________________
//
// Member: CJobObject::IDataObject::EnumDAdvise
//____________________________________________________________________________
STDMETHODIMP
CJobObject::EnumDAdvise(
IEnumSTATDATA **ppenumAdvise)
{
TRACE(CJobObject, EnumDAdvise);
return E_NOTIMPL;
}
//+--------------------------------------------------------------------------
//
// Function: JFGetDataObject
//
// Synopsis: Function to create a data object for jobs in the job folder.
//
// Arguments: [pszFolderPath] - full path to tasks folder
// [pidlFolder] - pidl to that folder, supplied by shell's
// call to IPersistFolder::Initialize.
// [cidl] - number elements in array
// [apidl] - array of idls, each naming a .job object
// [fCut] - TRUE if this is created for cut operation
// [ppvObj] - filled with pointer to new data object
//
// Returns: HRESULT
//
// Modifies: *[ppvObj]
//
// History: 01/31/1996 RaviR Created
// 05-30-1997 DavidMun Pass copy of [pidlFolder]
//
//---------------------------------------------------------------------------
HRESULT
JFGetDataObject(
LPCTSTR pszFolderPath,
LPCITEMIDLIST pidlFolder,
UINT cidl,
LPCITEMIDLIST * apidl,
BOOL fCut,
LPVOID * ppvObj)
{
TRACE_FUNCTION(JFGetDataObject);
LPITEMIDLIST * apidlTemp = ILA_Clone(cidl, apidl);
if (NULL == apidlTemp)
{
CHECK_HRESULT(E_OUTOFMEMORY);
return E_OUTOFMEMORY;
}
LPITEMIDLIST pidlFolderCopy = ILClone(pidlFolder);
if (!pidlFolderCopy)
{
ILA_Free(cidl, apidlTemp);
CHECK_HRESULT(E_OUTOFMEMORY);
return E_OUTOFMEMORY;
}
CJobObject * pJobObjects = new CJobObject(pszFolderPath,
pidlFolderCopy,
cidl,
apidlTemp,
fCut);
if (pJobObjects == NULL)
{
ILA_Free(cidl, apidlTemp);
CHECK_HRESULT(E_OUTOFMEMORY);
return E_OUTOFMEMORY;
}
HRESULT hr = pJobObjects->QueryInterface(IID_IDataObject, ppvObj);
pJobObjects->Release();
return hr;
}