📄 print.cpp
字号:
/*
* PRINT.CPP
* Patron Chapter 7
*
* Implementation of printing functions for both CPatronDoc
* and CPages classes. These functions are here to keep clutter
* down in document.cpp and pages.cpp.
*
* Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Microsoft
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
static HWND g_hDlgPrint=NULL;
static BOOL g_fCancelPrint=FALSE;
/*
* CPatronDoc::Print
*
* Purpose:
* Prints the current document.
*
* Parameters:
* hWndFrame HWND of the frame to use for dialog parents.
*
* Return Value:
* BOOL TRUE if printing happened, FALSE if it didn't
* start or didn't complete.
*/
BOOL CPatronDoc::Print(HWND hWndFrame)
{
PRINTDLG pd;
BOOL fSuccess;
memset(&pd, 0, sizeof(PRINTDLG));
pd.lStructSize=sizeof(PRINTDLG);
pd.hwndOwner =hWndFrame;
pd.nCopies =1;
pd.nFromPage =(USHORT)-1;
pd.nToPage =(USHORT)-1;
pd.nMinPage =1;
pd.nMaxPage =m_pPG->NumPagesGet();
pd.lpfnPrintHook=PrintDlgHook;
//Get the current document printer settings
pd.hDevMode=m_pPG->DevModeGet();
pd.Flags=PD_RETURNDC | PD_ALLPAGES | PD_COLLATE
| PD_HIDEPRINTTOFILE | PD_NOSELECTION | PD_ENABLEPRINTHOOK;
if (!PrintDlg(&pd))
return FALSE;
if (NULL!=pd.hDevMode)
GlobalFree(pd.hDevMode);
if (NULL!=pd.hDevNames)
GlobalFree(pd.hDevNames);
//Go do the actual printing.
fSuccess=m_pPG->Print(pd.hDC, PSZ(IDS_DOCUMENTNAME), pd.Flags
, pd.nFromPage, pd.nToPage, pd.nCopies);
if (!fSuccess)
{
MessageBox(m_hWnd, PSZ(IDS_PRINTERROR)
, PSZ(IDS_DOCUMENTCAPTION), MB_OK);
}
return fSuccess;
}
/*
* CPatronDoc::PrinterSetup
*
* Purpose:
* Selects a new printer and options for this document.
*
* Parameters:
* hWndFrame HWND of the frame to use for dialog parents.
* fDefault BOOL to avoid any dialog and just use the
* default.
*
* Return Value:
* UINT Undefined
*/
UINT CPatronDoc::PrinterSetup(HWND hWndFrame, BOOL fDefault)
{
PRINTDLG pd;
//Attempt to get printer metrics for the default printer.
memset(&pd, 0, sizeof(PRINTDLG));
pd.lStructSize=sizeof(PRINTDLG);
if (fDefault)
pd.Flags=PD_RETURNDEFAULT;
else
{
pd.hwndOwner=hWndFrame;
pd.Flags=PD_PRINTSETUP;
//Get the current document printer settings
pd.hDevMode=m_pPG->DevModeGet();
}
if (!PrintDlg(&pd))
return FALSE;
if (!m_pPG->DevModeSet(pd.hDevMode, pd.hDevNames))
{
GlobalFree(pd.hDevNames);
GlobalFree(pd.hDevMode);
return FALSE;
}
FDirtySet(TRUE);
return 1;
}
/*
* PrintDlgHook
*
* Purpose:
* Callback hook for the Print Dialog so we can hide the Setup
* button. Patron only allows Setup before anything exists on
* the page, and is not written to handle setup at Print time.
*/
UINT CALLBACK PrintDlgHook(HWND hDlg, UINT iMsg, WPARAM wParam
, LPARAM lParam)
{
if (WM_INITDIALOG==iMsg)
{
HWND hWnd;
hWnd=GetDlgItem(hDlg, psh1);
ShowWindow(hWnd, SW_HIDE);
return TRUE;
}
return FALSE;
}
/*
* CPages::DevModeSet
*
* Purpose:
* Provides the Pages with the current printer information.
*
* Parameters:
* hDevMode HGLOBAL to the memory containing the DEVMODE.
* This function assumes responsibility for this
* handle.
* hDevNames HGLOBAL providing the driver name and device
* name from which we can create a DC for
* information.
*
* Return Value:
* BOOL TRUE if we could accept this configuration,
* FALSE otherwise. If we return TRUE we also
* delete the old memory we hold.
*/
BOOL CPages::DevModeSet(HGLOBAL hDevMode, HGLOBAL hDevNames)
{
LPDEVNAMES pdn;
LPTSTR psz;
//CHAPTER7MOD
HGLOBAL hMem;
PDEVICECONFIG pdc;
LPDEVMODE pdm;
LPSTREAM pIStream;
HRESULT hr;
ULONG cbDevMode, cbWrite;
BOOL fRet=FALSE;
if (NULL==hDevMode || NULL==hDevNames)
return FALSE;
hr=m_pIStorage->OpenStream(SZSTREAMDEVICECONFIG, 0, STGM_DIRECT
| STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
if (FAILED(hr))
return FALSE;
/*
* DEVMODE is variable length--total length in hDevMode, so the
* amount to write is that plus string space. We subtract
* sizeof(DEVMODE) as that is already included from GlobalSize.
*/
cbDevMode=GlobalSize(hDevMode);
cbWrite=cbDevMode+sizeof(DEVICECONFIG)-sizeof(DEVMODE);
hMem=GlobalAlloc(GHND, cbWrite);
if (NULL==hMem)
{
pIStream->Release();
return FALSE;
}
pdc=(PDEVICECONFIG)GlobalLock(hMem); //This always works
pdm=(LPDEVMODE)GlobalLock(hDevMode); //This might not
if (NULL!=pdm)
{
pdc->cb=cbWrite;
pdc->cbDevMode=cbDevMode;
memcpy(&pdc->dm, pdm, (int)cbDevMode);
GlobalUnlock(hDevMode);
psz=(LPTSTR)GlobalLock(hDevNames);
if (NULL!=psz)
{
pdn=(LPDEVNAMES)psz;
lstrcpy(pdc->szDriver, psz+pdn->wDriverOffset);
lstrcpy(pdc->szDevice, psz+pdn->wDeviceOffset);
lstrcpy(pdc->szPort, psz+pdn->wOutputOffset);
pIStream->Write(pdc, cbWrite, &cbWrite);
GlobalUnlock(hDevNames);
fRet=TRUE;
}
}
GlobalUnlock(hMem);
GlobalFree(hMem);
pIStream->Release();
if (!fRet)
return FALSE;
GlobalFree(hDevNames);
GlobalFree(hDevMode);
//End CHAPTER7MOD
return ConfigureForDevice();
}
/*
* CPages::DevModeGet
*
* Purpose:
* Retrieves a copy of the current DEVMODE structure for this
* Pages window. The caller is responsible for this memory.
*
* Parameters:
* None
*
* Return Value:
* HGLOBAL Handle to the memory containing the DEVMODE
* structure.
*/
HGLOBAL CPages::DevModeGet(void)
{
//CHAPTER7MOD
HGLOBAL hMem;
LPVOID pv;
ULONG cbDevMode, cbRead;
LARGE_INTEGER li;
LPSTREAM pIStream;
HRESULT hr;
hr=m_pIStorage->OpenStream(SZSTREAMDEVICECONFIG, 0, STGM_DIRECT
| STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
if (FAILED(hr))
return FALSE;
//Read how much to allocate for the DEVMODE structure
LISet32(li, CBSEEKOFFSETCBDEVMODE);
pIStream->Seek(li, STREAM_SEEK_SET, NULL);
pIStream->Read(&cbDevMode, sizeof(ULONG), &cbRead);
hMem=GlobalAlloc(GHND, cbDevMode);
if (NULL!=hMem)
{
pv=(LPVOID)GlobalLock(hMem);
pIStream->Read(pv, cbDevMode, &cbRead);
GlobalUnlock(hMem);
}
pIStream->Release();
//End CHAPTER7MOD
return hMem;
}
/*
* CPages::ConfigureForDevice
*
* Purpose:
* Recalculates our drawing configuration based on the contents of
* an hDC. If no HDC is given we use the contents of our DevMode
* stream.
*
* Parameters:
* None
*
* Return Value:
* BOOL TRUE if successful, FALSE otherwise.
*/
BOOL CPages::ConfigureForDevice(void)
{
POINT ptOffset, ptPaper;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -