1388 lines
44 KiB
C++
1388 lines
44 KiB
C++
|
// Copyright (c) 1996-1997, Microsoft Corp. All rights reserved.
|
||
|
|
||
|
#include "header.h"
|
||
|
#include "contain.h"
|
||
|
#include "cprint.h"
|
||
|
#include "secwin.h"
|
||
|
#include "web.h"
|
||
|
#include "contain.h"
|
||
|
#include <exdisp.h>
|
||
|
#include <exdispid.h>
|
||
|
#include "cdlg.h"
|
||
|
#include "resource.h"
|
||
|
#include "progress.h"
|
||
|
#include "cpaldc.h"
|
||
|
#include "hha_strtable.h"
|
||
|
#include "animate.h"
|
||
|
#include <wininet.h>
|
||
|
|
||
|
// #define INITGUID
|
||
|
#include <mshtmhst.h>
|
||
|
#include <mshtmcid.h>
|
||
|
|
||
|
BOOL CPrint::OnBeginOrEnd(void)
|
||
|
{
|
||
|
if (m_fInitializing) {
|
||
|
switch (m_action) {
|
||
|
case PRINT_CUR_ALL:
|
||
|
SetCheck(IDRADIO_PRINT_ALL);
|
||
|
break;
|
||
|
|
||
|
case PRINT_CUR_HEADING:
|
||
|
SetCheck(IDRADIO_PRINT_BOOK);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
SetCheck(IDRADIO_PRINT_CURRENT);
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
if (GetCheck(IDRADIO_PRINT_ALL))
|
||
|
m_action = PRINT_CUR_ALL;
|
||
|
else if (GetCheck(IDRADIO_PRINT_BOOK))
|
||
|
m_action = PRINT_CUR_HEADING;
|
||
|
else
|
||
|
m_action = PRINT_CUR_TOPIC;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CHHWinType::OnPrint(void)
|
||
|
{
|
||
|
HWND hWnd;
|
||
|
|
||
|
if (m_pCIExpContainer == NULL)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
static BOOL fCurrentlyPrinting = FALSE;
|
||
|
if (fCurrentlyPrinting) {
|
||
|
MsgBox(IDS_PRINTING);
|
||
|
return;
|
||
|
}
|
||
|
CToc* ptoc = reinterpret_cast<CToc*>(m_aNavPane[HH_TAB_CONTENTS]) ; // HACKHACK: This should be a dynamic_cast. However, we are not compiling with RTTI.
|
||
|
hWnd = GetFocus();
|
||
|
int action = PRINT_CUR_TOPIC;
|
||
|
if (IsExpandedNavPane() && curNavType == HHWIN_NAVTYPE_TOC && ptoc != NULL)
|
||
|
{
|
||
|
HTREEITEM hitem = TreeView_GetSelection(ptoc->m_hwndTree);
|
||
|
if (hitem) {
|
||
|
CPrint prt(*this);
|
||
|
prt.SetAction(action);
|
||
|
if (!prt.DoModal())
|
||
|
{
|
||
|
SetFocus(hWnd);
|
||
|
return;
|
||
|
}
|
||
|
action = prt.GetAction();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (action == PRINT_CUR_TOPIC) {
|
||
|
m_pCIExpContainer->m_pIE3CmdTarget->Exec(NULL, OLECMDID_PRINT,
|
||
|
OLECMDEXECOPT_PROMPTUSER, NULL, NULL);
|
||
|
}
|
||
|
else {
|
||
|
fCurrentlyPrinting = TRUE;
|
||
|
PrintTopics(action, ptoc, m_pCIExpContainer->m_pWebBrowserApp, GetHwnd());
|
||
|
fCurrentlyPrinting = FALSE;
|
||
|
}
|
||
|
SetFocus(hWnd);
|
||
|
}
|
||
|
|
||
|
void PrintTopics(int action, CToc* ptoc, IWebBrowserAppImpl* pWebApp, HWND hWndHelp /* = NULL */)
|
||
|
{
|
||
|
ASSERT(pWebApp && pWebApp);
|
||
|
|
||
|
if (ptoc == NULL || pWebApp == NULL)
|
||
|
return;
|
||
|
|
||
|
static BOOL fCurrentlyPrinting = FALSE;
|
||
|
if (fCurrentlyPrinting) {
|
||
|
MsgBox(IDS_PRINTING);
|
||
|
return;
|
||
|
}
|
||
|
fCurrentlyPrinting = TRUE;
|
||
|
CStr cszCurrentUrl;
|
||
|
pWebApp->GetLocationURL(&cszCurrentUrl);
|
||
|
CPrintHook ph(cszCurrentUrl, ptoc, hWndHelp);
|
||
|
ph.BeginPrinting(action);
|
||
|
fCurrentlyPrinting = FALSE;
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
// CPrintHook member functions
|
||
|
CPrintHook::CPrintHook(PCSTR pszFirstUrl, CToc* pToc, HWND hWndHelp /* = NULL */)
|
||
|
: m_pcp(NULL), m_dwCookie(0), m_ref(0), m_pToc(pToc), m_action(PRINT_CUR_TOPIC),
|
||
|
m_hWndHelp(hWndHelp), m_phh(NULL), m_level(0),
|
||
|
m_fFirstHeading(TRUE), m_fDestroyHelpWindow(FALSE), m_cszFirstUrl(pszFirstUrl),
|
||
|
m_fIsIE3(FALSE), m_cszPrintFile("")
|
||
|
{
|
||
|
m_phh = pToc->m_phh;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL CPrintHook::CreatePrintWindow(CStr* pcszUrl /* = NULL */)
|
||
|
{
|
||
|
BOOL bReturn = FALSE;
|
||
|
|
||
|
HH_WINTYPE hhWinType;
|
||
|
ZERO_STRUCTURE(hhWinType);
|
||
|
hhWinType.cbStruct = sizeof(HH_WINTYPE);
|
||
|
hhWinType.pszType = txtPrintWindow;
|
||
|
hhWinType.pszCaption = GetStringResource(IDS_PRINT_CAPTION);
|
||
|
hhWinType.rcWindowPos.left = 0;
|
||
|
hhWinType.rcWindowPos.top = 0;
|
||
|
hhWinType.rcWindowPos.right = 200;
|
||
|
hhWinType.rcWindowPos.bottom = 200;
|
||
|
hhWinType.dwStyles = WS_MINIMIZE;
|
||
|
hhWinType.fsValidMembers = HHWIN_PARAM_RECT | HHWIN_PARAM_STYLES;
|
||
|
|
||
|
xHtmlHelpA(NULL, NULL, HH_SET_WIN_TYPE, (DWORD_PTR) &hhWinType);
|
||
|
|
||
|
m_hWndHelp = xHtmlHelpA(NULL, txtPrintWindow, HH_DISPLAY_TOPIC, (DWORD_PTR) (pcszUrl ? pcszUrl->psz : m_cszFirstUrl.psz));
|
||
|
m_fDestroyHelpWindow = TRUE;
|
||
|
|
||
|
if (m_hWndHelp != NULL)
|
||
|
{
|
||
|
StartAnimation(IDS_GATHERING_PRINTS, m_hWndHelp);
|
||
|
m_phh = FindWindowIndex(m_hWndHelp);
|
||
|
|
||
|
if (!m_fDestroyHelpWindow)
|
||
|
m_phh->m_pCIExpContainer->m_pWebBrowserApp->Navigate((pcszUrl ? (PCSTR)*pcszUrl : (PCSTR)m_cszFirstUrl),
|
||
|
NULL, NULL, NULL, NULL);
|
||
|
|
||
|
// Set up the event sink for the WebBrowser control.
|
||
|
LPCONNECTIONPOINTCONTAINER pcpc;
|
||
|
HRESULT hr = m_phh->m_pCIExpContainer->m_pWebBrowserApp->m_lpDispatch->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pcpc);
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
// Try to find the connection point for DIID_DWebBrowserEvents2.
|
||
|
// If that fails, try DIID_DWebBrowserEvents.
|
||
|
hr = pcpc->FindConnectionPoint(DIID_DWebBrowserEvents2, &m_pcp);
|
||
|
|
||
|
if (FAILED(hr))
|
||
|
{
|
||
|
m_fIsIE3 = TRUE;
|
||
|
hr = pcpc->FindConnectionPoint(DIID_DWebBrowserEvents, &m_pcp);
|
||
|
}
|
||
|
|
||
|
pcpc->Release();
|
||
|
|
||
|
if (SUCCEEDED(hr))
|
||
|
{
|
||
|
hr = m_pcp->Advise((LPUNKNOWN)(LPDISPATCH)this, &m_dwCookie);
|
||
|
bReturn = TRUE;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
|
||
|
void CPrintHook::DestroyPrintWindow()
|
||
|
{
|
||
|
// Disconnect the event sink.
|
||
|
if (m_pcp != NULL)
|
||
|
{
|
||
|
#ifdef _DEBUG
|
||
|
HRESULT hr = m_pcp->Unadvise(m_dwCookie);
|
||
|
ASSERT(SUCCEEDED(hr));
|
||
|
#else
|
||
|
m_pcp->Unadvise(m_dwCookie);
|
||
|
#endif
|
||
|
m_pcp->Release();
|
||
|
m_pcp = NULL;
|
||
|
}
|
||
|
|
||
|
if (m_hWndHelp != NULL)
|
||
|
{
|
||
|
if (m_fDestroyHelpWindow)
|
||
|
{
|
||
|
DestroyWindow(m_hWndHelp);
|
||
|
m_hWndHelp = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
DeleteFile(m_cszPrintFile);
|
||
|
}
|
||
|
|
||
|
|
||
|
CPrintHook::~CPrintHook()
|
||
|
{
|
||
|
DestroyPrintWindow();
|
||
|
|
||
|
ASSERT(m_ref == 0);
|
||
|
}
|
||
|
|
||
|
|
||
|
// Generic OLE method implementations.
|
||
|
|
||
|
STDMETHODIMP CPrintHook::QueryInterface(
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [iid_is][out] */ void **ppvObject)
|
||
|
{
|
||
|
if (DO_GUIDS_MATCH(riid, IID_IUnknown) ||
|
||
|
DO_GUIDS_MATCH(riid, IID_IDispatch) ||
|
||
|
DO_GUIDS_MATCH(riid, DIID_DWebBrowserEvents) ||
|
||
|
DO_GUIDS_MATCH(riid, DIID_DWebBrowserEvents2))
|
||
|
{
|
||
|
*ppvObject = (LPVOID)this;
|
||
|
AddRef();
|
||
|
return S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppvObject = NULL;
|
||
|
}
|
||
|
|
||
|
return E_NOINTERFACE;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CPrintHook::AddRef(void)
|
||
|
{
|
||
|
return ++m_ref;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CPrintHook::Release(void)
|
||
|
{
|
||
|
return --m_ref;
|
||
|
}
|
||
|
|
||
|
// IDispatch method implementation.
|
||
|
|
||
|
STDMETHODIMP CPrintHook::GetTypeInfoCount(
|
||
|
/* [out] */ UINT *pctinfo)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CPrintHook::GetTypeInfo(
|
||
|
/* [in] */ UINT iTInfo,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [out] */ ITypeInfo **ppTInfo)
|
||
|
{
|
||
|
// arg checking
|
||
|
|
||
|
if (iTInfo != 0)
|
||
|
return DISP_E_BADINDEX;
|
||
|
|
||
|
if (!ppTInfo)
|
||
|
return E_POINTER;
|
||
|
|
||
|
*ppTInfo = NULL;
|
||
|
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CPrintHook::GetIDsOfNames(
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [size_is][in] */ LPOLESTR __RPC_FAR *rgszNames,
|
||
|
/* [in] */ UINT cNames,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [size_is][out] */ DISPID __RPC_FAR *rgDispId)
|
||
|
{
|
||
|
return E_NOTIMPL;
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP CPrintHook::Invoke(
|
||
|
/* [in] */ DISPID dispIdMember,
|
||
|
/* [in] */ REFIID riid,
|
||
|
/* [in] */ LCID lcid,
|
||
|
/* [in] */ WORD wFlags,
|
||
|
/* [out][in] */ DISPPARAMS *pdispparams,
|
||
|
/* [out] */ VARIANT *pVarResult,
|
||
|
/* [out] */ EXCEPINFO *pExcepInfo,
|
||
|
/* [out] */ UINT *puArgErr)
|
||
|
{
|
||
|
if (!DO_GUIDS_MATCH(riid, IID_NULL))
|
||
|
return DISP_E_UNKNOWNINTERFACE;
|
||
|
|
||
|
if (!(wFlags & DISPATCH_METHOD))
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
switch (dispIdMember)
|
||
|
{
|
||
|
case DISPID_BEFORENAVIGATE:
|
||
|
DBWIN("DISPID_BEFORENAVIGATE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_BEFORENAVIGATE2: // ie4 version.
|
||
|
char szURL[MAX_URL];
|
||
|
char szTFN[MAX_URL];
|
||
|
char szHeaders[MAX_URL];
|
||
|
WideCharToMultiByte(CP_ACP, 0, pdispparams->rgvarg[5].pvarVal->bstrVal, -1, szURL, sizeof(szURL), NULL, NULL);
|
||
|
// 27-Sep-1997 [ralphw] IE 4 will send us a script command, followed
|
||
|
// by a 1 then the current URL. We don't care about the current URL
|
||
|
// in this case, so we nuke it.
|
||
|
{
|
||
|
PSTR pszCurUrl = StrChr(szURL, 1);
|
||
|
if (pszCurUrl)
|
||
|
*pszCurUrl = '\0';
|
||
|
}
|
||
|
szTFN[0] = 0;
|
||
|
if( pdispparams->rgvarg[3].pvarVal->bstrVal )
|
||
|
WideCharToMultiByte(CP_ACP, 0, pdispparams->rgvarg[3].pvarVal->bstrVal, -1, szTFN, sizeof(szTFN), NULL, NULL);
|
||
|
szHeaders[0] = 0;
|
||
|
if( pdispparams->rgvarg[1].pvarVal->bstrVal )
|
||
|
WideCharToMultiByte(CP_ACP, 0, pdispparams->rgvarg[1].pvarVal->bstrVal, -1, szHeaders, sizeof(szHeaders), NULL, NULL);
|
||
|
|
||
|
// OnBeforeNavigate(szURL, (long)pdispparams->rgvarg[4].pvarVal->lVal, szTFN,
|
||
|
// pdispparams->rgvarg[2].pvarVal, szHeaders, (BOOL*)pdispparams->rgvarg[0].pboolVal );
|
||
|
break;
|
||
|
|
||
|
#if 0
|
||
|
case DISPID_STATUSTEXTCHANGE:
|
||
|
DBWIN("DISPID_STATUSTEXTCHANGE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_DOWNLOADBEGIN:
|
||
|
DBWIN("DISPID_DOWNLOADBEGIN\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_NEWWINDOW:
|
||
|
DBWIN("DISPID_NEWWINDOW\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_WINDOWMOVE:
|
||
|
DBWIN("DISPID_WINDOWMOVE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_WINDOWRESIZE:
|
||
|
DBWIN("DISPID_WINDOWRESIZE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_WINDOWACTIVATE:
|
||
|
DBWIN("DISPID_WINDOWACTIVATE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_PROPERTYCHANGE:
|
||
|
DBWIN("DISPID_PROPERTYCHANGE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_TITLECHANGE:
|
||
|
DBWIN("DISPID_TITLECHANGE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_FRAMEBEFORENAVIGATE:
|
||
|
DBWIN("DISPID_FRAMEBEFORENAVIGATE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_FRAMENAVIGATECOMPLETE:
|
||
|
DBWIN("DISPID_FRAMENAVIGATECOMPLETE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_FRAMENEWWINDOW:
|
||
|
DBWIN("DISPID_FRAMENEWWINDOW\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_NAVIGATECOMPLETE:
|
||
|
DBWIN("DISPID_NAVIGATECOMPLETE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_DOWNLOADCOMPLETE:
|
||
|
DBWIN("DISPID_DOWNLOADCOMPLETE\n");
|
||
|
break;
|
||
|
|
||
|
case DISPID_DOCUMENTCOMPLETE:
|
||
|
DBWIN("DISPID_DOCUMENTCOMPLETE\n");
|
||
|
break;
|
||
|
#endif
|
||
|
case DISPID_PROGRESSCHANGE:
|
||
|
ASSERT(pdispparams->cArgs == 2);
|
||
|
DBWIN("DISPID_PROGRESSCHANGE\n");
|
||
|
OnProgressChange(V_I4(&(pdispparams->rgvarg[1])), V_I4(&(pdispparams->rgvarg[0])));
|
||
|
#if 1
|
||
|
#ifdef _DEBUG
|
||
|
char szDebug[80];
|
||
|
wsprintf(szDebug, "ProgressChange(%li, %li)\n", V_I4(&(pdispparams->rgvarg[1])), V_I4(&(pdispparams->rgvarg[0])));
|
||
|
DBWIN(szDebug);
|
||
|
#endif
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
return S_OK;
|
||
|
}
|
||
|
|
||
|
void CPrintHook::OnProgressChange(LONG lProgress, LONG lProgressMax)
|
||
|
{
|
||
|
if (lProgress == -1)
|
||
|
{
|
||
|
StopAnimation();
|
||
|
// Print the page if it isn't a duplicate.
|
||
|
if (m_fIsPrinting)
|
||
|
{
|
||
|
Print();
|
||
|
DBWIN("Printing");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
NextAnimation();
|
||
|
}
|
||
|
|
||
|
// This function allows the WebBrowser to handle its queued messages before continuing.
|
||
|
|
||
|
BOOL CPrintHook::PumpMessages()
|
||
|
{
|
||
|
MSG msg;
|
||
|
|
||
|
// Handle WebBrowser window messages
|
||
|
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||
|
{
|
||
|
if (!m_fIsPrinting)
|
||
|
{
|
||
|
if (m_phh && m_phh->m_pCIExpContainer && m_phh->m_pCIExpContainer->m_pWebBrowserApp)
|
||
|
{
|
||
|
m_phh->m_pCIExpContainer->m_pWebBrowserApp->Stop();
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if(!IsDialogMessage(m_hWndHelp, &msg))
|
||
|
{
|
||
|
TranslateMessage(&msg);
|
||
|
DispatchMessage(&msg);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
void CPrintHook::BeginPrinting(int action)
|
||
|
{
|
||
|
m_pos = 1;
|
||
|
m_level = 0;
|
||
|
m_action = action;
|
||
|
m_fIsPrinting = TRUE;
|
||
|
m_fFirstHeading = TRUE;
|
||
|
SITEMAP_ENTRY* psme = NULL;
|
||
|
TV_ITEM tvi;
|
||
|
|
||
|
if (m_action == PRINT_CUR_TOPIC || m_action == PRINT_CUR_HEADING)
|
||
|
{
|
||
|
tvi.hItem = TreeView_GetSelection(m_pToc->m_hwndTree);
|
||
|
if (!tvi.hItem)
|
||
|
goto ExitBegin; // no current selection
|
||
|
|
||
|
if (m_pToc->m_fBinaryTOC == FALSE)
|
||
|
{
|
||
|
tvi.mask = TVIF_PARAM;
|
||
|
if (TreeView_GetItem(m_pToc->m_hwndTree, &tvi))
|
||
|
psme = m_pToc->m_sitemap.GetSiteMapEntry((int)tvi.lParam);
|
||
|
if (psme == NULL)
|
||
|
goto ExitBegin;
|
||
|
m_pos = (int)tvi.lParam;
|
||
|
|
||
|
// Because the user may have selected a topic under a heading, but
|
||
|
// wants to print all of the topics under that heading, we have to
|
||
|
// search upward until we find the heading.
|
||
|
if (m_action == PRINT_CUR_HEADING)
|
||
|
{
|
||
|
if (psme->fTopic || psme->cUrls <= 0)
|
||
|
{
|
||
|
while (psme != NULL && psme->fTopic && m_pos > 0)
|
||
|
{
|
||
|
psme = m_pToc->m_sitemap.GetSiteMapEntry(--m_pos);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
// Set the current level for reference later. If the user just
|
||
|
// wants to print the current topic, the level isn't significant.
|
||
|
m_level = ((m_action == PRINT_CUR_TOPIC || psme == NULL) ? 0 : psme->level);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_pToc->m_fBinaryTOC == FALSE)
|
||
|
{
|
||
|
// If the user isn't printing all topics and psme is NULL,
|
||
|
// see if this is just a single topic and, if so, print it.
|
||
|
if (m_action != PRINT_CUR_ALL && psme == NULL)
|
||
|
{
|
||
|
// Get the original sitemap entry.
|
||
|
m_pos = (int)tvi.lParam;
|
||
|
psme = m_pToc->m_sitemap.GetSiteMapEntry(m_pos);
|
||
|
|
||
|
// If there's a URL, print it.
|
||
|
if (psme->cUrls > 0)
|
||
|
{
|
||
|
m_action = PRINT_CUR_TOPIC;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (BuildPrintTable())
|
||
|
{
|
||
|
// We sit in this loop while printing because we don't want this
|
||
|
// function to return until printing is complete.
|
||
|
while (PumpMessages());
|
||
|
DestroyPrintWindow();
|
||
|
}
|
||
|
|
||
|
ExitBegin:
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
BOOL CPrintHook::BuildPrintTable()
|
||
|
{
|
||
|
BOOL bReturn = FALSE;
|
||
|
|
||
|
if (!m_fIsPrinting)
|
||
|
return bReturn;
|
||
|
|
||
|
CTable table;
|
||
|
CStr cszCurUrl;
|
||
|
|
||
|
if (m_pToc->m_fBinaryTOC)
|
||
|
{
|
||
|
switch (m_action)
|
||
|
{
|
||
|
case PRINT_CUR_TOPIC:
|
||
|
m_pToc->m_phhctrl->m_pWebBrowserApp->GetLocationURL(&cszCurUrl);
|
||
|
table.AddString((PCSTR)cszCurUrl);
|
||
|
break;
|
||
|
|
||
|
case PRINT_CUR_HEADING:
|
||
|
TV_ITEM tvi;
|
||
|
|
||
|
tvi.hItem = TreeView_GetSelection(m_pToc->m_hwndTree);
|
||
|
if (!tvi.hItem)
|
||
|
{
|
||
|
m_pToc->m_phhctrl->m_pWebBrowserApp->GetLocationURL(&cszCurUrl);
|
||
|
table.AddString((PCSTR)cszCurUrl);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tvi.mask = TVIF_PARAM;
|
||
|
TreeView_GetItem(m_pToc->m_hwndTree, &tvi);
|
||
|
|
||
|
CTreeNode *p = (CTreeNode *)tvi.lParam;
|
||
|
CTreeNode *pParent = NULL;
|
||
|
|
||
|
if (p->GetType() == TOPIC)
|
||
|
{
|
||
|
pParent = p->GetParent();
|
||
|
}
|
||
|
CHourGlass hour;
|
||
|
m_phh->m_phmData->m_pTitleCollection->GetChildURLS((pParent ? pParent: p), &table);
|
||
|
if (pParent)
|
||
|
delete pParent;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case PRINT_CUR_ALL:
|
||
|
if (!m_pToc->m_pBinTOCRoot)
|
||
|
{
|
||
|
m_pToc->m_phhctrl->m_pWebBrowserApp->GetLocationURL(&cszCurUrl);
|
||
|
table.AddString((PCSTR)cszCurUrl);
|
||
|
}
|
||
|
else
|
||
|
m_phh->m_phmData->m_pTitleCollection->GetChildURLS(m_pToc->m_pBinTOCRoot, &table); // oh my god they are printing the entire TOC
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Get the next sitemap entry.
|
||
|
// Print the sitemap entry URL if the its level is greater than
|
||
|
// the saved level. If the sitemap entry is a heading at the same
|
||
|
// level and contains a URL, proceed as well.
|
||
|
for (SITEMAP_ENTRY* psme = m_pToc->m_sitemap.GetSiteMapEntry(m_pos);
|
||
|
psme != NULL;
|
||
|
psme = m_pToc->m_sitemap.GetSiteMapEntry(++m_pos))
|
||
|
{
|
||
|
if ((psme->level > m_level) ||
|
||
|
(!psme->fTopic && psme->level == m_level && m_fFirstHeading))
|
||
|
{
|
||
|
// The top level heading could have a URL, so we
|
||
|
// want to print it. However, we don't want to print
|
||
|
// any other headings at that level, so set the
|
||
|
// m_fFirstHeading flag to FALSE.
|
||
|
if (m_action == PRINT_CUR_HEADING &&
|
||
|
!psme->fTopic &&
|
||
|
psme->level == m_level)
|
||
|
{
|
||
|
m_fFirstHeading = FALSE;
|
||
|
}
|
||
|
|
||
|
if (psme->cUrls > 0)
|
||
|
{
|
||
|
// Get the URL from the sitemap entry.
|
||
|
LPCTSTR pszUrl = (psme->pUrls->urlPrimary ? psme->pUrls->urlPrimary : psme->pUrls->urlSecondary);
|
||
|
CStr cszUrl(pszUrl);
|
||
|
|
||
|
// Synchronize the TOC if we created the print window.
|
||
|
if (m_fDestroyHelpWindow)
|
||
|
m_pToc->Synchronize(cszUrl);
|
||
|
|
||
|
// Truncate the strings at the # character if there is one.
|
||
|
LPTSTR pszFind = StrChr(cszUrl, '#');
|
||
|
if (pszFind != NULL)
|
||
|
*pszFind = '\0';
|
||
|
|
||
|
ConvertBackSlashToForwardSlash(cszUrl);
|
||
|
|
||
|
if (table.IsStringInTable(cszUrl) == 0)
|
||
|
table.AddString((PCSTR)cszUrl);
|
||
|
|
||
|
if (m_action == PRINT_CUR_TOPIC)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (m_pToc->m_phhctrl != NULL)
|
||
|
{
|
||
|
m_pToc->m_phhctrl->m_pWebBrowserApp->GetLocationURL(&cszCurUrl);
|
||
|
m_hwndParent = m_pToc->m_phhctrl->m_hwndParent;
|
||
|
}
|
||
|
else if (m_pToc->m_fBinaryTOC)
|
||
|
{
|
||
|
cszCurUrl = m_phh->GetToc();
|
||
|
m_hwndParent = m_phh->GetHwnd();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
cszCurUrl = m_pToc->m_sitemap.GetSiteMapFile();
|
||
|
if (m_phh)
|
||
|
m_hwndParent = m_phh->GetHwnd();
|
||
|
else
|
||
|
m_hwndParent = m_hWndHelp;
|
||
|
}
|
||
|
|
||
|
if (ConstructFile((PCSTR)cszCurUrl, &table, &m_cszPrintFile))
|
||
|
{
|
||
|
bReturn = CreatePrintWindow(&m_cszPrintFile);
|
||
|
}
|
||
|
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
static const char txtTmpPrefix[] = "~hh";
|
||
|
static const char txtHtmlExtension[] = ".htm";
|
||
|
static const char txtImg[] = "IMG";
|
||
|
static const char txtSrc[] = "SRC";
|
||
|
static const char txtLink[] = "LINK";
|
||
|
static const char txtHREF[] = "HREF";
|
||
|
static const char txtTagBeginBody[] = "BODY";
|
||
|
static const char txtTagEndBody[] = "/BODY";
|
||
|
static const char txtTagItAll[] = "</BODY></HTML>";
|
||
|
static const char txtTmpPrintStinrg[] = "~hh%X.htm";
|
||
|
static const char txtFrame[] = "FRAME";
|
||
|
static const char txtBeginScript[] = "SCRIPT";
|
||
|
static const char txtEndScript[] = "/SCRIPT";
|
||
|
|
||
|
const int FILE_PAD = 16 * 1024;
|
||
|
|
||
|
BOOL CPrintHook::ConstructFile(PCSTR pszCurrentUrl, CTable* pFileTable,
|
||
|
CStr* pm_cszPrintFile)
|
||
|
{
|
||
|
char szTempPath[MAX_PATH];
|
||
|
char szHtmlFile[MAX_PATH];
|
||
|
char szThisURL[MAX_PATH];
|
||
|
char szCurrentUrl[MAX_PATH];
|
||
|
|
||
|
CProgress progress(GetStringResource(IDS_GATHERING_PRINTS),
|
||
|
m_hwndParent, pFileTable->CountStrings() / 10, 10);
|
||
|
|
||
|
strcpy(szCurrentUrl, pszCurrentUrl);
|
||
|
PSTR pszFilePortion = (PSTR) FindFilePortion(szCurrentUrl);
|
||
|
ASSERT(pszFilePortion);
|
||
|
|
||
|
GetTempPath(sizeof(szHtmlFile), szHtmlFile);
|
||
|
AddTrailingBackslash(szHtmlFile);
|
||
|
wsprintf(szHtmlFile + strlen(szHtmlFile), txtTmpPrintStinrg, GetTickCount() & 0xFFFF);
|
||
|
HFILE hfDst = _lcreat(szHtmlFile, 0);
|
||
|
if (hfDst == HFILE_ERROR) {
|
||
|
MsgBox(IDS_FILE_ERROR, szHtmlFile, MB_OK);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
int endpos = pFileTable->CountStrings();
|
||
|
PSTR pszMem = NULL;
|
||
|
CStr cszTmpFile;
|
||
|
|
||
|
for (int i = 1; i <= endpos; i++) {
|
||
|
BOOL fSeenBody = FALSE;
|
||
|
if (pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
pszMem = NULL;
|
||
|
}
|
||
|
progress.Progress();
|
||
|
|
||
|
ASSERT_COMMENT(pFileTable->CountStrings(), "Empty file list");
|
||
|
|
||
|
PSTR pszFile;
|
||
|
if (!StrChr(pFileTable->GetPointer(i), CH_COLON)) {
|
||
|
if (*pFileTable->GetPointer(i) == '/' || *pFileTable->GetPointer(i) == '\\')
|
||
|
{
|
||
|
TranslateUrl(szCurrentUrl, pFileTable->GetPointer(i));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strcpy(pszFilePortion, pFileTable->GetPointer(i));
|
||
|
}
|
||
|
pszFile = szCurrentUrl;
|
||
|
}
|
||
|
else {
|
||
|
pszFile = pFileTable->GetPointer(i);
|
||
|
PSTR psz = stristr(pszFile, txtSysRoot);
|
||
|
if (psz) {
|
||
|
char szPath[MAX_PATH];
|
||
|
GetRegWindowsDirectory(szPath);
|
||
|
strcat(szPath, psz + strlen(txtSysRoot));
|
||
|
cszTmpFile = szPath;
|
||
|
pszFile = cszTmpFile.psz;
|
||
|
}
|
||
|
else if (IsCompiledHtmlFile(pszFile, &cszTmpFile)) {
|
||
|
pszFile = cszTmpFile.psz;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
strcpy(szThisURL, pszFile);
|
||
|
|
||
|
if (!ConvertToCacheFile(pszFile, szTempPath)) {
|
||
|
// AuthorMsg(IDS_CANT_OPEN, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
int cbMem;
|
||
|
UINT cbFile, cbFinalLen;
|
||
|
PSTR psz, pszStart , pszTag;
|
||
|
|
||
|
if ( IsCompiledURL(szTempPath ) ) {
|
||
|
CStr cszCompiledName;
|
||
|
PCSTR pszStream = GetCompiledName(szTempPath, &cszCompiledName);
|
||
|
if (pszStream == NULL)
|
||
|
continue;
|
||
|
|
||
|
// BUGBUG: should use existing file system handle if available
|
||
|
|
||
|
CFSClient fs;
|
||
|
if (!fs.Initialize(cszCompiledName)) {
|
||
|
MsgBox(IDS_FILE_ERROR, pFileTable->GetPointer(i), MB_OK);
|
||
|
continue;
|
||
|
}
|
||
|
if (FAILED(fs.OpenStream(pszStream))) {
|
||
|
// AuthorMsg(IDS_CANT_OPEN, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
cbFile = fs.SeekSub(0, SK_END);
|
||
|
cbFinalLen = cbFile;
|
||
|
fs.SeekSub(0, SK_SET);
|
||
|
cbMem = cbFile + FILE_PAD;
|
||
|
pszMem = (PSTR) GlobalAlloc(GMEM_FIXED, cbMem);
|
||
|
ASSERT(pszMem);
|
||
|
if (!pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
fs.CloseStream();
|
||
|
continue;
|
||
|
}
|
||
|
if (FAILED(fs.Read((PBYTE) pszMem, cbFile))) {
|
||
|
fs.CloseStream();
|
||
|
continue;
|
||
|
}
|
||
|
fs.CloseStream();
|
||
|
}
|
||
|
else {
|
||
|
HANDLE hf = CreateFile(szTempPath, GENERIC_READ, FILE_SHARE_READ,
|
||
|
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||
|
if (hf == INVALID_HANDLE_VALUE)
|
||
|
goto BadFile;
|
||
|
|
||
|
ASSERT(hf);
|
||
|
cbFile = GetFileSize(hf, NULL);
|
||
|
cbFinalLen = cbFile;
|
||
|
cbMem = cbFile + FILE_PAD;
|
||
|
pszMem = (PSTR) GlobalAlloc(GMEM_FIXED, cbMem);
|
||
|
ASSERT(pszMem);
|
||
|
if (!pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
CloseHandle(hf);
|
||
|
continue; // next HTML file might be smaller, so try again
|
||
|
}
|
||
|
DWORD cbRead;
|
||
|
if (!ReadFile(hf, pszMem, cbFile, &cbRead, NULL) || cbRead != cbFile) {
|
||
|
CloseHandle(hf);
|
||
|
continue;
|
||
|
}
|
||
|
CloseHandle(hf);
|
||
|
}
|
||
|
pszMem[cbFile] = '\0';
|
||
|
|
||
|
psz = pszMem;
|
||
|
pszStart = psz;
|
||
|
pszTag = psz;
|
||
|
while ((pszTag = StrChr(pszTag, '<'))) {
|
||
|
pszTag = FirstNonSpace(pszTag + 1);
|
||
|
if (IsSamePrefix(pszTag, txtTagEndBody, sizeof(txtTagEndBody) - 1)) {
|
||
|
while (*pszTag != '<') // back up to the angle bracket
|
||
|
pszTag--;
|
||
|
cbFile = (int)(pszTag - pszStart);
|
||
|
break;
|
||
|
}
|
||
|
else if (IsSamePrefix(pszTag, txtBeginScript, sizeof(txtBeginScript) - 1)) {
|
||
|
// skip to end tag
|
||
|
while ((pszTag = StrChr(pszTag, '<'))) {
|
||
|
pszTag = FirstNonSpace(pszTag + 1);
|
||
|
if (IsSamePrefix(pszTag, txtEndScript, sizeof(txtEndScript) - 1))
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if (IsSamePrefix(pszTag, txtTagBeginBody, sizeof(txtTagBeginBody) - 1)) {
|
||
|
|
||
|
// If this isn't the first HTML file, then we ignore everything
|
||
|
// up to the body tag
|
||
|
|
||
|
if (i > 1 && !fSeenBody) {
|
||
|
fSeenBody = TRUE;
|
||
|
pszStart = StrChr(pszTag, '>');
|
||
|
if (!pszStart) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
pszStart++;
|
||
|
cbFile -= (int)(pszStart - pszMem);
|
||
|
}
|
||
|
}
|
||
|
else if (IsSamePrefix(pszTag, txtImg, sizeof(txtImg) - 1)) {
|
||
|
|
||
|
// Change the URL for images to be a full path -- this lets
|
||
|
// the browser pull it in without us having to copy it
|
||
|
// anywhere.
|
||
|
|
||
|
pszTag += sizeof(txtImg) - 1;
|
||
|
for(;;) {
|
||
|
while (*pszTag != ' ' && *pszTag != '>') {
|
||
|
if (*pszTag == CH_QUOTE) {
|
||
|
pszTag = StrChr(pszTag + 1, CH_QUOTE);
|
||
|
if (!pszTag) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
}
|
||
|
pszTag++;
|
||
|
}
|
||
|
if (*pszTag == '>')
|
||
|
goto NoSrcTag;
|
||
|
pszTag++;
|
||
|
if (IsSamePrefix(pszTag, txtSrc, sizeof(txtSrc) - 1))
|
||
|
break;
|
||
|
pszTag++;
|
||
|
}
|
||
|
ASSERT(IsSamePrefix(pszTag, txtSrc, sizeof(txtSrc) - 1));
|
||
|
pszTag = StrChr(pszTag, '=');
|
||
|
if (!pszTag) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
pszTag = FirstNonSpace(pszTag + 1);
|
||
|
char chSearch;
|
||
|
if (*pszTag == CH_QUOTE) {
|
||
|
chSearch = CH_QUOTE;
|
||
|
pszTag = FirstNonSpace(pszTag + 1);
|
||
|
}
|
||
|
else
|
||
|
chSearch = ' ';
|
||
|
PSTR pszBeginUrl = pszTag;
|
||
|
pszTag = StrChr(pszTag + 1, chSearch);
|
||
|
if (!pszTag) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
char chSave = *pszTag;
|
||
|
*pszTag = '\0';
|
||
|
if (!StrChr(pszBeginUrl, CH_COLON)) {
|
||
|
|
||
|
// This makes it relative to the original HTML file,
|
||
|
// but not necessarily relative to the current file
|
||
|
|
||
|
CStr cszCompiledName;
|
||
|
char fname[_MAX_FNAME]="";
|
||
|
int diff=0;
|
||
|
PSTR pszBeginFile='\0';
|
||
|
strcpy(szTempPath, szThisURL);
|
||
|
|
||
|
if ( IsCompiledURL(szTempPath ) )
|
||
|
{ // a compiled URL with an image in it.
|
||
|
PCSTR pszStream = GetCompiledName(szTempPath, &cszCompiledName);
|
||
|
SplitPath(pszStream, NULL, NULL, fname, NULL);
|
||
|
pszBeginFile = stristr(szTempPath, fname);
|
||
|
ASSERT( pszBeginFile );
|
||
|
diff = (int)(strlen(szThisURL) - strlen(pszBeginFile));
|
||
|
}else
|
||
|
{ // non-compiled URL; an html file with and image in it
|
||
|
pszBeginFile = strrchr(szTempPath, '/');
|
||
|
ASSERT(pszBeginFile);
|
||
|
diff = (int)(pszBeginFile - szTempPath) + 1;
|
||
|
}
|
||
|
|
||
|
cbFile += diff;
|
||
|
cbFinalLen += diff;
|
||
|
while (cbFinalLen > (UINT) cbMem) {
|
||
|
int StartDiff = (int)(pszStart - pszMem);
|
||
|
int TagDiff = (int)(pszTag - pszMem);
|
||
|
int BeginDiff = (int)(pszBeginUrl - pszMem);
|
||
|
PSTR pszNew = (PSTR) GlobalReAlloc((HGLOBAL) pszMem, cbMem += FILE_PAD, GMEM_MOVEABLE);
|
||
|
ASSERT(pszNew);
|
||
|
if (!pszNew) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
MsgBox(IDS_OOM);
|
||
|
_lclose(hfDst);
|
||
|
DeleteFile(szHtmlFile);
|
||
|
if (pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
pszMem = NULL;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
pszMem = pszNew;
|
||
|
pszStart = pszMem + StartDiff;
|
||
|
pszTag = pszMem + TagDiff;
|
||
|
pszBeginUrl = pszMem + BeginDiff;
|
||
|
}
|
||
|
MoveMemory(pszTag + diff, pszTag, cbFinalLen - (pszTag - pszMem) - diff);
|
||
|
|
||
|
if ( !IsCompiledURL(szTempPath) )
|
||
|
{
|
||
|
strcpy(pszBeginFile, "/");
|
||
|
pszBeginFile ++; // pointing at the NULL
|
||
|
}
|
||
|
strcpy(pszBeginFile, pszBeginUrl);
|
||
|
strcpy( pszBeginUrl, szTempPath);
|
||
|
pszTag += diff;
|
||
|
*pszTag = chSave;
|
||
|
}
|
||
|
else
|
||
|
*pszTag = chSave;
|
||
|
}
|
||
|
else if (IsSamePrefix(pszTag, txtLink, sizeof(txtLink) - 1)) {
|
||
|
|
||
|
// Change the URL for CSS to be a full path -- this lets
|
||
|
// the browser pull it in without us having to copy it
|
||
|
// anywhere.
|
||
|
|
||
|
pszTag += sizeof(txtImg) - 1;
|
||
|
for(;;) {
|
||
|
while (*pszTag != ' ' && *pszTag != '>') {
|
||
|
if (*pszTag == CH_QUOTE) {
|
||
|
pszTag = StrChr(pszTag + 1, CH_QUOTE);
|
||
|
if (!pszTag) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
}
|
||
|
pszTag++;
|
||
|
}
|
||
|
if (*pszTag == '>')
|
||
|
goto NoSrcTag;
|
||
|
pszTag++;
|
||
|
if (IsSamePrefix(pszTag, txtHREF, sizeof(txtHREF) - 1))
|
||
|
break;
|
||
|
pszTag++;
|
||
|
}
|
||
|
ASSERT(IsSamePrefix(pszTag, txtHREF, sizeof(txtHREF) - 1));
|
||
|
pszTag = StrChr(pszTag, '=');
|
||
|
if (!pszTag) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
pszTag = FirstNonSpace(pszTag + 1);
|
||
|
char chSearch;
|
||
|
if (*pszTag == CH_QUOTE) {
|
||
|
chSearch = CH_QUOTE;
|
||
|
pszTag = FirstNonSpace(pszTag + 1);
|
||
|
}
|
||
|
else
|
||
|
chSearch = ' ';
|
||
|
PSTR pszBeginUrl = pszTag;
|
||
|
pszTag = StrChr(pszTag + 1, chSearch);
|
||
|
if (!pszTag) {
|
||
|
AuthorMsg(IDSHHA_CORRUPTED_HTML, pFileTable->GetPointer(i), m_hwndParent, NULL);
|
||
|
goto BadFile;
|
||
|
}
|
||
|
char chSave = *pszTag;
|
||
|
*pszTag = '\0';
|
||
|
char szScratch[MAX_URL];
|
||
|
if (!StrChr(pszBeginUrl, CH_COLON)) {
|
||
|
|
||
|
// BUGBUG: This makes it relative to the original HTML file,
|
||
|
// but not necessarily relative to the current file
|
||
|
strcpy(pszFilePortion, pszBeginUrl);
|
||
|
strcpy(szScratch, szCurrentUrl);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// qualify .CHM filespec which will look like: MK@MSITStore:foo.chm::/bar.css
|
||
|
//
|
||
|
CExCollection* pCollection;
|
||
|
CExTitle* pTitle;
|
||
|
HRESULT hr;
|
||
|
|
||
|
if ( (pCollection = GetCurrentCollection(NULL, pszBeginUrl)) )
|
||
|
{
|
||
|
if ( SUCCEEDED(hr = pCollection->URL2ExTitle( pszBeginUrl, &pTitle )) && pTitle )
|
||
|
{
|
||
|
const char* pszPathName;
|
||
|
char* psz;
|
||
|
lstrcpy(szScratch, pszBeginUrl);
|
||
|
if ( (pszPathName = pTitle->GetPathName()) )
|
||
|
{
|
||
|
if ( (psz = StrChr(szScratch, CH_COLON)) )
|
||
|
{
|
||
|
++psz;
|
||
|
strcpy(psz, pszPathName);
|
||
|
if ( (psz = StrStr(pszBeginUrl, "::")) )
|
||
|
strcat(szScratch, psz);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
int diff = (int)(strlen(szScratch) - strlen(pszBeginUrl));
|
||
|
cbFile += diff;
|
||
|
cbFinalLen += diff;
|
||
|
while (cbFinalLen >= (UINT) cbMem) {
|
||
|
int StartDiff = (int)(pszStart - pszMem);
|
||
|
int TagDiff = (int)(pszTag - pszMem);
|
||
|
int BeginDiff = (int)(pszBeginUrl - pszMem);
|
||
|
PSTR pszNew = (PSTR) GlobalReAlloc((HGLOBAL) pszMem, cbMem += FILE_PAD, GMEM_MOVEABLE);
|
||
|
ASSERT(pszNew);
|
||
|
if (!pszNew) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
MsgBox(IDS_OOM);
|
||
|
_lclose(hfDst);
|
||
|
DeleteFile(szHtmlFile);
|
||
|
if (pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
pszMem = NULL;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
pszMem = pszNew;
|
||
|
pszStart = pszMem + StartDiff;
|
||
|
pszTag = pszMem + TagDiff;
|
||
|
pszBeginUrl = pszMem + BeginDiff;
|
||
|
}
|
||
|
MoveMemory(pszTag + diff, pszTag, cbFinalLen - (pszTag - pszMem) - diff);
|
||
|
strcpy(pszBeginUrl, szScratch);
|
||
|
pszTag += diff;
|
||
|
*pszTag = chSave;
|
||
|
}
|
||
|
else if (IsSamePrefix(pszTag, txtFrame, sizeof(txtFrame) - 1)) {
|
||
|
MsgBox(IDS_CANT_PRINT_FRAMESET);
|
||
|
_lclose(hfDst);
|
||
|
DeleteFile(szHtmlFile);
|
||
|
if (pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
pszMem = NULL;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
NoSrcTag:
|
||
|
pszTag++; // skip over the '<'
|
||
|
}
|
||
|
if (_lwrite(hfDst, pszStart, cbFile) != cbFile) {
|
||
|
MsgBox(IDS_INSUFFICIENT_SPACE, szHtmlFile, MB_OK);
|
||
|
_lclose(hfDst);
|
||
|
DeleteFile(szHtmlFile);
|
||
|
}
|
||
|
BadFile:
|
||
|
continue;
|
||
|
}
|
||
|
if (pszMem) {
|
||
|
GlobalFree((HGLOBAL) pszMem);
|
||
|
pszMem = NULL;
|
||
|
}
|
||
|
_lclose(hfDst);
|
||
|
*pm_cszPrintFile = szHtmlFile;
|
||
|
return TRUE;
|
||
|
|
||
|
#if 0
|
||
|
BOOL bReturn = (GetSystemDirectory(m_szPrintFile, _MAX_PATH) > 0);
|
||
|
|
||
|
if (bReturn)
|
||
|
{
|
||
|
StrCat(m_szPrintFile, "\\hhtest.htm");
|
||
|
*pm_cszPrintFile = m_szPrintFile;
|
||
|
|
||
|
HANDLE hFile = CreateFile(m_szPrintFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||
|
|
||
|
if (hFile != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
DWORD dwBytesWritten = 0;
|
||
|
TCHAR szOpenHTML[] = "<HTML>\r\n<BODY>\r\n" \
|
||
|
"<H2>Printing is not currently implemented.</H2>\r\n" \
|
||
|
"<P></P>\r\n" \
|
||
|
"<B>Here is the list of files that you asked to print:</B>\r\n"
|
||
|
"<P></P>\r\n";
|
||
|
WriteFile(hFile, (LPCVOID)szOpenHTML, strlen(szOpenHTML) * sizeof(TCHAR), &dwBytesWritten, NULL);
|
||
|
|
||
|
TCHAR szFile[_MAX_PATH], szFileHTML[_MAX_PATH * 2];
|
||
|
|
||
|
pFileTable->SetPosition();
|
||
|
while (pFileTable->GetString(szFile))
|
||
|
{
|
||
|
wsprintf(szFileHTML, "%s <BR>\r\n", szFile);
|
||
|
WriteFile(hFile, (LPCVOID)szFileHTML, strlen(szFileHTML) * sizeof(TCHAR), &dwBytesWritten, NULL);
|
||
|
}
|
||
|
|
||
|
TCHAR szCloseHTML[] = "<P></P>\r\n" \
|
||
|
"</BODY>\r\n</HTML>\r\n";
|
||
|
WriteFile(hFile, (LPCVOID)szCloseHTML, strlen(szCloseHTML) * sizeof(TCHAR), &dwBytesWritten, NULL);
|
||
|
CloseHandle(hFile);
|
||
|
}
|
||
|
else
|
||
|
bReturn = FALSE;
|
||
|
}
|
||
|
|
||
|
return bReturn;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
BOOL CPrintHook::TranslateUrl(PSTR pszFullUrl, PSTR pszRelUrl)
|
||
|
{
|
||
|
BOOL bReturn;
|
||
|
URL_COMPONENTS uc;
|
||
|
ZERO_STRUCTURE(uc);
|
||
|
|
||
|
uc.dwStructSize = sizeof(URL_COMPONENTS);
|
||
|
uc.dwSchemeLength = 1;
|
||
|
uc.nScheme = INTERNET_SCHEME_DEFAULT ;
|
||
|
uc.dwHostNameLength = 1;
|
||
|
uc.dwUserNameLength = 1;
|
||
|
uc.dwPasswordLength = 1;
|
||
|
uc.dwUrlPathLength = 1;
|
||
|
uc.dwExtraInfoLength = 1;
|
||
|
|
||
|
if ((bReturn = InternetCrackUrl(pszFullUrl, 0, 0, &uc)))
|
||
|
{
|
||
|
uc.lpszUrlPath = pszRelUrl;
|
||
|
uc.dwUrlPathLength = 0;
|
||
|
|
||
|
// Make a copy of uc.lpszExtraInfo because it will
|
||
|
// be lost when InternetCreateUrl() modifies pszFullUrl.
|
||
|
|
||
|
CStr cszExtraInfo(uc.lpszExtraInfo);
|
||
|
|
||
|
uc.lpszExtraInfo = (PSTR)cszExtraInfo;
|
||
|
uc.dwExtraInfoLength = 0;
|
||
|
|
||
|
DWORD dwBufLen = MAX_PATH;
|
||
|
|
||
|
bReturn = InternetCreateUrl(&uc, 0, pszFullUrl, &dwBufLen);
|
||
|
}
|
||
|
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
// This function just tells the WebBrowser to print the current page.
|
||
|
|
||
|
HRESULT CPrintHook::Print()
|
||
|
{
|
||
|
// Change the cursor to an hourglass.
|
||
|
SetClassLongPtr(m_hWndHelp, GCLP_HCURSOR, (LONG_PTR)LoadCursor(NULL, (LPCTSTR) IDC_WAIT));
|
||
|
|
||
|
HRESULT hr = E_FAIL;
|
||
|
HRESULT hrCancelled = (m_fIsIE3 ? 0x80040100 : 0x80040104);
|
||
|
|
||
|
LPOLECOMMANDTARGET lpOleCommandTarget = m_phh->m_pCIExpContainer->m_pIE3CmdTarget;
|
||
|
ASSERT(lpOleCommandTarget);
|
||
|
|
||
|
if (lpOleCommandTarget != NULL)
|
||
|
{
|
||
|
// Give printing 10 tries and then bail out if it doesn't work.
|
||
|
|
||
|
for (USHORT i = 0; i < 10 && FAILED(hr); i++)
|
||
|
{
|
||
|
if (!PumpMessages())
|
||
|
break;
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
try
|
||
|
{
|
||
|
#endif
|
||
|
// Call the Exec() function to print the currently displayed page.
|
||
|
|
||
|
if (m_fIsIE3)
|
||
|
{
|
||
|
hr = lpOleCommandTarget->Exec(NULL,OLECMDID_PRINT,
|
||
|
OLECMDEXECOPT_PROMPTUSER,
|
||
|
NULL, NULL);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = lpOleCommandTarget->Exec(&CGID_MSHTML,IDM_PRINT,
|
||
|
MSOCMDEXECOPT_PROMPTUSER,
|
||
|
NULL, NULL);
|
||
|
}
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
TCHAR szDebug[40];
|
||
|
wsprintf(szDebug, "m_pos == %i, hr == %lx", m_pos, hr);
|
||
|
DBWIN(szDebug);
|
||
|
#endif
|
||
|
#ifdef _DEBUG
|
||
|
}
|
||
|
catch(...)
|
||
|
{
|
||
|
ASSERT_COMMENT(TRUE, "An exception occurred when printing. " \
|
||
|
"Please send email to randyfe or ralphw.");
|
||
|
hr = E_FAIL;
|
||
|
}
|
||
|
#endif
|
||
|
// On IE 4, wait for printing to finish before continuing.
|
||
|
|
||
|
if (!m_fIsIE3)
|
||
|
{
|
||
|
OLECMD olecmd;
|
||
|
olecmd.cmdID = IDM_PRINTQUERYJOBSPENDING;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
DBWIN("Waiting for printing to finish...");
|
||
|
olecmd.cmdf = 0;
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
try
|
||
|
{
|
||
|
#else
|
||
|
if (m_phh && m_phh->m_pCIExpContainer && m_phh->m_pCIExpContainer->m_pIE3CmdTarget)
|
||
|
#endif
|
||
|
m_phh->m_pCIExpContainer->m_pIE3CmdTarget->QueryStatus(&CGID_MSHTML, 1, &olecmd, NULL);
|
||
|
#ifdef _DEBUG
|
||
|
}
|
||
|
catch(...)
|
||
|
{
|
||
|
ASSERT_COMMENT(TRUE, "An exception occurred when waiting for printing to finish. " \
|
||
|
"Please send email to randyfe or ralphw.");
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
PumpMessages();
|
||
|
}
|
||
|
while (olecmd.cmdf & OLECMDF_ENABLED);
|
||
|
}
|
||
|
|
||
|
if (hr == hrCancelled)
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_fIsPrinting = FALSE;
|
||
|
|
||
|
// Change the cursor back to an arrow.
|
||
|
SetClassLongPtr(m_hWndHelp, GCLP_HCURSOR, (LONG_PTR)LoadCursor(NULL, (LPCTSTR) IDC_ARROW));
|
||
|
|
||
|
#ifdef _DEBUG
|
||
|
TCHAR szDebug[50];
|
||
|
wsprintf(szDebug, "Print complete... hr == %lx", hr);
|
||
|
DBWIN(szDebug);
|
||
|
#endif
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
STATIC INT_PTR CALLBACK ProgressDialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||
|
|
||
|
const int DEFAULT_WIDTH = 200;
|
||
|
const int DEFAULT_HEIGHT = 50;
|
||
|
|
||
|
CProgress::CProgress(PCSTR pszCaption, HWND hwndCallersParent, int cSteps,
|
||
|
int cHowOften)
|
||
|
{
|
||
|
cProgress = -1;
|
||
|
steps = cSteps;
|
||
|
cFrequency = cHowOften;
|
||
|
pszTitle = lcStrDup(pszCaption);
|
||
|
fWindowCreationFailed = FALSE;
|
||
|
hwndProgress = NULL;
|
||
|
hwndParent = hwndCallersParent;
|
||
|
hwndFrame = NULL;
|
||
|
|
||
|
dwStartTime = GetTickCount();
|
||
|
|
||
|
counter = 0;
|
||
|
}
|
||
|
|
||
|
CProgress::~CProgress()
|
||
|
{
|
||
|
if (hwndFrame && IsWindow(hwndFrame))
|
||
|
DestroyWindow(hwndFrame);
|
||
|
lcFree(pszTitle);
|
||
|
}
|
||
|
|
||
|
void CProgress::Progress() {
|
||
|
if (++counter == cFrequency) {
|
||
|
counter = 0;
|
||
|
if (hwndProgress)
|
||
|
SendMessage(hwndProgress, PBM_STEPIT, 0, 0);
|
||
|
else {
|
||
|
cProgress++;
|
||
|
if (GetTickCount() - dwStartTime >= 1500)
|
||
|
CreateTheWindow();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CProgress::CreateTheWindow(void)
|
||
|
{
|
||
|
if (fWindowCreationFailed)
|
||
|
return; // couldn't create the window
|
||
|
|
||
|
if (!hwndParent) {
|
||
|
CPalDC dc(SCREEN_IC);
|
||
|
rc.left = dc.GetDeviceWidth() - (DEFAULT_WIDTH / 2);
|
||
|
rc.top = dc.GetDeviceHeight() - (DEFAULT_HEIGHT / 2);
|
||
|
}
|
||
|
else {
|
||
|
RECT rcParent;
|
||
|
GetWindowRect(hwndParent, &rcParent);
|
||
|
rc.left = (RECT_WIDTH(rcParent) / 2) - (DEFAULT_WIDTH / 2);
|
||
|
rc.top = (RECT_HEIGHT(rcParent) / 2) - (DEFAULT_HEIGHT / 2);
|
||
|
}
|
||
|
|
||
|
hwndFrame = CreateDialog(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDDLG_PROGRESS),
|
||
|
hwndParent, ProgressDialogProc);
|
||
|
|
||
|
if (!hwndFrame) {
|
||
|
fWindowCreationFailed = TRUE;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
RECT rcFrame;
|
||
|
GetWindowRect(hwndFrame, &rcFrame);
|
||
|
MoveWindow(hwndFrame, rcFrame.left, rc.top, RECT_WIDTH(rcFrame),
|
||
|
RECT_HEIGHT(rcFrame), FALSE);
|
||
|
|
||
|
hwndProgress = GetDlgItem(hwndFrame, ID_PROGRESS);
|
||
|
if (steps > 0) {
|
||
|
SendMessage(hwndProgress, PBM_SETRANGE, 0, MAKELPARAM(0, steps));
|
||
|
SendMessage(hwndProgress, PBM_SETSTEP, (WPARAM) 1, 0);
|
||
|
}
|
||
|
|
||
|
SetWindowText(hwndFrame, pszTitle);
|
||
|
|
||
|
while (cProgress-- >= 0)
|
||
|
SendMessage(hwndProgress, PBM_STEPIT, 0, 0);
|
||
|
|
||
|
ShowWindow(hwndFrame, SW_SHOW);
|
||
|
}
|
||
|
|
||
|
STATIC INT_PTR CALLBACK ProgressDialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||
|
{
|
||
|
if (msg == WM_INITDIALOG)
|
||
|
return TRUE;
|
||
|
else
|
||
|
return FALSE;
|
||
|
}
|