經過系統提供的打印接口和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(); }