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.

396 lines
11 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. PrintHost.cpp
  5. Abstract:
  6. Trident control hosting code for multi-topic printing.
  7. Revision History:
  8. Davide Massarenti (Dmassare) 05/07/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. ////////////////////////////////////////////////////////////////////////////////
  13. static CComBSTR l_bstrPrintStruct ( L"printStruct" );
  14. static CComBSTR l_bstrPrintToFileOk ( L"printToFileOk" );
  15. static CComBSTR l_bstrPrintToFileName( L"printToFileName" );
  16. ////////////////////////////////////////////////////////////////////////////////
  17. Printing::HostWindow::HostWindow()
  18. {
  19. m_cRef = 0; // ULONG m_cRef;
  20. //
  21. // MPC::wstring m_szPrintFileName;
  22. m_fMultiTopic = false; // bool m_fMultiTopic;
  23. //
  24. m_fShowPrintDlg = true; // bool m_fShowPrintDlg;
  25. m_pDevMode = NULL; // LPDEVMODEW m_pDevMode;
  26. // CComBSTR m_bstrPrinterName;
  27. //
  28. m_fAborted = false; // bool m_fAborted;
  29. m_hEvent = NULL; // HANDLE m_hEvent;
  30. }
  31. Printing::HostWindow::~HostWindow()
  32. {
  33. if(m_pDevMode) delete m_pDevMode;
  34. }
  35. STDMETHODIMP Printing::HostWindow::QueryStatus( /*[in] */ const GUID* pguidCmdGroup ,
  36. /*[in] */ ULONG cCmds ,
  37. /*[in/out]*/ OLECMD *prgCmds ,
  38. /*[in/out]*/ OLECMDTEXT *pCmdText )
  39. {
  40. return E_NOTIMPL;
  41. }
  42. STDMETHODIMP Printing::HostWindow::Exec( /*[in] */ const GUID* pguidCmdGroup ,
  43. /*[in] */ DWORD nCmdID ,
  44. /*[in] */ DWORD nCmdExecOpt ,
  45. /*[in] */ VARIANTARG* pvaIn ,
  46. /*[out]*/ VARIANTARG* pvaOut )
  47. {
  48. HRESULT hr = E_NOTIMPL;
  49. HINSTANCE hInst = NULL;
  50. if(nCmdID == OLECMDID_SHOWPRINT)
  51. {
  52. for(;;)
  53. {
  54. LPPRINTDLGW pPrintDlg = NULL;
  55. if(m_fAborted)
  56. {
  57. hr = S_FALSE;
  58. break;
  59. }
  60. if(pvaIn == NULL || pvaIn->vt != VT_UNKNOWN) break;
  61. // Get the event object
  62. CComQIPtr<IHTMLEventObj2> spHTMLEventObj( pvaIn->punkVal ); if(!spHTMLEventObj) break;
  63. // Get a pointer to the PRINTDLG struct
  64. {
  65. CComVariant var;
  66. if(FAILED(spHTMLEventObj->getAttribute( l_bstrPrintStruct, 0, &var ))) break;
  67. if(var.vt == VT_PTR)
  68. {
  69. pPrintDlg = (LPPRINTDLGW)var.byref;
  70. }
  71. else
  72. {
  73. #ifdef _WIN64
  74. if(var.vt == VT_I8)
  75. {
  76. pPrintDlg = (LPPRINTDLGW)var.llVal;
  77. }
  78. #else
  79. if(var.vt == VT_I4)
  80. {
  81. pPrintDlg = (LPPRINTDLGW)var.lVal;
  82. }
  83. #endif
  84. }
  85. if(!pPrintDlg) break;
  86. }
  87. // do multi-topic extra stuff
  88. if(m_fMultiTopic)
  89. {
  90. // Get the printToFileOk attribute
  91. {
  92. CComVariant var;
  93. if(FAILED(spHTMLEventObj->getAttribute( l_bstrPrintToFileOk, 0, &var )) || var.vt != VT_BOOL) break;
  94. var.boolVal = VARIANT_TRUE;
  95. if(FAILED(spHTMLEventObj->setAttribute( l_bstrPrintToFileOk, var, 0 ))) break;
  96. }
  97. // Get the printToFileName attribute
  98. {
  99. CComVariant var;
  100. if(FAILED(spHTMLEventObj->getAttribute( l_bstrPrintToFileName, 0, &var )) || var.vt != VT_BSTR) break;
  101. if(FAILED(spHTMLEventObj->setAttribute( l_bstrPrintToFileName, CComVariant( m_szPrintFileName.c_str() ), 0 ))) break;
  102. }
  103. }
  104. if(m_fShowPrintDlg || m_pDevMode == NULL)
  105. {
  106. BOOL fRes;
  107. // hide the print to file option here, it could mess things up
  108. pPrintDlg->Flags |= PD_HIDEPRINTTOFILE;
  109. pPrintDlg->Flags &= ~PD_RETURNDEFAULT;
  110. fRes = PrintDlgW( pPrintDlg );
  111. if(fRes == FALSE)
  112. {
  113. hr = S_FALSE;
  114. break;
  115. }
  116. m_fShowPrintDlg = false;
  117. // get the devmode, which holds the device name
  118. LPDEVMODEW pdevmode = (LPDEVMODEW)::GlobalLock( pPrintDlg->hDevMode );
  119. if(pdevmode)
  120. {
  121. size_t size = pdevmode->dmSize + pdevmode->dmDriverExtra;
  122. m_pDevMode = (LPDEVMODEW)new BYTE[size];
  123. if(m_pDevMode == NULL)
  124. {
  125. hr = S_FALSE;
  126. break;
  127. }
  128. if(fRes == FALSE)
  129. {
  130. pPrintDlg->nCopies = 0;
  131. pdevmode ->dmCopies = 0;
  132. }
  133. ::CopyMemory( m_pDevMode, pdevmode, size );
  134. ::GlobalUnlock( pPrintDlg->hDevMode );
  135. }
  136. // get the printer name
  137. LPDEVNAMES pdevnames = (LPDEVNAMES)::GlobalLock( pPrintDlg->hDevNames );
  138. if(pdevnames)
  139. {
  140. m_bstrPrinterName = (WCHAR*)pdevnames + pdevnames->wDeviceOffset;
  141. ::GlobalUnlock( pPrintDlg->hDevNames );
  142. }
  143. }
  144. else
  145. {
  146. pPrintDlg->hDC = ::CreateDCW( NULL, m_bstrPrinterName, NULL, m_pDevMode );
  147. }
  148. // set the print to file flag for multi-topic
  149. if(m_fMultiTopic)
  150. {
  151. pPrintDlg->Flags |= PD_PRINTTOFILE;
  152. }
  153. // if we get here, all is ok
  154. hr = S_OK;
  155. break;
  156. }
  157. }
  158. if(hr == S_FALSE)
  159. {
  160. m_fAborted = true;
  161. if(m_hEvent)
  162. {
  163. ::SetEvent( m_hEvent );
  164. }
  165. }
  166. if(hInst) ::FreeLibrary( hInst );
  167. return hr;
  168. }
  169. void Printing::HostWindow::SetMultiTopic ( /*[in]*/ bool fMulti ) { m_fMultiTopic = fMulti ; }
  170. void Printing::HostWindow::SetPrintFileName( /*[in]*/ LPCWSTR szPrintFileName ) { m_szPrintFileName = szPrintFileName; }
  171. void Printing::HostWindow::SetAbortEvent ( /*[in]*/ HANDLE hEvent ) { m_hEvent = hEvent ; }
  172. bool Printing::HostWindow::GetAbortState ( ) { return m_fAborted; }
  173. BSTR Printing::HostWindow::GetPrinterName() { return m_bstrPrinterName; }
  174. ////////////////////////////////////////////////////////////////////////////////
  175. ////////////////////////////////////////////////////////////////////////////////
  176. Printing::WindowHandle::WindowHandle()
  177. {
  178. m_pSiteObject = NULL; // theSite* m_pSiteObject;
  179. m_fMultiTopic = false; // bool m_fMultiTopic;
  180. // MPC::wstring m_szPrintFileName;
  181. m_hEvent = NULL; // HANDLE m_hEvent;
  182. AtlAxWinInit();
  183. }
  184. Printing::WindowHandle::~WindowHandle()
  185. {
  186. if(m_pSiteObject)
  187. {
  188. m_pSiteObject->Release(); m_pSiteObject = NULL;
  189. }
  190. }
  191. HRESULT Printing::WindowHandle::PrivateCreateControlEx( LPCOLESTR lpszName ,
  192. HWND hWnd ,
  193. IStream* pStream ,
  194. IUnknown* *ppUnkContainer ,
  195. IUnknown* *ppUnkControl ,
  196. REFIID iidSink ,
  197. IUnknown* punkSink )
  198. {
  199. __HCP_FUNC_ENTRY( "Printing::WindowHandle::PrivateCreateControlEx" );
  200. HRESULT hr;
  201. CComPtr<IUnknown> spUnkContainer;
  202. CComPtr<IUnknown> spUnkControl;
  203. CComPtr<IAxWinHostWindow> pAxWindow;
  204. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pSiteObject->CreateInstance( &m_pSiteObject )); m_pSiteObject->AddRef();
  205. // set the print-specific data
  206. m_pSiteObject->SetMultiTopic ( m_fMultiTopic );
  207. m_pSiteObject->SetPrintFileName( m_szPrintFileName.c_str() );
  208. m_pSiteObject->SetAbortEvent ( m_hEvent );
  209. __MPC_EXIT_IF_METHOD_FAILS(hr, m_pSiteObject->QueryInterface( IID_IUnknown, (void**)&spUnkContainer ));
  210. __MPC_EXIT_IF_METHOD_FAILS(hr, spUnkContainer.QueryInterface( &pAxWindow ));
  211. hr = pAxWindow->CreateControlEx( CComBSTR( lpszName ), hWnd, pStream, &spUnkControl, iidSink, punkSink );
  212. __HCP_FUNC_CLEANUP;
  213. if(ppUnkContainer != NULL) *ppUnkContainer = spUnkContainer.Detach();
  214. if(ppUnkControl != NULL) *ppUnkControl = spUnkControl .Detach();
  215. __HCP_FUNC_EXIT(hr);
  216. }
  217. void Printing::WindowHandle::SetMultiTopic( /*[in]*/ bool fMulti )
  218. {
  219. m_fMultiTopic = fMulti;
  220. if(m_pSiteObject) m_pSiteObject->SetMultiTopic( fMulti );
  221. }
  222. void Printing::WindowHandle::SetPrintFileName( /*[in]*/ LPCWSTR szPrintFileName )
  223. {
  224. m_szPrintFileName = szPrintFileName;
  225. if(m_pSiteObject) m_pSiteObject->SetPrintFileName( szPrintFileName );
  226. }
  227. void Printing::WindowHandle::SetAbortEvent( /*[in]*/ HANDLE hEvent )
  228. {
  229. m_hEvent = hEvent;
  230. if(m_pSiteObject) m_pSiteObject->SetAbortEvent( hEvent );
  231. }
  232. bool Printing::WindowHandle::GetAbortState()
  233. {
  234. return m_pSiteObject ? m_pSiteObject->GetAbortState() : false;
  235. }
  236. BSTR Printing::WindowHandle::GetPrinterName()
  237. {
  238. return m_pSiteObject ? m_pSiteObject->GetPrinterName() : NULL;
  239. }
  240. ////////////////////////////////////////////////////////////////////////////////
  241. ////////////////////////////////////////////////////////////////////////////////
  242. Printing::CDispatchSink::CDispatchSink()
  243. {
  244. m_hEvent = NULL; // HANDLE m_hEvent;
  245. // CComBSTR m_URL;
  246. }
  247. void Printing::CDispatchSink::SetNotificationEvent( /*[in]*/ HANDLE hEvent )
  248. {
  249. m_hEvent = hEvent;
  250. }
  251. BSTR Printing::CDispatchSink::GetCurrentURL()
  252. {
  253. return m_URL;
  254. }
  255. ////////////////////////////////////////
  256. STDMETHODIMP Printing::CDispatchSink::GetTypeInfoCount(UINT* pctinfo)
  257. {
  258. return E_NOTIMPL;
  259. }
  260. STDMETHODIMP Printing::CDispatchSink::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
  261. {
  262. return E_NOTIMPL;
  263. }
  264. STDMETHODIMP Printing::CDispatchSink::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
  265. {
  266. return E_NOTIMPL;
  267. }
  268. STDMETHODIMP Printing::CDispatchSink::Invoke( DISPID dispidMember ,
  269. REFIID riid ,
  270. LCID lcid ,
  271. WORD wFlags ,
  272. DISPPARAMS* pdispparams ,
  273. VARIANT* pvarResult ,
  274. EXCEPINFO* pexcepinfo ,
  275. UINT* puArgErr )
  276. {
  277. HRESULT hr = S_OK;
  278. // check for NULL
  279. if(pdispparams)
  280. {
  281. switch(dispidMember)
  282. {
  283. case DISPID_DOCUMENTCOMPLETE:
  284. m_URL.Empty();
  285. if(pdispparams->rgvarg != NULL)
  286. {
  287. (void)MPC::PutBSTR( m_URL, &pdispparams->rgvarg[0] );
  288. }
  289. // signal our doc complete semaphore
  290. if(m_hEvent)
  291. {
  292. ::SetEvent( m_hEvent );
  293. }
  294. break;
  295. default:
  296. hr = DISP_E_MEMBERNOTFOUND;
  297. break;
  298. }
  299. }
  300. else
  301. {
  302. hr = DISP_E_PARAMNOTFOUND;
  303. }
  304. return hr;
  305. }