VC++ 打印類

經過系統提供的打印接口和gdi繪圖,實現一個簡單的打印類,驅動打印機,能夠打印文字,設置文字字體和下劃線,用'\n'控制換行。能夠在這個基礎上添加打印圖片、打印一維碼和二維碼接口。使用以下,字體

CSystemPrinter Printer;
Printer.StartPrint();
//打印操做,PrintString() or DrawUnderLine();
//以‘\n’結束一行。
Printer.EndPrint();

類的實現code

//CSystemPrinter.h

#ifdef __CSYSTEMPRINTER_H__
#define __CSYSTEMPRINTER_H__

//define font param
/*nWeight range in:
*#define FW_DONTCARE         0
#define FW_THIN             100
#define FW_EXTRALIGHT       200
#define FW_LIGHT            300
#define FW_NORMAL           400
#define FW_MEDIUM           500
#define FW_SEMIBOLD         600
#define FW_BOLD             700
#define FW_EXTRABOLD        800
#define FW_HEAVY            900

#define FW_ULTRALIGHT       FW_EXTRALIGHT
#define FW_REGULAR          FW_NORMAL
#define FW_DEMIBOLD         FW_SEMIBOLD
#define FW_ULTRABOLD        FW_EXTRABOLD
#define FW_BLACK            FW_HEAVY
*/
typedef struct _tagFontParam
{
    int nWidth;
    int nHeight;
    int nWeight;
    bool bItalic;
    bool bUnderLine;
    LPCTSTR szFontName;
    _tagFontParam()
    {
    nWidth=20;
    nHeight=30;
    nWeight=FW_THIN;
    bItalic=false;
    bUnderLine=false;
    szFontName=_T("宋體");
    }
}FontParam;

typedef struct _tagPoint2f
{
    double x;
    double y;
    Point2f()
    {
        x=0.0;
        y=0.0;
    }
}Point2f;

class CSystemPrinter
{
public:
CSystemPrinter();
~CSystemPrinter();
protected:
CDC m_PrtDC;
FontParam m_fontParam;
LPCTSTR m_szDocName;
Point2f m_ptInitPos,m_ptCurrentPos;//初始座標,和目前所在的座標
SHORT m_nPageWidth;
    SHORT m_nPageLength;
protected:
double Cm2UnitH(float yScale, double h);//物理長度轉換爲設備長度,高cm-->pix
double Cm2UnitW(float xScale, double w);//寬cm-->pix
double RvtCm2UnitH(float yScale, double h);//設備長度轉換爲物理長度
double RvtCm2UnitW(float xScale, double w);
float GetXScale() ;//水平方向比例
float GetYScale() ;//垂直方向比例
CSize getCharSize();//獲得字尺寸
double getTextLength(LPCTSTR szText);//獲得字符串的物理寬度
void DrawUnderLine(double xCm,double yCm,double lineWidth=3.5);//畫下劃線
public:

int GetFontWidth(){return m_fontParam.nWidth;}
void SetFontWidth(int nWidth){m_fontParam.nWidth=nWidth;}

int GetFontHeight(){return m_fontParam.nHeight;}
void SetFontHeight(int nHeight){m_fontParam.nHeight=nHeight;}

void SetFontWeight(int nWeight){m_fontParam.nWeight=nWeight;}
void SetItalic(bool bSet){m_fontParam.bItalic=bSet;}
void SetUnderLine(bool bSet){m_fontParam.bUnderLine=bSet;}
void SetFontFontName(LPCTSTR szFontName){m_fontParam.szFontName=szFontName;}
void SetDocName(LPCTSTR szDocName){m_szDocName=szDocName;}

int StartPrint();
void EndPrint();

void PrintString(double xCm,double yCm,LPCSTR szPrintTxt,int nLineHeight=1,bool bCenterAlign=false);
    
void SetInitPos(double dX,double dy);
    void SetPrintRect(SHORT nPageWidth,SHORT nPageHeight);

Point2f GetCurrentPos(){return m_ptCurrentPos;}
};
#endif
//CSystemPrinter.cpp

