📄 cpage.cpp
字号:
#include "stdafx.h"
#include "CPage.h"
////////////////////////////////////////////////////////////////////////////
// Desc: Constructor
// params: RECT ( the area allowed to print to ) CDC* Display context nMapMode the mapping mode
// Returns: nada
///////////////////////////////////////////////////////////////////////////
CPage::CPage(RECT rectDraw, CDC* pDC, int nMapMode)
{
if(nMapMode !=MM_TEXT && nMapMode != MM_ANISOTROPIC)
nMapMode=MM_TEXT;
pDC->SetMapMode(nMapMode );
m_PrtDesc.tm=&tm;
StateInd=-1;
m_PrintMode=GetPrinterMode(pDC);
if(nMapMode==MM_ANISOTROPIC)
{
pDC->SetWindowOrg (0, 0 );
// if you change these numbers you must also change them in maxWidth
// and maxLength for ConvertToMappedUnits() conversion to be correct
pDC->SetWindowExt (1000, 1000 );
pDC->SetViewportOrg (rectDraw.left,rectDraw.top );
pDC->SetViewportExt (rectDraw.right, rectDraw.bottom );
// SEE ABOVE
m_PrtDesc.n_maxWidth=1000;
m_PrtDesc.n_maxLength=1000;
m_PrtDesc.rc.left=0;
m_PrtDesc.rc.top=0;
// SEE ABOVE
m_PrtDesc.rc.right=1000;
m_PrtDesc.rc.bottom=1000;
}
else
{
m_PrtDesc.n_maxWidth=rectDraw.right;
m_PrtDesc.n_maxLength=rectDraw.bottom;
m_PrtDesc.rc.left=rectDraw.left;
m_PrtDesc.rc.top=rectDraw.top;
m_PrtDesc.rc.right=rectDraw.right;
m_PrtDesc.rc.bottom=rectDraw.bottom;
}
// all the textmetrics we need
m_PixPerInchX=pDC->GetDeviceCaps(LOGPIXELSX);
m_PixPerInchY=pDC->GetDeviceCaps(LOGPIXELSY);
// determine how many inches wide and deep the rectangle is
m_WidthInches=rectDraw.right/(double)m_PixPerInchX;
m_LengthInches=rectDraw.bottom/(double)m_PixPerInchY;
m_PrtDesc.pDC=pDC;
// default font stuff
m_PrtDesc.FontName="Times New Roman";
m_PrtDesc.PointSize=10;
m_PrtDesc.m_NextCharPos=0;
// default print flags
m_PrtDesc.uFillFlags=FILL_NONE;
m_PrtDesc.uTextFlags=TEXT_NOCLIP|TEXT_LEFT;
m_PrtDesc.uPenFlags=PEN_SOLID;
// do not change this value
m_PrtDesc.m_MinDisplacement=10;
// modify to increase line spacing but should be no smaller than this
m_Spacing=1.0;
pUserFunc=NULL;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Sets the address of the user supplied function to be
// called for the virtual info printing functions
// params: Pointer to a functio of type PF_REMOTE
// Returns:
///////////////////////////////////////////////////////////////////////////
void CPage::SetUserFunction(PF_REMOTE ptr)
{
pUserFunc=ptr;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Returns the current print mode
// params: The display context* for the output
// Returns: either DMORIENT_LANDSACPE or DMORIENT_PORTRIAT
///////////////////////////////////////////////////////////////////////////
int CPage::GetPrinterMode(CDC* pDC)
{
int Mode;
if(!pDC->IsPrinting())
return 0;
PRINTDLG* pPrintDlg = new PRINTDLG;
AfxGetApp()->GetPrinterDeviceDefaults(pPrintDlg);
DEVMODE* lpDevMode = (DEVMODE*)::GlobalLock(pPrintDlg->hDevMode);
Mode= lpDevMode->dmOrientation;
::GlobalUnlock(pPrintDlg->hDevMode);
delete pPrintDlg;
return Mode;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Destructor deletes the regions from the list if any
// params: None
// Returns: None
///////////////////////////////////////////////////////////////////////////
CPage::~CPage()
{
CPrintRegion* pRegion;
for(int y=0;y < m_RegionList.GetSize();++y)
{
pRegion=(CPrintRegion*)m_RegionList[y];
delete pRegion;
}
m_RegionList.RemoveAll();
}
////////////////////////////////////////////////////////////////////////////
// Desc: Saves the current printer variables to a psuedo stack
// params:
// Returns:
///////////////////////////////////////////////////////////////////////////
void CPage::SaveState()
{
m_SaveState[++StateInd]=m_PrtDesc;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Restores printer variables saved by above
// params:
// Returns:
///////////////////////////////////////////////////////////////////////////
void CPage::RestoreState()
{
if(StateInd==-1)
return;
m_PrtDesc=m_SaveState[StateInd--];
}
////////////////////////////////////////////////////////////////////////////
// PARAMETER ACCESS ROUTINES
////////////////////////////////////////////////////////////////////////////
// Desc: Changes the width of the default allowable printing area
// params: The new right side coordinates in mapping units:If 0 there is no change
// if -1 margin is set to maximum allowable size
// Returns: The previous coordinates
///////////////////////////////////////////////////////////////////////////
int CPage::SetRightMargin(int w)
{
int temp=m_PrtDesc.rc.right;
if(w > 0)
m_PrtDesc.rc.right=w;
if(w==-1)
m_PrtDesc.rc.right=m_PrtDesc.n_maxWidth;
return temp;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Sets new coordinates for allowable printing rectangle depth
// params: The new coordinate in mapping units:If 0 there is no change
// if -1 margin is set to maximum allowable size
// Returns: The old coordinate
///////////////////////////////////////////////////////////////////////////
int CPage::SetBottomMargin(int w)
{
int temp=m_PrtDesc.rc.bottom;
if(w > 0)
m_PrtDesc.rc.bottom=w;
if(w== -1)
m_PrtDesc.rc.right=m_PrtDesc.n_maxLength;
return temp;
}
////////////////////////////////////////////////////////////////////////////
// Desc: See above
// params: Same as above except units are in inches
// Returns: See above
///////////////////////////////////////////////////////////////////////////
double CPage::SetRightMargin(double w)
{
int temp=m_PrtDesc.rc.right;
if(w > 0)
m_PrtDesc.rc.right=ConvertToMappedUnits(w,HORZRES);
if(w==-1)
m_PrtDesc.rc.right=m_PrtDesc.n_maxWidth;
return ConvertToInches(temp,HORZRES);
}
////////////////////////////////////////////////////////////////////////////
// Desc: See Above
// params: Same as above except units are in inches: if 0 no change
// Returns: See Above
///////////////////////////////////////////////////////////////////////////
double CPage::SetBottomMargin(double w)
{
int temp=m_PrtDesc.rc.bottom;
if(w > 0)
m_PrtDesc.rc.bottom=ConvertToMappedUnits(w,VERTRES);
if(w==-1)
m_PrtDesc.rc.right=m_PrtDesc.n_maxLength;
return ConvertToInches(temp,VERTRES);
}
////////////////////////////////////////////////////////////////////////////
// Desc: Changes the space returned for the next logical line
// params: The constant applied to the fontsize to produce the spacing The formula is
// ConvertToMappedUnits(PointSize/72.0,VERTRES)*(m_Spacing-1))
// Returns: The old spacing factor
///////////////////////////////////////////////////////////////////////////
double CPage::SetLineSpacing(double Spacing)
{
double temp=m_Spacing;
if(Spacing > 0)
m_Spacing=Spacing;
return temp;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Changes the font face used for ptinting
// params: The new face name IE Courier
// Returns: he old font face
///////////////////////////////////////////////////////////////////////////
LPCSTR CPage::SetFont(LPCSTR FontName)
{
static char buff[40];
strcpy(buff,m_PrtDesc.FontName);
if(FontName != NULL)
m_PrtDesc.FontName=FontName;
return buff;
}
////////////////////////////////////////////////////////////////////////////
// Desc: Sets The text Color if the device supports colored text
// params: The color
// Returns:The old color
///////////////////////////////////////////////////////////////////////////
COLORREF CPage::SetColor(COLORREF Color)
{
return m_PrtDesc.pDC->SetTextColor(Color);
}
////////////////////////////////////////////////////////////////////////////
// Desc: changes the default font size
// params: the size
// Returns: the old size
///////////////////////////////////////////////////////////////////////////
int CPage::SetFontSize(int sz)
{
int temp=m_PrtDesc.PointSize;
m_PrtDesc.PointSize=sz;
return temp;
}
////////////////////////////////////////////////////////////////////////////
// Desc: fetch the display context used by this object
// params:
// Returns: a pointer to the display context
///////////////////////////////////////////////////////////////////////////
CDC* CPage::GetDisplayContext()
{
return m_PrtDesc.pDC;
}
////////////////////////////////////////////////////////////////////////////
// Desc: returns the next logical print column. Used in printing continious text that
// may have different text attributes
// params:Convert flag to convert to inches.AddOffset flag add a extra space
// Returns: the logical column offset.double is used so it can handle all mapping units.
// if Convert is true the result is in inches else in device units.
///////////////////////////////////////////////////////////////////////////
double CPage::GetNextLogicalColumn(BOOL Convert,BOOL AddOffset)
{
if(Convert==FALSE)
{
if(AddOffset)
return m_nNextPos+tm.tmMaxCharWidth;
else
return m_nNextPos;
}
else
{
if(AddOffset)
return ConvertToInches(m_nNextPos+tm.tmMaxCharWidth,HORZRES);
else
return ConvertToInches(m_nNextPos,HORZRES);
}
}
////////////////////////////////////////////////////////////////////////////
// UNIT CONVERSION ROUTINES
////////////////////////////////////////////////////////////////////////////
// Desc: Converts inches to physical units based on the mapping mode
// params: dwInch ( the number of inches bWidth either VERTRES or HORTZRES
// Returns: the physical device displacment representing the number of inches
//
// conversion is done as follows:mapmode=MM_TEXT;
// The number of inches are multiplied by the constant for the # of pixels per inch
// in the diminsion requested.The value(s) for the # of pixels are set at creation
// of the object and are retrieved from the GetDevCaps function
// mapmode=MM_ANISOTROPIC:
// The size in inches for the requested diminsion are devided by 1000 to get the
// size in inches for each unit. This value is devided into the requested size
// to return the physical offset, for example
// width of display is 10 in
// 10/1000=.01. So we want to go three inches to the right 3.0/.01=300 logical
// units
// hight of display is 12 in
// 12/1000=.012. To move 5 inches down 5.0/.012=417 logical units
// NOTES:
// These conversion routines attempt to normalize positioning between the two allowed
// mapping modes but are not exact due to cumalitive rounding errors.While in MM_TEXT
// mode the units will be much smaller than in MM_ANISOTROPIC mode and therefore the
// class can position the text with a much finer position. When in ANISOTROPIC mode
// the smallest unit can be as much as 2.8 pixels per unit resulting in small but
// noticable differences in positioning
///////////////////////////////////////////////////////////////////////////
int CPage::ConvertToMappedUnits(double dwInch,int bWidth)
{
double tempx,tempy;
if(dwInch <=0)
return 0;
if(m_PrtDesc.pDC->GetMapMode()==MM_TEXT)
{
if(bWidth==HORZRES)
return (int)(dwInch*m_PixPerInchX);
else
return (int)(dwInch*m_PixPerInchY);
}
tempx=m_WidthInches/m_PrtDesc.n_maxWidth;
tempy=m_LengthInches/m_PrtDesc.n_maxLength;
if(bWidth==HORZRES)
return (int)(dwInch/tempx);
else
return (int)(dwInch/tempy);
}
////////////////////////////////////////////////////////////////////////////
// Desc: Converts physical device units to inches
// params: value ( the # of physical units to convert bWidth HORZRES or VERTRES
// Returns: The number of inches defined by the displacment
///////////////////////////////////////////////////////////////////////////
double CPage::ConvertToInches(int value,int bWidth)
{
double tempx,tempy;
if(value <=0)
return 0;
if(m_PrtDesc.pDC->GetMapMode()==MM_TEXT)
{
if(bWidth==HORZRES)
return ((double)value/(double)m_PixPerInchX);
else
return ((double)value/(double)m_PixPerInchY);
}
tempx=m_WidthInches/(double)m_PrtDesc.n_maxWidth;
tempy=m_LengthInches/(double)m_PrtDesc.n_maxLength;
if(bWidth==HORZRES)
return (double)(value*tempx);
else
return (double)(value*tempy);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -