Leaked source code of windows server 2003
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.

403 lines
14 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Printing.h
  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. #if !defined(__INCLUDED___HCP___PRINTING_H___)
  12. #define __INCLUDED___HCP___PRINTING_H___
  13. #include <commdlg.h>
  14. #include <shlobj.h>
  15. #include <exdisp.h>
  16. #include <exdispid.h>
  17. namespace Printing
  18. {
  19. class HostWindow :
  20. public CAxHostWindow,
  21. public IOleCommandTarget
  22. {
  23. ULONG m_cRef;
  24. MPC::wstring m_szPrintFileName;
  25. bool m_fMultiTopic;
  26. bool m_fShowPrintDlg;
  27. LPDEVMODEW m_pDevMode;
  28. CComBSTR m_bstrPrinterName;
  29. bool m_fAborted;
  30. HANDLE m_hEvent;
  31. public:
  32. HostWindow();
  33. virtual ~HostWindow();
  34. DECLARE_GET_CONTROLLING_UNKNOWN()
  35. DECLARE_PROTECT_FINAL_CONSTRUCT()
  36. BEGIN_COM_MAP(HostWindow)
  37. COM_INTERFACE_ENTRY(IOleCommandTarget)
  38. COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow)
  39. END_COM_MAP()
  40. //
  41. // IOleCommandTarget
  42. //
  43. STDMETHODIMP QueryStatus( /*[in] */ const GUID* pguidCmdGroup ,
  44. /*[in] */ ULONG cCmds ,
  45. /*[in/out]*/ OLECMD *prgCmds ,
  46. /*[in/out]*/ OLECMDTEXT *pCmdText );
  47. STDMETHODIMP Exec( /*[in] */ const GUID* pguidCmdGroup ,
  48. /*[in] */ DWORD nCmdID ,
  49. /*[in] */ DWORD nCmdExecOpt ,
  50. /*[in] */ VARIANTARG* pvaIn ,
  51. /*[out]*/ VARIANTARG* pvaOut );
  52. void SetMultiTopic ( /*[in]*/ bool fMulti );
  53. void SetPrintFileName( /*[in]*/ LPCWSTR szPrintFileName );
  54. void SetAbortEvent ( /*[in]*/ HANDLE hEvent );
  55. bool GetAbortState ( );
  56. BSTR GetPrinterName ( );
  57. };
  58. template <typename TDerived, typename TWindow = CAxWindow> class WindowImplT : public CWindowImplBaseT< TWindow >
  59. {
  60. public:
  61. typedef WindowImplT<TWindow> thisClass;
  62. BEGIN_MSG_MAP(thisClass)
  63. MESSAGE_HANDLER(WM_CREATE,OnCreate)
  64. MESSAGE_HANDLER(WM_NCDESTROY,OnNCDestroy)
  65. END_MSG_MAP()
  66. DECLARE_WND_SUPERCLASS(_T("AtlPchAxWin"), CAxWindow::GetWndClassName())
  67. virtual HRESULT PrivateCreateControlEx( LPCOLESTR lpszName ,
  68. HWND hWnd ,
  69. IStream* pStream ,
  70. IUnknown* *ppUnkContainer ,
  71. IUnknown* *ppUnkControl ,
  72. REFIID iidSink ,
  73. IUnknown* punkSink )
  74. {
  75. return AtlAxCreateControlEx( lpszName ,
  76. hWnd ,
  77. pStream ,
  78. ppUnkContainer ,
  79. ppUnkControl ,
  80. iidSink ,
  81. punkSink );
  82. }
  83. HWND Create( HWND hWndParent,
  84. RECT& rcPos,
  85. LPCTSTR szWindowName = NULL ,
  86. DWORD dwStyle = 0 ,
  87. DWORD dwExStyle = 0 ,
  88. UINT nID = 0 ,
  89. LPVOID lpCreateParam = NULL )
  90. {
  91. if(GetWndClassInfo().m_lpszOrigName == NULL)
  92. {
  93. GetWndClassInfo().m_lpszOrigName = GetWndClassName();
  94. }
  95. ATOM atom = GetWndClassInfo().Register( &m_pfnSuperWindowProc );
  96. dwStyle = GetWndStyle ( dwStyle );
  97. dwExStyle = GetWndExStyle( dwExStyle );
  98. return CWindowImplBaseT<TWindow>::Create( hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, atom, lpCreateParam );
  99. }
  100. ////////////////////////////////////////////////////////////////////////////////
  101. LRESULT OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  102. {
  103. USES_CONVERSION;
  104. CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
  105. int nLen = ::GetWindowTextLength( m_hWnd );
  106. LPTSTR lpstrName = (LPTSTR)_alloca( (nLen + 1) * sizeof(TCHAR) );
  107. IAxWinHostWindow* pAxWindow = NULL;
  108. int nCreateSize = 0;
  109. CComPtr<IUnknown> spUnk;
  110. CComPtr<IStream> spStream;
  111. ::GetWindowText( m_hWnd, lpstrName, nLen + 1 );
  112. ::SetWindowText( m_hWnd, _T("") );
  113. if(lpCreate && lpCreate->lpCreateParams)
  114. {
  115. nCreateSize = *((WORD*)lpCreate->lpCreateParams);
  116. }
  117. //
  118. // Get the data for the initialization stream.
  119. //
  120. if(nCreateSize)
  121. {
  122. HGLOBAL h = GlobalAlloc( GHND, nCreateSize );
  123. if(h)
  124. {
  125. BYTE* pBytes = (BYTE*)GlobalLock( h );
  126. BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
  127. //Align to DWORD
  128. //pSource += (((~((DWORD)pSource)) + 1) & 3);
  129. memcpy( pBytes, pSource, nCreateSize );
  130. ::GlobalUnlock( h );
  131. ::CreateStreamOnHGlobal( h, TRUE, &spStream );
  132. }
  133. }
  134. //
  135. // call the real creation routine here...
  136. //
  137. HRESULT hRet = PrivateCreateControlEx( T2COLE( lpstrName ), m_hWnd, spStream, &spUnk, NULL, IID_NULL, NULL );
  138. if(FAILED(hRet)) return -1; // abort window creation
  139. hRet = spUnk->QueryInterface( IID_IAxWinHostWindow, (void**)&pAxWindow );
  140. if(FAILED(hRet)) return -1; // abort window creation
  141. ::SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)pAxWindow );
  142. //
  143. // check for control parent style if control has a window
  144. //
  145. {
  146. HWND hWndChild = ::GetWindow( m_hWnd, GW_CHILD );
  147. if(hWndChild != NULL)
  148. {
  149. if(::GetWindowLong( hWndChild, GWL_EXSTYLE ) & WS_EX_CONTROLPARENT)
  150. {
  151. DWORD dwExStyle = ::GetWindowLong( m_hWnd, GWL_EXSTYLE );
  152. dwExStyle |= WS_EX_CONTROLPARENT;
  153. ::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle );
  154. }
  155. }
  156. }
  157. bHandled = TRUE;
  158. return 0L;
  159. }
  160. LRESULT OnNCDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  161. {
  162. IAxWinHostWindow* pAxWindow = (IAxWinHostWindow*)::GetWindowLongPtr( m_hWnd, GWLP_USERDATA );
  163. if(pAxWindow != NULL) pAxWindow->Release();
  164. m_hWnd = NULL;
  165. bHandled = TRUE;
  166. return 0L;
  167. }
  168. };
  169. ////////////////////////////////////////////////////////////////////////////////
  170. class WindowHandle : public WindowImplT<WindowHandle>
  171. {
  172. public:
  173. typedef WindowImplT<WindowHandle> baseClass;
  174. typedef CComObject<HostWindow> theSite;
  175. private:
  176. theSite* m_pSiteObject;
  177. bool m_fMultiTopic;
  178. MPC::wstring m_szPrintFileName;
  179. HANDLE m_hEvent;
  180. public:
  181. WindowHandle();
  182. ~WindowHandle();
  183. BEGIN_MSG_MAP(WindowHandle)
  184. CHAIN_MSG_MAP(baseClass)
  185. END_MSG_MAP()
  186. virtual HRESULT PrivateCreateControlEx( LPCOLESTR lpszName ,
  187. HWND hWnd ,
  188. IStream* pStream ,
  189. IUnknown* *ppUnkContainer ,
  190. IUnknown* *ppUnkControl ,
  191. REFIID iidSink ,
  192. IUnknown* punkSink );
  193. void SetMultiTopic ( /*[in]*/ bool fMulti );
  194. void SetPrintFileName( /*[in]*/ LPCWSTR szPrintFileName );
  195. void SetAbortEvent ( /*[in]*/ HANDLE hEvent );
  196. bool GetAbortState ( );
  197. BSTR GetPrinterName ( );
  198. };
  199. ////////////////////////////////////////////////////////////////////////////////
  200. class ATL_NO_VTABLE CDispatchSink :
  201. public CComObjectRootEx<CComSingleThreadModel>,
  202. public IDispatch
  203. {
  204. HANDLE m_hEvent;
  205. CComBSTR m_URL;
  206. public:
  207. BEGIN_COM_MAP(CDispatchSink)
  208. COM_INTERFACE_ENTRY(IDispatch)
  209. COM_INTERFACE_ENTRY_IID(DIID_DWebBrowserEvents2, IDispatch)
  210. END_COM_MAP()
  211. CDispatchSink();
  212. void SetNotificationEvent( /*[in]*/ HANDLE hEvent );
  213. BSTR GetCurrentURL ( );
  214. STDMETHOD(GetTypeInfoCount)(UINT* pctinfo);
  215. STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
  216. STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid);
  217. STDMETHOD(Invoke)( DISPID dispidMember ,
  218. REFIID riid ,
  219. LCID lcid ,
  220. WORD wFlags ,
  221. DISPPARAMS* pdispparams ,
  222. VARIANT* pvarResult ,
  223. EXCEPINFO* pexcepinfo ,
  224. UINT* puArgErr );
  225. };
  226. ////////////////////////////////////////////////////////////////////////////////
  227. class Print
  228. {
  229. public:
  230. class Notification
  231. {
  232. public:
  233. virtual HRESULT Progress( /*[in]*/ LPCWSTR szURL, /*[in]*/ int iDone, /*[in]*/ int iTotal ) = 0;
  234. };
  235. private:
  236. Notification* m_pCallback; // Client for notification.
  237. //
  238. MPC::WStringList m_lstURLs; // list of urls to be printed
  239. //
  240. HWND m_hwnd; // parent window.
  241. WindowHandle m_wnd; // window for hosting Trident
  242. CComPtr<IWebBrowser2> m_spWebBrowser2; // pointer for Navigate call
  243. //
  244. CComPtr<CDispatchSink> m_spObjDisp; // our sink object for Trident events
  245. HANDLE m_eventDocComplete; // this event is for notifying our code when the webbrowser is done loading a topic
  246. HANDLE m_eventAbortPrint; // this event is for notifying our code when the webbrowser is done printing a topic
  247. //
  248. CComPtr<IUnknown> m_spUnkControl; // IUnknown of our control
  249. DWORD m_dwCookie; // cookie for our Unadvise call
  250. CComPtr<IOleCommandTarget> m_spOleCmdTarg; // pointer we need to tell Trident to print
  251. MPC::wstring m_szPrintDir; // directory to print to
  252. MPC::wstring m_szPrintFile; // file to print to
  253. //
  254. CComPtr<IStream> m_streamPrintData; // pointer to raw printer data
  255. HRESULT PrintSingleURL( /*[in]*/ MPC::wstring& szUrl ); // print a single URL
  256. HRESULT HookUpEventSink(); // hook up our event sink
  257. HRESULT PreparePrintFileLoc(); // prepare our temporary print files
  258. HRESULT WaitForDocComplete(); // wait for Trident to load the page
  259. HRESULT DoPrint(); // send the print command to Trident
  260. HRESULT WaitForPrintComplete(); // wait for Trident to finish printing
  261. HRESULT UpdatePrintBuffer(); // load the print file data into our buffer
  262. HRESULT RawDataToPrinter(); // dump a raw stream of data to the printer
  263. public:
  264. Print();
  265. ~Print();
  266. HRESULT Initialize( /*[in]*/ HWND hwnd );
  267. HRESULT Terminate ( );
  268. HRESULT AddUrl( /*[in]*/ LPCWSTR szUrl );
  269. HRESULT PrintAll( /*[in]*/ Notification* pCallback );
  270. };
  271. };
  272. ////////////////////////////////////////////////////////////////////////////////
  273. class ATL_NO_VTABLE CPCHPrintEngine : // Hungarian: hcppe
  274. public MPC::Thread < CPCHPrintEngine, IPCHPrintEngine, COINIT_APARTMENTTHREADED >,
  275. public MPC::ConnectionPointImpl< CPCHPrintEngine, &DIID_DPCHPrintEngineEvents, MPC::CComSafeMultiThreadModel >,
  276. public IDispatchImpl < IPCHPrintEngine, &IID_IPCHPrintEngine, &LIBID_HelpCenterTypeLib >,
  277. public Printing::Print::Notification
  278. {
  279. Printing::Print m_engine;
  280. MPC::CComPtrThreadNeutral<IDispatch> m_sink_onProgress;
  281. MPC::CComPtrThreadNeutral<IDispatch> m_sink_onComplete;
  282. //////////////////////////////////////////////////////////////////////
  283. HRESULT Run();
  284. HRESULT CanModifyProperties();
  285. //////////////////////////////////////////////////////////////////////
  286. //
  287. // Event firing methods.
  288. //
  289. HRESULT Fire_onProgress( IPCHPrintEngine* hcppe, BSTR bstrURL, long lDone, long lTotal );
  290. HRESULT Fire_onComplete( IPCHPrintEngine* hcppe, HRESULT hrRes );
  291. //
  292. // Callbacks
  293. //
  294. HRESULT Progress( /*[in]*/ LPCWSTR szURL, /*[in]*/ int iDone, /*[in]*/ int iTotal );
  295. //////////////////////////////////////////////////////////////////////
  296. public:
  297. BEGIN_COM_MAP(CPCHPrintEngine)
  298. COM_INTERFACE_ENTRY(IDispatch)
  299. COM_INTERFACE_ENTRY(IPCHPrintEngine)
  300. COM_INTERFACE_ENTRY(IConnectionPointContainer)
  301. END_COM_MAP()
  302. CPCHPrintEngine();
  303. void FinalRelease();
  304. public:
  305. // IPCHPrintEngine
  306. STDMETHOD(put_onProgress)( /*[in] */ IDispatch* function );
  307. STDMETHOD(put_onComplete)( /*[in] */ IDispatch* function );
  308. STDMETHOD(AddTopic)( /*[in]*/ BSTR bstrURL );
  309. STDMETHOD(Start)();
  310. STDMETHOD(Abort)();
  311. };
  312. #endif // !defined(__INCLUDED___HCP___PRINTING_H___)