CSystemPrinter::CSystemPrinter()
{

}
CSystemPrinter::~CSystemPrinter()
{

}

double CSystemPrinter::Cm2UnitH(float yScale, double h)
{
return h*100/yScale;
}
double CSystemPrinter::Cm2UnitW(float xScale, double w)
{
return w*100/xScale;
}
double CSystemPrinter::RvtCm2UnitH(float yScale, double h)
{
return h*yScale/100;
}
double CSystemPrinter::RvtCm2UnitW(float xScale, double w)
{
return w*xScale/100;
}

float CSystemPrinter::GetXScale()
{
//獲得打印機水平方向的DPI
int xDPI = GetDeviceCaps(m_PrtDC.GetSafeHdc(), LOGPIXELSX);
//254.0: 每英寸25.4毫米
return (float)(254.0 / xDPI);
}
float CSystemPrinter::GetYScale()
{
int yDPI = GetDeviceCaps(m_PrtDC.GetSafeHdc(), LOGPIXELSY);

return (float)(254.0 / yDPI);
}

CSize CSystemPrinter::GetCharSize()
{
  return m_PrtDC.GetTextExtent(_T("A"), 1);
}

double CSystemPrinter::GetTextLength(LPCTSTR szText)
{
CString strText=szText;
CFont font;
font.CreateFont(m_fontParam.nHeight,m_fontParam.nWidth,
0,0,m_fontParam.nWeight,
m_fontParam.bItalic,m_fontParam.bUnderLine,false,
CHINESEBIG5_CHARSET,OUT_CHARACTER_PRECIS,
CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
FF_MODERN,m_fontParam.szFontName);
CFont *oldFont=m_PrtDC.SelectObject(&font);
int dis=strText.GetLength()*GetCharSize(m_PrtDC).cx;

float xScale=GetXScale(m_PrtDC.GetSafeHdc());
double szLen=RvtCm2UnitW(xScale,dis);
m_PrtDC.SelectObject(oldFont);
font.DeleteObject();

return szLen;
}

void CSystemPrinter::DrawUnderLine(double xCm,double yCm,double lineWidth=3.5)
{
float xScale=GetXScale(m_PrtDC.GetSafeHdc());
float yScale=GetYScale(m_PrtDC.GetSafeHdc());
double x=Cm2UnitW(xScale,xCm);//物理尺寸轉換爲設備尺寸pix
double y=Cm2UnitH(yScale,yCm);
int width=Cm2UnitW(xScale,lineWidth);//線的長度
//int penWidth=2;
CPen pen(PS_SOLID,5,RGB(0,0,0));
CPen *pOldPen=m_PrtDC.SelectObject(&pen);
m_PrtDC.MoveTo(x,y);
m_PrtDC.LineTo(width,y);
m_PrtDC.SelectObject(pOldPen);
m_ptCurrentPos.x=RvtCm2UnitW(xScale,x);
m_ptCurrentPos.y+=RvtCm2UnitH(yScale,lineWidth);//從新計算行的位置

}

void  CSystemPrinter::SetInitPos(double dX,double dy)
{
   m_ptInitPos.x=dX;
   m_ptInitPos.y=dy;
}  

void CSystemPrinter::SetPrintRect(SHORT nPageWidth,SHORT nPageLength)
{
m_nPageWidth=nPageWidth;
m_nPageLength=nPageLength;
   
}

