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.
330 lines
9.5 KiB
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);
|
|
}
|
|
|