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

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: drop.cpp
  6. *
  7. * VERSION: 1.0, stolen from netplwiz
  8. *
  9. * AUTHOR: RickTu
  10. *
  11. * DATE: 10/12/00
  12. *
  13. * DESCRIPTION: IDropTarget implementation
  14. *
  15. *****************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. /*****************************************************************************
  19. CPrintDropTarget
  20. class definition
  21. *****************************************************************************/
  22. class CPrintDropTarget : public IDropTarget, IPersistFile
  23. {
  24. public:
  25. CPrintDropTarget(CLSID clsidWizard);
  26. ~CPrintDropTarget();
  27. // IUnknown
  28. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObj);
  29. STDMETHOD_(ULONG,AddRef)(void);
  30. STDMETHOD_(ULONG,Release)(void);
  31. // IPersist
  32. STDMETHODIMP GetClassID(CLSID *pClassID)
  33. { *pClassID = _clsidWizard; return S_OK; };
  34. // IPersistFile
  35. STDMETHODIMP IsDirty(void)
  36. { return S_FALSE; };
  37. STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode)
  38. { return S_OK; };
  39. STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember)
  40. { return S_OK; };
  41. STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName)
  42. { return S_OK; };
  43. STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName)
  44. { *ppszFileName = NULL; return S_OK; };
  45. // IDropTarget
  46. STDMETHODIMP DragEnter(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
  47. { *pdwEffect = DROPEFFECT_COPY; return S_OK; };
  48. STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
  49. { *pdwEffect = DROPEFFECT_COPY; return S_OK; };
  50. STDMETHODIMP DragLeave(void)
  51. { return S_OK; };
  52. STDMETHODIMP Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect);
  53. private:
  54. static DWORD s_PrintPhotosThreadProc(void *pv);
  55. void _PrintPhotos(IDataObject *pdo);
  56. CLSID _clsidWizard; // instance of the wizard being invoked (publish vs. ipp)
  57. LONG _cRef;
  58. CComPtr<IPrintPhotosWizardSetInfo> _ppwsi; // print photos set wizard info object
  59. };
  60. #define WIZDLG(dlg_id, name_id, title_id, dlgproc, dwFlags) \
  61. { MAKEINTRESOURCE(##dlg_id##), dlgproc, MAKEINTRESOURCE(##name_id##), MAKEINTRESOURCE(##title_id##), dwFlags }
  62. /*****************************************************************************
  63. CPrintDropTarget
  64. Constructor/Destructor
  65. *****************************************************************************/
  66. CPrintDropTarget::CPrintDropTarget(CLSID clsidWizard) :
  67. _clsidWizard(clsidWizard),
  68. _cRef(1)
  69. {
  70. WIA_PUSH_FUNCTION_MASK((TRACE_DROP,TEXT("CPrintDropTarget::CPrintDropTarget( this == 0x%x )"),this));
  71. DllAddRef();
  72. }
  73. CPrintDropTarget::~CPrintDropTarget()
  74. {
  75. WIA_PUSH_FUNCTION_MASK((TRACE_DROP,TEXT("CPrintDropTarget::~CPrintDropTarget( this == 0x%x )"),this));
  76. DllRelease();
  77. }
  78. /*****************************************************************************
  79. CPrintDropTarget
  80. IUnknown methods
  81. *****************************************************************************/
  82. ULONG CPrintDropTarget::AddRef()
  83. {
  84. ULONG ul = InterlockedIncrement(&_cRef);
  85. WIA_PUSH_FUNCTION_MASK((TRACE_REF_COUNTS,TEXT("CPrintDropTarget::AddRef( new count is %d )"), ul));
  86. return ul;
  87. }
  88. ULONG CPrintDropTarget::Release()
  89. {
  90. ULONG ul = InterlockedDecrement(&_cRef);
  91. WIA_PUSH_FUNCTION_MASK((TRACE_REF_COUNTS,TEXT("CPrintDropTarget::Release( new count is %d )"), ul));
  92. if (ul)
  93. return ul;
  94. WIA_TRACE((TEXT("deleting CPrintDropTarget( this == 0x%x ) object"),this));
  95. delete this;
  96. return 0;
  97. }
  98. HRESULT CPrintDropTarget::QueryInterface(REFIID riid, void **ppv)
  99. {
  100. WIA_PUSH_FUNCTION_MASK((TRACE_DROP,TEXT("CPrintDropTarget::QueryInterface()")));
  101. static const QITAB qit[] =
  102. {
  103. QITABENT(CPrintDropTarget, IDropTarget), // IID_IDropTarget
  104. QITABENT(CPrintDropTarget, IPersistFile), // IID_IPersistFile
  105. {0, 0 },
  106. };
  107. HRESULT hr = QISearch(this, qit, riid, ppv);
  108. WIA_RETURN_HR(hr);
  109. }
  110. /*****************************************************************************
  111. CPrintDropTarget::_PrintPhotos
  112. Creates the wizard.
  113. *****************************************************************************/
  114. void CPrintDropTarget::_PrintPhotos(IDataObject *pdo)
  115. {
  116. WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintDropTarget::_PrintPhotos")));
  117. CComPtr<IUnknown> pUnk;
  118. HRESULT hr = CPrintPhotosWizard_CreateInstance(NULL, (IUnknown **)&pUnk, NULL);
  119. WIA_CHECK_HR(hr,"CPrintPhotosWizard_CreateInstance()");
  120. if (SUCCEEDED(hr) && pUnk)
  121. {
  122. hr = pUnk->QueryInterface( IID_IPrintPhotosWizardSetInfo, (LPVOID *)&_ppwsi );
  123. WIA_CHECK_HR(hr, "pUnk->QI( IID_IPrintPhotosWizardSetInfo )");
  124. }
  125. // initialize the wizard with the DataObject that expressess the
  126. // files that we are going to copy to.
  127. if (SUCCEEDED(hr) && _ppwsi)
  128. {
  129. hr = _ppwsi->SetFileListDataObject( pdo );
  130. WIA_CHECK_HR(hr,"_ppwsi->SetFileListDataObject()");
  131. if (SUCCEEDED(hr))
  132. {
  133. hr = _ppwsi->RunWizard();
  134. WIA_CHECK_HR(hr,"_ppwsi->RunWizard()")
  135. }
  136. }
  137. else
  138. {
  139. WIA_ERROR((TEXT("not calling into wizard, hr = 0x%x, _ppwsi = 0x%x"),hr,_ppwsi));
  140. }
  141. }
  142. typedef struct
  143. {
  144. CLSID clsidWizard; // which wizard is being invoked
  145. IStream *pStream; // stream for doing marshalling
  146. CPrintDropTarget *that; // copy of object pointer
  147. } PRINTWIZDROPINFO;
  148. /*****************************************************************************
  149. CPrintDropTarget::s_PrintPhotosThreadProc
  150. Thread to handle creating & running the wizard (in order to free up
  151. caller to ::Drop).
  152. *****************************************************************************/
  153. DWORD CPrintDropTarget::s_PrintPhotosThreadProc(void *pv)
  154. {
  155. WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintDropTarget::s_PrintPhotosThreadProc")));
  156. PRINTWIZDROPINFO *ppwdi = (PRINTWIZDROPINFO*)pv;
  157. CPrintDropTarget * that = (ppwdi) ? (ppwdi->that):NULL;
  158. if (ppwdi)
  159. {
  160. WIA_PRINTGUID((ppwdi->clsidWizard,TEXT("ppwdi->_clsid =")));
  161. CComPtr<IDataObject> pdo;
  162. HRESULT hr = CoGetInterfaceAndReleaseStream(ppwdi->pStream, IID_PPV_ARG(IDataObject, &pdo));
  163. WIA_CHECK_HR(hr,"CoGetInterfaceAndReleaseStream()");
  164. if (SUCCEEDED(hr) && pdo)
  165. {
  166. that->_PrintPhotos(pdo);
  167. }
  168. delete [] ppwdi;
  169. }
  170. if (that)
  171. {
  172. that->Release();
  173. }
  174. return 0;
  175. }
  176. /*****************************************************************************
  177. CPrintDropTarget::Drop
  178. Handle the drop operation, as the printing wizard can take a long time we
  179. marshall the IDataObject and then create a worker thread which can
  180. handle showing the wizard.
  181. *****************************************************************************/
  182. STDMETHODIMP CPrintDropTarget::Drop(IDataObject *pdtobj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect)
  183. {
  184. WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintDropTarget::Drop")));
  185. HRESULT hr = E_OUTOFMEMORY;
  186. // create an instance of the wizard on another thread, package up any parameters
  187. // into a structure for the thread to handle (eg. the drop target)
  188. PRINTWIZDROPINFO *ppwdi = (PRINTWIZDROPINFO*) new BYTE[sizeof(PRINTWIZDROPINFO)];
  189. if (ppwdi)
  190. {
  191. ppwdi->clsidWizard = _clsidWizard;
  192. ppwdi->that = this;
  193. hr = CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pdtobj, &ppwdi->pStream);
  194. WIA_CHECK_HR(hr,"CoMarshalInterThreadInterfaceInStream()");
  195. if (SUCCEEDED(hr))
  196. {
  197. //
  198. // AddRef this object so it stays around for the length of the
  199. // thread. The thread will Release() the object, unless there
  200. // is an error creating it in which case we need to release it
  201. // here...
  202. AddRef();
  203. if (!SHCreateThread(s_PrintPhotosThreadProc, ppwdi, CTF_COINIT | CTF_FREELIBANDEXIT, NULL))
  204. {
  205. WIA_ERROR((TEXT("SHCreateThread failed! Cleaning up.")));
  206. hr = E_FAIL;
  207. ppwdi->pStream->Release();
  208. Release();
  209. }
  210. }
  211. if (FAILED(hr))
  212. delete [] ppwdi;
  213. }
  214. WIA_RETURN_HR(hr);
  215. }
  216. /*****************************************************************************
  217. CPrintPhotosDropTarget_CreateInstance
  218. Create an instance of the CPrintDropTarget specifically configured
  219. as the photo printing wizard.
  220. *****************************************************************************/
  221. STDAPI CPrintPhotosDropTarget_CreateInstance(IUnknown* pUnkOuter, IUnknown** ppunk, LPCOBJECTINFO poi)
  222. {
  223. WIA_PUSH_FUNCTION_MASK((TRACE_DROP, TEXT("CPrintPhotosDropTarget_CreateInstance")));
  224. HRESULT hr = E_OUTOFMEMORY;
  225. CPrintDropTarget *pDrop = new CPrintDropTarget(*poi->pclsid);
  226. if (!pDrop)
  227. {
  228. *ppunk = NULL; // incase of failure
  229. WIA_RETURN_HR(hr);
  230. }
  231. hr = pDrop->QueryInterface(IID_PPV_ARG(IUnknown, ppunk));
  232. pDrop->Release(); // we do this release because the new of CPrintPhotosDropTarget
  233. // set the ref count to 1, doing the QI bumps it up to 2,
  234. // and we want to leave this function with the ref count
  235. // at zero...
  236. WIA_RETURN_HR(hr);
  237. }