int CSystemPrinter::StartPrint()
{
CPrintDialog printDlg(FALSE/*,dwflags,NULL*/);
printDlg.GetDefaults();
LPDEVMODE dev      = printDlg.GetDevMode();
dev->dmPaperSize=DMPAPER_USER; //用戶自定義紙張大小
dev->dmPaperLength=m_nPageLength*10;
dev->dmPaperWidth=m_nPageWidth*10;
dev->dmOrientation=DMORIENT_PORTRAIT;//橫向打印
dev->dmScale=100;
dev->dmFields |= DM_PAPERSIZE | DM_PAPERWIDTH 
| DM_PAPERLENGTH|DM_ORIENTATION|DM_SCALE;
HDC hPrintDc=printDlg.GetPrinterDC();
if (hPrintDc==NULL)
{
AfxMessageBox(_T("No Printer!"));
return -1;

}
m_PrtDC.Attach(hPrintDc);
m_PrtDC.ResetDC(dev);
m_PrtDC.m_bPrinting=TRUE;

DOCINFO docInfo;
memset(&docInfo, 0, sizeof(docInfo));
docInfo.cbSize = sizeof(docInfo);
docInfo.lpszDocName=m_szDocName;
if (m_PrtDC.StartDoc(&docInfo) < 0)
{
AfxMessageBox(_T("Printer wouldn't initalize"));
return -1;
}
else
{
if (m_PrtDC.StartPage() < 0)
{
AfxMessageBox(_T("Could not start page"));
m_PrtDC.AbortDoc();
return -1;
}
return 0;
}


}

void CSystemPrinter::EndPrint()
{
ASSERT(m_PrtDC.m_hDC!=NULL);
m_PrtDC.EndPage();
m_PrtDC.EndDoc();
}

void CSystemPrinter::PrintString(double xCm,double yCm,LPCSTR szPrintTxt,int nLineHeight,bool bCenterAlign)
{
CString szPrintText=szPrintTxt;
CFont font;
font.CreateFont(m_fontParam.nHeight,m_fontParam.nWidth,
0,0,m_fontParam.nWeight,
m_fontParam.bItalic,m_fontParam.bUnderLine,false,
GB2312_CHARSET,OUT_CHARACTER_PRECIS,
CLIP_CHARACTER_PRECIS,DEFAULT_QUALITY,
FF_MODERN,m_fontParam.szFontName);
CFont *oldFont=m_PrtDC.SelectObject(&font);

m_PrtDC.SetTextAlign(TA_BOTTOM | TA_LEFT);//設置對齊方式

CSize charSize=GetCharSize(m_PrtDC);//字體尺寸
int textHight=charSize.cy;//字高行距行距
int textWidth=charSize.cx;//字寬

float xScale=GetXScale(m_PrtDC.GetSafeHdc());
float yScale=GetYScale(m_PrtDC.GetSafeHdc());
double x=Cm2UnitW(xScale,xCm);//物理尺寸轉換爲設備尺寸(像素)
double y=Cm2UnitH(yScale,yCm);
if (bCenterAlign)//中心對齊
{
double lenCm=GetTextLength(m_PrtDC,m_fontParam,strPrintTxt);//字體長度物理尺寸
double len=Cm2UnitW(xScale,lenCm);//轉換爲像素
int leftMargin=GetDeviceCaps(m_PrtDC.GetSafeHdc(), PHYSICALOFFSETX );//邊距
int width=GetDeviceCaps(m_PrtDC.GetSafeHdc(),HORZRES);//dc 寬度
x=(width-leftMargin-len)/2;//中心座標
}
int nIndex=-1;
while (TRUE)                  //
{  
nIndex = szPrintText.Find(_T("\n"));
if (nIndex>-1)
{
CString strPrint = szPrintText.Left(nIndex);  
CString strMessage = szPrintText.Mid(nIndex+1); 
m_PrtDC.TextOut(x,y,strPrint);
y += nLineHeight*textHight;       //下移一行,行高爲字體高度
szPrintText=strMessage;
}
else
{
m_PrtDC.TextOut(x,y,szPrintText);
m_ptCurrentPos.x=RvtCm2UnitW(xScale,x);
m_ptCurrentPos.y=RvtCm2UnitH(yScale,y);
break;
}

}
m_PrtDC.SelectObject(oldFont);
font.DeleteObject();
}
相關文章
相關標籤/搜索