mirror of https://github.com/tongzx/nt5src
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
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;
|
|
}
|
|
|
|
|