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.
 
 
 
 
 
 

330 lines
9.5 KiB

/*****************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 2000
*
* TITLE: drop.cpp
*
* VERSION: 1.0, stolen from netplwiz
*
* AUTHOR: RickTu
*
* DATE: 10/12/00
*
* DESCRIPTION: IDropTarget implementation
*
*****************************************************************************/
#include "precomp.h"
#pragma hdrstop
/*****************************************************************************
CPrintDropTarget
class definition
*****************************************************************************/
class CPrintDropTarget : public IDropTarget, IPersistFile
{
public:
CPrintDropTarget(CLSID clsidWizard);
~CPrintDropTarget();
// IUnknown
STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
STDMETHOD_(ULONG,AddRef)(void);
STDMETHOD_(ULONG,Release)(void);
// IPersist
STDMETHODIMP GetClassID(CLSID *pClassID)
{ *pClassID = _clsidWizard; return S_OK; };
// IPersistFile
STDMETHODIMP IsDirty(void)
{ return S_FALSE; };
STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode)
{ return S_OK; };
STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember)
{ return S_OK; };
STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName)
{ return S_OK; };
STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName)
{ *ppszFileName = NULL; return S_OK; };
// IDropTarget
STDMETHODIMP DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{ *pdwEffect = DROPEFFECT_COPY; return S_OK; };
STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{ *pdwEffect = DROPEFFECT_COPY; return S_OK; };
STDMETHODIMP DragLeave(void)
{ return S_OK; };
STDMETHODIMP Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
private:
static DWORD s_PrintPhotosThreadProc(void *pv);
void _PrintPhotos(IDataObject *pdo);
CLSID _clsidWizard; // instance of the wizard being invoked (publish vs. ipp)
LONG _cRef;
CComPtr<IPrintPhotosWizardSetInfo> _ppwsi; // print photos set wizard info object
};
#define WIZDLG(dlg_id, name_id, title_id, dlgproc, dwFlags) \
{ MAKEINTRESOURCE(##dlg_id##), dlgproc, MAKEINTRESOURCE(##name_id##), MAKEINTRESOURCE(##title_id##), dwFlags }
/*****************************************************************************
CPrintDropTarget
Constructor/Destructor
*****************************************************************************/
CPrintDropTarget::CPrintDropTarget(CLSID clsidWizard) :
_clsidWizard(clsidWizard),
_cRef(1)
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP,TEXT("CPrintDropTarget::CPrintDropTarget( this == 0x%x )"),this));
DllAddRef();
}
CPrintDropTarget::~CPrintDropTarget()
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP,TEXT("CPrintDropTarget::~CPrintDropTarget( this == 0x%x )"),this));
DllRelease();
}
/*****************************************************************************
CPrintDropTarget
IUnknown methods
*****************************************************************************/
ULONG CPrintDropTarget::AddRef()
{
ULONG ul = InterlockedIncrement(&_cRef);
WIA_PUSH_FUNCTION_MASK((TRACE_REF_COUNTS,TEXT("CPrintDropTarget::AddRef( new count is %d )"), ul));
return ul;
}
ULONG CPrintDropTarget::Release()
{
ULONG ul = InterlockedDecrement(&_cRef);
WIA_PUSH_FUNCTION_MASK((TRACE_REF_COUNTS,TEXT("CPrintDropTarget::Release( new count is %d )"), ul));
if (ul)
return ul;
WIA_TRACE((TEXT("deleting CPrintDropTarget( this == 0x%x ) object"),this));
delete this;
return 0;
}
HRESULT CPrintDropTarget::QueryInterface(REFIID riid, void **ppv)
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP,TEXT("CPrintDropTarget::QueryInterface()")));
static const QITAB qit[] =
{
QITABENT(CPrintDropTarget, IDropTarget), // IID_IDropTarget
QITABENT(CPrintDropTarget, IPersistFile), // IID_IPersistFile
{0, 0 },
};
HRESULT hr = QISearch(this, qit, riid, ppv);
WIA_RETURN_HR(hr);
}
/*****************************************************************************
CPrintDropTarget::_PrintPhotos
Creates the wizard.
*****************************************************************************/
void CPrintDropTarget::_PrintPhotos(IDataObject *pdo)
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintDropTarget::_PrintPhotos")));
CComPtr<IUnknown> pUnk;
HRESULT hr = CPrintPhotosWizard_CreateInstance(NULL, (IUnknown **)&pUnk, NULL);
WIA_CHECK_HR(hr,"CPrintPhotosWizard_CreateInstance()");
if (SUCCEEDED(hr) && pUnk)
{
hr = pUnk->QueryInterface( IID_IPrintPhotosWizardSetInfo, (LPVOID *)&_ppwsi );
WIA_CHECK_HR(hr, "pUnk->QI( IID_IPrintPhotosWizardSetInfo )");
}
// initialize the wizard with the DataObject that expressess the
// files that we are going to copy to.
if (SUCCEEDED(hr) && _ppwsi)
{
hr = _ppwsi->SetFileListDataObject( pdo );
WIA_CHECK_HR(hr,"_ppwsi->SetFileListDataObject()");
if (SUCCEEDED(hr))
{
hr = _ppwsi->RunWizard();
WIA_CHECK_HR(hr,"_ppwsi->RunWizard()")
}
}
else
{
WIA_ERROR((TEXT("not calling into wizard, hr = 0x%x, _ppwsi = 0x%x"),hr,_ppwsi));
}
}
typedef struct
{
CLSID clsidWizard; // which wizard is being invoked
IStream *pStream; // stream for doing marshalling
CPrintDropTarget *that; // copy of object pointer
} PRINTWIZDROPINFO;
/*****************************************************************************
CPrintDropTarget::s_PrintPhotosThreadProc
Thread to handle creating & running the wizard (in order to free up
caller to ::Drop).
*****************************************************************************/
DWORD CPrintDropTarget::s_PrintPhotosThreadProc(void *pv)
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintDropTarget::s_PrintPhotosThreadProc")));
PRINTWIZDROPINFO *ppwdi = (PRINTWIZDROPINFO*)pv;
CPrintDropTarget * that = (ppwdi) ? (ppwdi->that):NULL;
if (ppwdi)
{
WIA_PRINTGUID((ppwdi->clsidWizard,TEXT("ppwdi->_clsid =")));
CComPtr<IDataObject> pdo;
HRESULT hr = CoGetInterfaceAndReleaseStream(ppwdi->pStream, IID_PPV_ARG(IDataObject, &pdo));
WIA_CHECK_HR(hr,"CoGetInterfaceAndReleaseStream()");
if (SUCCEEDED(hr) && pdo)
{
that->_PrintPhotos(pdo);
}
delete [] ppwdi;
}
if (that)
{
that->Release();
}
return 0;
}
/*****************************************************************************
CPrintDropTarget::Drop
Handle the drop operation, as the printing wizard can take a long time we
marshall the IDataObject and then create a worker thread which can
handle showing the wizard.
*****************************************************************************/
STDMETHODIMP CPrintDropTarget::Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintDropTarget::Drop")));
HRESULT hr = E_OUTOFMEMORY;
// create an instance of the wizard on another thread, package up any parameters
// into a structure for the thread to handle (eg. the drop target)
PRINTWIZDROPINFO *ppwdi = (PRINTWIZDROPINFO*) new BYTE[sizeof(PRINTWIZDROPINFO)];
if (ppwdi)
{
ppwdi->clsidWizard = _clsidWizard;
ppwdi->that = this;
hr = CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pdtobj, &ppwdi->pStream);
WIA_CHECK_HR(hr,"CoMarshalInterThreadInterfaceInStream()");
if (SUCCEEDED(hr))
{
//
// AddRef this object so it stays around for the length of the
// thread. The thread will Release() the object, unless there
// is an error creating it in which case we need to release it
// here...
AddRef();
if (!SHCreateThread(s_PrintPhotosThreadProc, ppwdi, CTF_COINIT | CTF_FREELIBANDEXIT, NULL))
{
WIA_ERROR((TEXT("SHCreateThread failed! Cleaning up.")));
hr = E_FAIL;
ppwdi->pStream->Release();
Release();
}
}
if (FAILED(hr))
delete [] ppwdi;
}
WIA_RETURN_HR(hr);
}
/*****************************************************************************
CPrintPhotosDropTarget_CreateInstance
Create an instance of the CPrintDropTarget specifically configured
as the photo printing wizard.
*****************************************************************************/
STDAPI CPrintPhotosDropTarget_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
{
WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintPhotosDropTarget_CreateInstance")));
HRESULT hr = E_OUTOFMEMORY;
CPrintDropTarget *pDrop = new CPrintDropTarget(*poi->pclsid);
if (!pDrop)
{
*ppunk = NULL; // incase of failure
WIA_RETURN_HR(hr);
}
hr = pDrop->QueryInterface(IID_PPV_ARG(IUnknown, ppunk));
pDrop->Release(); // we do this release because the new of CPrintPhotosDropTarget
// set the ref count to 1, doing the QI bumps it up to 2,
// and we want to leave this function with the ref count
// at zero...
WIA_RETURN_HR(hr);
}