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.
 
 
 
 
 
 

403 lines
14 KiB

/******************************************************************************
Copyright (c) 2000 Microsoft Corporation
Module Name:
Printing.h
Abstract:
Trident control hosting code for multi-topic printing.
Revision History:
Davide Massarenti (Dmassare) 05/07/2000
created
******************************************************************************/
#if !defined(__INCLUDED___HCP___PRINTING_H___)
#define __INCLUDED___HCP___PRINTING_H___
#include <commdlg.h>
#include <shlobj.h>
#include <exdisp.h>
#include <exdispid.h>
namespace Printing
{
class HostWindow :
public CAxHostWindow,
public IOleCommandTarget
{
ULONG m_cRef;
MPC::wstring m_szPrintFileName;
bool m_fMultiTopic;
bool m_fShowPrintDlg;
LPDEVMODEW m_pDevMode;
CComBSTR m_bstrPrinterName;
bool m_fAborted;
HANDLE m_hEvent;
public:
HostWindow();
virtual ~HostWindow();
DECLARE_GET_CONTROLLING_UNKNOWN()
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(HostWindow)
COM_INTERFACE_ENTRY(IOleCommandTarget)
COM_INTERFACE_ENTRY_CHAIN(CAxHostWindow)
END_COM_MAP()
//
// IOleCommandTarget
//
STDMETHODIMP QueryStatus( /*[in] */ const GUID* pguidCmdGroup ,
/*[in] */ ULONG cCmds ,
/*[in/out]*/ OLECMD *prgCmds ,
/*[in/out]*/ OLECMDTEXT *pCmdText );
STDMETHODIMP Exec( /*[in] */ const GUID* pguidCmdGroup ,
/*[in] */ DWORD nCmdID ,
/*[in] */ DWORD nCmdExecOpt ,
/*[in] */ VARIANTARG* pvaIn ,
/*[out]*/ VARIANTARG* pvaOut );
void SetMultiTopic ( /*[in]*/ bool fMulti );
void SetPrintFileName( /*[in]*/ LPCWSTR szPrintFileName );
void SetAbortEvent ( /*[in]*/ HANDLE hEvent );
bool GetAbortState ( );
BSTR GetPrinterName ( );
};
template <typename TDerived, typename TWindow = CAxWindow> class WindowImplT : public CWindowImplBaseT< TWindow >
{
public:
typedef WindowImplT<TWindow> thisClass;
BEGIN_MSG_MAP(thisClass)
MESSAGE_HANDLER(WM_CREATE,OnCreate)
MESSAGE_HANDLER(WM_NCDESTROY,OnNCDestroy)
END_MSG_MAP()
DECLARE_WND_SUPERCLASS(_T("AtlPchAxWin"), CAxWindow::GetWndClassName())
virtual HRESULT PrivateCreateControlEx( LPCOLESTR lpszName ,
HWND hWnd ,
IStream* pStream ,
IUnknown* *ppUnkContainer ,
IUnknown* *ppUnkControl ,
REFIID iidSink ,
IUnknown* punkSink )
{
return AtlAxCreateControlEx( lpszName ,
hWnd ,
pStream ,
ppUnkContainer ,
ppUnkControl ,
iidSink ,
punkSink );
}
HWND Create( HWND hWndParent,
RECT& rcPos,
LPCTSTR szWindowName = NULL ,
DWORD dwStyle = 0 ,
DWORD dwExStyle = 0 ,
UINT nID = 0 ,
LPVOID lpCreateParam = NULL )
{
if(GetWndClassInfo().m_lpszOrigName == NULL)
{
GetWndClassInfo().m_lpszOrigName = GetWndClassName();
}
ATOM atom = GetWndClassInfo().Register( &m_pfnSuperWindowProc );
dwStyle = GetWndStyle ( dwStyle );
dwExStyle = GetWndExStyle( dwExStyle );
return CWindowImplBaseT<TWindow>::Create( hWndParent, rcPos, szWindowName, dwStyle, dwExStyle, nID, atom, lpCreateParam );
}
////////////////////////////////////////////////////////////////////////////////
LRESULT OnCreate( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
USES_CONVERSION;
CREATESTRUCT* lpCreate = (CREATESTRUCT*)lParam;
int nLen = ::GetWindowTextLength( m_hWnd );
LPTSTR lpstrName = (LPTSTR)_alloca( (nLen + 1) * sizeof(TCHAR) );
IAxWinHostWindow* pAxWindow = NULL;
int nCreateSize = 0;
CComPtr<IUnknown> spUnk;
CComPtr<IStream> spStream;
::GetWindowText( m_hWnd, lpstrName, nLen + 1 );
::SetWindowText( m_hWnd, _T("") );
if(lpCreate && lpCreate->lpCreateParams)
{
nCreateSize = *((WORD*)lpCreate->lpCreateParams);
}
//
// Get the data for the initialization stream.
//
if(nCreateSize)
{
HGLOBAL h = GlobalAlloc( GHND, nCreateSize );
if(h)
{
BYTE* pBytes = (BYTE*)GlobalLock( h );
BYTE* pSource = ((BYTE*)(lpCreate->lpCreateParams)) + sizeof(WORD);
//Align to DWORD
//pSource += (((~((DWORD)pSource)) + 1) & 3);
memcpy( pBytes, pSource, nCreateSize );
::GlobalUnlock( h );
::CreateStreamOnHGlobal( h, TRUE, &spStream );
}
}
//
// call the real creation routine here...
//
HRESULT hRet = PrivateCreateControlEx( T2COLE( lpstrName ), m_hWnd, spStream, &spUnk, NULL, IID_NULL, NULL );
if(FAILED(hRet)) return -1; // abort window creation
hRet = spUnk->QueryInterface( IID_IAxWinHostWindow, (void**)&pAxWindow );
if(FAILED(hRet)) return -1; // abort window creation
::SetWindowLongPtr( m_hWnd, GWLP_USERDATA, (LONG_PTR)pAxWindow );
//
// check for control parent style if control has a window
//
{
HWND hWndChild = ::GetWindow( m_hWnd, GW_CHILD );
if(hWndChild != NULL)
{
if(::GetWindowLong( hWndChild, GWL_EXSTYLE ) & WS_EX_CONTROLPARENT)
{
DWORD dwExStyle = ::GetWindowLong( m_hWnd, GWL_EXSTYLE );
dwExStyle |= WS_EX_CONTROLPARENT;
::SetWindowLong(m_hWnd, GWL_EXSTYLE, dwExStyle );
}
}
}
bHandled = TRUE;
return 0L;
}
LRESULT OnNCDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
{
IAxWinHostWindow* pAxWindow = (IAxWinHostWindow*)::GetWindowLongPtr( m_hWnd, GWLP_USERDATA );
if(pAxWindow != NULL) pAxWindow->Release();
m_hWnd = NULL;
bHandled = TRUE;
return 0L;
}
};
////////////////////////////////////////////////////////////////////////////////
class WindowHandle : public WindowImplT<WindowHandle>
{
public:
typedef WindowImplT<WindowHandle> baseClass;
typedef CComObject<HostWindow> theSite;
private:
theSite* m_pSiteObject;
bool m_fMultiTopic;
MPC::wstring m_szPrintFileName;
HANDLE m_hEvent;
public:
WindowHandle();
~WindowHandle();
BEGIN_MSG_MAP(WindowHandle)
CHAIN_MSG_MAP(baseClass)
END_MSG_MAP()
virtual HRESULT PrivateCreateControlEx( LPCOLESTR lpszName ,
HWND hWnd ,
IStream* pStream ,
IUnknown* *ppUnkContainer ,
IUnknown* *ppUnkControl ,
REFIID iidSink ,
IUnknown* punkSink );
void SetMultiTopic ( /*[in]*/ bool fMulti );
void SetPrintFileName( /*[in]*/ LPCWSTR szPrintFileName );
void SetAbortEvent ( /*[in]*/ HANDLE hEvent );
bool GetAbortState ( );
BSTR GetPrinterName ( );
};
////////////////////////////////////////////////////////////////////////////////
class ATL_NO_VTABLE CDispatchSink :
public CComObjectRootEx<CComSingleThreadModel>,
public IDispatch
{
HANDLE m_hEvent;
CComBSTR m_URL;
public:
BEGIN_COM_MAP(CDispatchSink)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_IID(DIID_DWebBrowserEvents2, IDispatch)
END_COM_MAP()
CDispatchSink();
void SetNotificationEvent( /*[in]*/ HANDLE hEvent );
BSTR GetCurrentURL ( );
STDMETHOD(GetTypeInfoCount)(UINT* pctinfo);
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo);
STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid);
STDMETHOD(Invoke)( DISPID dispidMember ,
REFIID riid ,
LCID lcid ,
WORD wFlags ,
DISPPARAMS* pdispparams ,
VARIANT* pvarResult ,
EXCEPINFO* pexcepinfo ,
UINT* puArgErr );
};
////////////////////////////////////////////////////////////////////////////////
class Print
{
public:
class Notification
{
public:
virtual HRESULT Progress( /*[in]*/ LPCWSTR szURL, /*[in]*/ int iDone, /*[in]*/ int iTotal ) = 0;
};
private:
Notification* m_pCallback; // Client for notification.
//
MPC::WStringList m_lstURLs; // list of urls to be printed
//
HWND m_hwnd; // parent window.
WindowHandle m_wnd; // window for hosting Trident
CComPtr<IWebBrowser2> m_spWebBrowser2; // pointer for Navigate call
//
CComPtr<CDispatchSink> m_spObjDisp; // our sink object for Trident events
HANDLE m_eventDocComplete; // this event is for notifying our code when the webbrowser is done loading a topic
HANDLE m_eventAbortPrint; // this event is for notifying our code when the webbrowser is done printing a topic
//
CComPtr<IUnknown> m_spUnkControl; // IUnknown of our control
DWORD m_dwCookie; // cookie for our Unadvise call
CComPtr<IOleCommandTarget> m_spOleCmdTarg; // pointer we need to tell Trident to print
MPC::wstring m_szPrintDir; // directory to print to
MPC::wstring m_szPrintFile; // file to print to
//
CComPtr<IStream> m_streamPrintData; // pointer to raw printer data
HRESULT PrintSingleURL( /*[in]*/ MPC::wstring& szUrl ); // print a single URL
HRESULT HookUpEventSink(); // hook up our event sink
HRESULT PreparePrintFileLoc(); // prepare our temporary print files
HRESULT WaitForDocComplete(); // wait for Trident to load the page
HRESULT DoPrint(); // send the print command to Trident
HRESULT WaitForPrintComplete(); // wait for Trident to finish printing
HRESULT UpdatePrintBuffer(); // load the print file data into our buffer
HRESULT RawDataToPrinter(); // dump a raw stream of data to the printer
public:
Print();
~Print();
HRESULT Initialize( /*[in]*/ HWND hwnd );
HRESULT Terminate ( );
HRESULT AddUrl( /*[in]*/ LPCWSTR szUrl );
HRESULT PrintAll( /*[in]*/ Notification* pCallback );
};
};
////////////////////////////////////////////////////////////////////////////////
class ATL_NO_VTABLE CPCHPrintEngine : // Hungarian: hcppe
public MPC::Thread < CPCHPrintEngine, IPCHPrintEngine, COINIT_APARTMENTTHREADED >,
public MPC::ConnectionPointImpl< CPCHPrintEngine, &DIID_DPCHPrintEngineEvents, MPC::CComSafeMultiThreadModel >,
public IDispatchImpl < IPCHPrintEngine, &IID_IPCHPrintEngine, &LIBID_HelpCenterTypeLib >,
public Printing::Print::Notification
{
Printing::Print m_engine;
MPC::CComPtrThreadNeutral<IDispatch> m_sink_onProgress;
MPC::CComPtrThreadNeutral<IDispatch> m_sink_onComplete;
//////////////////////////////////////////////////////////////////////
HRESULT Run();
HRESULT CanModifyProperties();
//////////////////////////////////////////////////////////////////////
//
// Event firing methods.
//
HRESULT Fire_onProgress( IPCHPrintEngine* hcppe, BSTR bstrURL, long lDone, long lTotal );
HRESULT Fire_onComplete( IPCHPrintEngine* hcppe, HRESULT hrRes );
//
// Callbacks
//
HRESULT Progress( /*[in]*/ LPCWSTR szURL, /*[in]*/ int iDone, /*[in]*/ int iTotal );
//////////////////////////////////////////////////////////////////////
public:
BEGIN_COM_MAP(CPCHPrintEngine)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IPCHPrintEngine)
COM_INTERFACE_ENTRY(IConnectionPointContainer)
END_COM_MAP()
CPCHPrintEngine();
void FinalRelease();
public:
// IPCHPrintEngine
STDMETHOD(put_onProgress)( /*[in] */ IDispatch* function );
STDMETHOD(put_onComplete)( /*[in] */ IDispatch* function );
STDMETHOD(AddTopic)( /*[in]*/ BSTR bstrURL );
STDMETHOD(Start)();
STDMETHOD(Abort)();
};
#endif // !defined(__INCLUDED___HCP___PRINTING_H___)