VC++ 打印类

通过系统提供的打印接口和gdi绘图,实现一个简单的打印类,驱动打印机,可以打印文字,设置文字字体和下划线,用'\n'控制换行。可以在这个基础上添加打印图片、打印一维码和二维码接口。使用如下,

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

类的实现

//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();
}

转载于:https://my.oschina.net/u/221120/blog/649377

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值