文档章节

VC++ 打印类

Ne0o0
 Ne0o0
发布于 2016/03/29 17:21
字数 1024
阅读 50
收藏 2

通过系统提供的打印接口和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();
}

© 著作权归作者所有

共有 人打赏支持
Ne0o0
粉丝 2
博文 68
码字总数 28287
作品 0
程序员
2016-2017学年第二学期C++第二章

C++ 上机课参考答案 本系列文章供北京邮电大学信通院及数媒学院「C++高级程序语言设计」上机课学生参考。 C 上机课参考答案 2016-2017学年第二学期C++第二章 1489.VC++实验2.1 字母大小写转换...

u013594828
2017/04/30
0
0
iOS Debuger(便捷辅助调试器)

前言 首先写这篇文章之前祝大家周末愉快,然后自我介绍一下,我叫吴海超(WHC)在iOS领域有丰富的开发架构经验Github以后我也会以文章的形式分享具有实战意义的文章给大家,希望能够给大家有所...

WHC
2017/01/15
0
0
简单的Windows应用程序创建Aztec条形码控件Aztec Fontware

Aztec Fontware 使你的Windows应用程序创建Aztec条码变得极其简单,你的应用程序可以使用字体、Win32 DLL编码器、.NET类库编码器打印Aztc条码,该产品可以完全集成到你的Crystal Reports 、O...

yidongkaifa
2014/05/31
0
0
vc第三方界面库BCGControlBar与Xtreme Toolkit对比

vc第三方界面库BCGControlBar与Xtreme Toolkit对比 BCGControlBar简介 BCGControlBar专业版(BCGControlBar Pro for MFC )是MFC的扩展类库,一直是MFC界面领域的老大哥,而且是微软合作商,对...

baobiaokongjian
2014/08/16
0
0
CSDN回帖得分大全(近两年)

√ vs2005调用dll的时候Initialize()函数返回错误 [VC/MFC 基础类] √ 为什么我创建登陆框之后,然后获取登陆框的数据时候总是出现非法操作! [VC/MFC 界面] √ CFileFind::FindFile 支持通配...

junwong
2012/03/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

弹性工作制的魔咒

简评:你找到了一份完美的工作 —— 可以提前离开公司,还可以在晚上从家里回复邮件。既然如此,你为什么还会有那么强的负罪感呢? 或许是弹性工作制魔咒在作祟。 很多享受弹性工作制的人会始...

极光推送
6分钟前
0
0
KAFKA介绍(分布式架构)

Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统术语: Kafka将消息以...

明理萝
12分钟前
0
1
os::NodeHandle::subscribe回调函数绑定对象

void Foo::callback(const std_msgs::Empty::ConstPtr& message){}Foo foo_object;ros::Subscriber sub = handle.subscribe("my_topic", 1, &Foo::callback, &foo_object); 参考: ht......

itfanr
14分钟前
0
0
React16.4 开发简书项目 从零基础入门到实战

React16.4 开发简书项目 从零基础入门到实战 关注我的订阅号下载 React16.4 开发简书项目 从零基础入门到实战

蜗牛奔跑
16分钟前
0
0
day57-20180815-流利阅读笔记-待学习

社恐怎么办?这个漫画或许能治愈你 毛西 2018-08-15 1.今日导读 近日,芬兰漫画家卡罗利娜·科尔霍宁创作的绘本《芬兰人的噩梦》在中国大火。一时间书中的主人公马蒂成为了人们茶余饭后热议的...

aibinxiao
20分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部