📄 htmlprint.cpp
字号:
/*----------------------------------------------------------------------
Copyright (c) 1998 Gipsysoft. All Rights Reserved.
Please see the file "licence.txt" for licencing details.
File:
Owner: rich@woodbridgeinternalmed.com
Purpose: Quick HTM print interface
----------------------------------------------------------------------*/
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <LIMITS.H>
#include "Defaults.h"
#include "QHTM.h"
#include "HtmlSection.h"
#include "QHTM_Includes.h"
#pragma warning( disable : 4100 ) // unreferenced formal parameter
// The actual structure referred to by the QHTMCONTEXT is private to this
// module. We should be checking that the context truly exists. They can be stored
// in an map for this purpose.
#ifdef QHTM_ALLOW_PRINT
struct CQHTMPrintContext
{
CHTMLSection m_htmlSection; // The section that does the work
CRect m_rcLayout; // The rect used to layout the data
UINT m_nPages; // Number of pages
UINT m_uZoomLevel; // HTML zoom level
int m_cxDeviceScaleNumer, m_cxDeviceScaleDenom;
int m_cyDeviceScaleNumer, m_cyDeviceScaleDenom;
CQHTMPrintContext( UINT uZoomLevel ) : m_htmlSection( NULL, &g_defaults) ,m_uZoomLevel(uZoomLevel) { m_htmlSection.SetZoomLevel( m_uZoomLevel ); }
private:
CQHTMPrintContext(const CQHTMPrintContext& );
CQHTMPrintContext &operator =( const CQHTMPrintContext &);
};
static MapClass< QHTMCONTEXT, CQHTMPrintContext* > g_mapPrintContext;
#endif // QHTM_ALLOW_PRINT
// Call this to create a new print context
QHTMCONTEXT WINAPI QHTM_PrintCreateContext( UINT uZoomLevel )
{
if( uZoomLevel > QHTM_ZOOM_MAX )
uZoomLevel = QHTM_ZOOM_MAX;
if( uZoomLevel < QHTM_ZOOM_MIN )
uZoomLevel = QHTM_ZOOM_MIN;
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext* ctxNew = new CQHTMPrintContext( uZoomLevel );
if (ctxNew)
{
QHTMCONTEXT ctx = (QHTMCONTEXT)ctxNew;
g_mapPrintContext.SetAt(ctx, ctxNew);
return ctx;
}
else
#endif //QHTM_ALLOW_PRINT
return (QHTMCONTEXT)0;
}
// Call this to destroy a print context
BOOL WINAPI QHTM_PrintDestroyContext( QHTMCONTEXT ctx )
{
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext** ppctx = g_mapPrintContext.Lookup( ctx );
if (ppctx)
{
delete *ppctx;
g_mapPrintContext.RemoveAt( ctx );
return TRUE;
}
else
#endif // QHTM_ALLOW_PRINT
return FALSE;
}
// Call this to set the HTML
BOOL WINAPI QHTM_PrintSetText( QHTMCONTEXT ctx, LPCTSTR pcszText )
{
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext** ppctx = g_mapPrintContext.Lookup( ctx );
if (ppctx)
{
(*ppctx)->m_htmlSection.SetHTML( pcszText, lstrlen( pcszText ), NULL );
return TRUE;
}
else
#endif // QHTM_ALLOW_PRINT
return FALSE;
}
// Call this to layout the HTML. Returns the number of pages in nPages
BOOL WINAPI QHTM_PrintLayout( QHTMCONTEXT ctx, HDC hDC, LPCRECT pRect, LPINT nPages )
{
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext** ppctx = g_mapPrintContext.Lookup( ctx );
if (ppctx)
{
CQHTMPrintContext & ctx = *(*ppctx);
ctx.m_rcLayout = *pRect;
ctx.m_rcLayout.Offset( -ctx.m_rcLayout.left, -ctx.m_rcLayout.top );
HDC screenDC = ::GetDC(g_hwnd);
ctx.m_cxDeviceScaleNumer = ::GetDeviceCaps(hDC, LOGPIXELSX);
ctx.m_cxDeviceScaleDenom = ::GetDeviceCaps(screenDC, LOGPIXELSX);
ctx.m_cyDeviceScaleNumer = ::GetDeviceCaps(hDC, LOGPIXELSY);
ctx.m_cyDeviceScaleDenom = ::GetDeviceCaps(screenDC, LOGPIXELSY);
::ReleaseDC(g_hwnd, screenDC);
CDrawContext dc( NULL, hDC, true );
dc.SetScaling( ctx.m_cxDeviceScaleNumer, ctx.m_cxDeviceScaleDenom, ctx.m_cyDeviceScaleNumer, ctx.m_cyDeviceScaleDenom );
ctx.m_htmlSection.OnLayout( ctx.m_rcLayout, dc );
ctx.m_nPages = *nPages = ctx.m_htmlSection.Paginate( ctx.m_rcLayout );
return TRUE;
}
else
#endif // QHTM_ALLOW_PRINT
return FALSE;
}
BOOL WINAPI QHTM_PrintSetTextResource( QHTMCONTEXT ctx, HINSTANCE hInst, LPCTSTR pcszName )
{
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext** ppctx = g_mapPrintContext.Lookup( ctx );
if (ppctx)
{
if( (*ppctx)->m_htmlSection.SetHTML( hInst, pcszName ) )
{
return TRUE;
}
}
#endif // QHTM_ALLOW_PRINT
return FALSE;
}
BOOL WINAPI QHTM_PrintSetTextFile( QHTMCONTEXT ctx, LPCTSTR pcszFilename )
{
BOOL bRetVal = FALSE;
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext** ppctx = g_mapPrintContext.Lookup( ctx );
if (ppctx)
{
CHTMLSection* pSection = &(*ppctx)->m_htmlSection;
TCHAR drive[_MAX_DRIVE];
TCHAR dir[_MAX_DIR];
TCHAR fname[_MAX_FNAME];
TCHAR ext[_MAX_EXT];
_tsplitpath( pcszFilename, drive, dir, fname, ext );
TCHAR path_buffer[_MAX_PATH];
_tmakepath( path_buffer, drive, dir, NULL, NULL );
FILE *pFile = _tfopen( pcszFilename, _T("rb") );
if( pFile )
{
fpos_t pos;
if( !fseek( pFile, 0, SEEK_END ) && !fgetpos( pFile, &pos ) && !fseek( pFile, 0, SEEK_SET ) )
{
UINT uLength = static_cast<UINT>( pos );
char * pszHTML = reinterpret_cast<char *>( malloc( uLength + 1 ) );
if( pszHTML )
{
if( fread( reinterpret_cast<void*>(pszHTML), uLength, 1, pFile ) )
{
pszHTML[ uLength ] = _T('\000');
#ifdef _UNICODE
LPTSTR pszHTML2 = reinterpret_cast<LPTSTR>( malloc( uLength * sizeof( TCHAR ) + 1 ) );
MultiByteToWideChar(CP_ACP, 0, pszHTML, uLength, pszHTML2, uLength * sizeof( TCHAR ) );
LPTSTR pszText = pszHTML2;
#else // _UNICODE
LPTSTR pszText = pszHTML;
#endif // _UNICODE
pSection->SetHTML( pszText, uLength, path_buffer );
#ifdef _UNICODE
free( pszHTML2 );
#endif // _UNICODE
bRetVal = TRUE;
}
free( pszHTML );
}
}
fclose( pFile );
}
}
#endif // QHTM_ALLOW_PRINT
return bRetVal;
}
BOOL WINAPI QHTM_PrintPage( QHTMCONTEXT ctx, HDC hDC, UINT nPage, LPCRECT rDest)
{
#ifdef QHTM_ALLOW_PRINT
CQHTMPrintContext** ppctx = g_mapPrintContext.Lookup( ctx );
if (ppctx)
{
CQHTMPrintContext & ctx = *(*ppctx);
// Validate page number
if( nPage >= ctx.m_nPages )
return FALSE;
// Prevent background painting.
ctx.m_htmlSection.Transparent( true );
// Get the page rect (clip rect)
CRect rcPage = ctx.m_htmlSection.GetPageRect( nPage );
// The dest rect maps to the rect rcPage.
// Ensure that the cliprect matches the minimum of rcPage, rcDest
// In this mode, we are always printing from top,left
CRect rcClip( rcPage );
// If this rect is taller or wider than rcPage, trim it
if( rcClip.Height() > rcPage.Height() )
rcClip.bottom = rcClip.top + rcPage.Height();
if( rcClip.Width() > rcPage.Width() )
rcClip.right = rcClip.left + rcPage.Width();
// Scroll the document so that 0,0 points to the top left
// of the clipRect
// Scroll the document...
ctx.m_htmlSection.SetPosAbsolute(rcPage.left, rcPage.top);
// Handle the case where the destination is not top/left
POINT oldWindowOrg;
VAPI( ::SetWindowOrgEx( hDC, -rDest->left, -rDest->top, &oldWindowOrg ) );
rcClip.Offset(-rcClip.left, -rcClip.top); // Move to 0,0
CDrawContext dc( &rcClip, hDC, true );
dc.SetScaling( ctx.m_cxDeviceScaleNumer, ctx.m_cxDeviceScaleDenom, ctx.m_cyDeviceScaleNumer, ctx.m_cyDeviceScaleDenom );
// Do the printing
ctx.m_htmlSection.OnDraw( dc );
// Restore context
VAPI( ::SetWindowOrgEx( hDC, oldWindowOrg.x, oldWindowOrg.y, NULL ) );
//
return TRUE;
}
else
#endif // QHTM_ALLOW_PRINT
return FALSE;
}
int WINAPI QHTM_PrintGetHTMLHeight( HDC hDC, LPCTSTR pcszText, int nMaxWidth, UINT uZoomLevel )
{
if( uZoomLevel > QHTM_ZOOM_MAX )
uZoomLevel = QHTM_ZOOM_MAX;
if( uZoomLevel < QHTM_ZOOM_MIN )
uZoomLevel = QHTM_ZOOM_MIN;
int nHeight = -1;
#ifdef QHTM_ALLOW_PRINT
if( hDC && pcszText && nMaxWidth )
{
CHTMLSection htmlSection( NULL, &g_defaults );
htmlSection.SetZoomLevel( uZoomLevel );
htmlSection.SetHTML( pcszText, lstrlen( pcszText ), NULL );
CRect rc( 0, 0, nMaxWidth, INT_MAX );
HDC screenDC = ::GetDC(g_hwnd);
int cxDeviceScaleNumer = ::GetDeviceCaps(hDC, LOGPIXELSX);
int cxDeviceScaleDenom = ::GetDeviceCaps(screenDC, LOGPIXELSX);
int cyDeviceScaleNumer = ::GetDeviceCaps(hDC, LOGPIXELSY);
int cyDeviceScaleDenom = ::GetDeviceCaps(screenDC, LOGPIXELSY);
::ReleaseDC(g_hwnd, screenDC);
CDrawContext dc( NULL, hDC, true );
dc.SetScaling( cxDeviceScaleNumer, cxDeviceScaleDenom, cyDeviceScaleNumer, cyDeviceScaleDenom );
htmlSection.OnLayout( rc, dc );
nHeight = htmlSection.GetSize().cy;
}
#endif // QHTM_ALLOW_PRINT
return nHeight;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -