文档章节

VC++ 打印类

Ne0o0
 Ne0o0
发布于 2016/03/29 17:21
字数 1024
阅读 50
收藏 2
点赞 1
评论 0

通过系统提供的打印接口和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
博文 57
码字总数 28287
作品 0
程序员
2016-2017学年第二学期C++第二章

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

u013594828 ⋅ 2017/04/30 ⋅ 0

iOS Debuger(便捷辅助调试器)

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

WHC ⋅ 2017/01/15 ⋅ 0

简单的Windows应用程序创建Aztec条形码控件Aztec Fontware

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

yidongkaifa ⋅ 2014/05/31 ⋅ 0

vc第三方界面库BCGControlBar与Xtreme Toolkit对比

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

baobiaokongjian ⋅ 2014/08/16 ⋅ 0

CSDN回帖得分大全(近两年)

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

junwong ⋅ 2012/03/09 ⋅ 0

从现在,开始swift

导语 苹果在2014的WWDC中推出了Swift 这一全新的编程语言,一时之间成为各大网站的头条和所有程序员的讨论热点,与可读性较差的Objective-C相比,这门融合了多种编程语言优点的语言得到了各大...

芳仔小脚丫 ⋅ 2014/10/15 ⋅ 4

VC2015调用Grid++report报表控件

Grid++report这是一个国产报表控件,从2.x就开始接触,基本所有的学习资源,来自于自带的文档和例子。能学多少靠摸索。整体功能还是不错的。他提供了3个控件,一个组件。在VC2015如果不想用控件...

Chinayu2014 ⋅ 05/21 ⋅ 0

GIS属性数据高效显示

对于GIS软件来说,属性数据的显示是一个比较重要的问题,在基于VC++的GIS底层开发中,一般用ClistCtrl或者DBGrid来显示属性数据。然而这些控件显示效率比较低或者效率高的话比较难操作。通过...

长平狐 ⋅ 2013/12/25 ⋅ 0

VC 6.0 配置和使用gdi+

GDI+ GDI+是Windows XP中的一个子系统,它主要负责在显示屏幕和打印设备输出有关信息,它是一组通过C++类实现的应用程序编程接口。顾名思义,GDI+是以前版本GDI的继承者,出于兼容性考虑,W...

junwong ⋅ 2012/03/23 ⋅ 0

DataMatrix Fontware控件介绍

DataMatrix Fontware控件使你的Windows应用程序创建DataMatrix条码变得十分简单,你的应用程序可以使用字体、Win32 DLL编码器、.NET类库编码器打印DataMatrix条码,该产品可以完全集成到你的...

yidongkaifa ⋅ 2014/08/25 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

vbs 取文件大小 字节

dim namedim fs, s'name = Inputbox("姓名")'msgbox(name)set fs = wscript.createobject("scripting.filesystemobject") 'fs为FSO实例if (fs.folderexists("c:\temp"))......

vga ⋅ 12分钟前 ⋅ 1

高并发之Nginx的限流

首先Nginx的版本号有要求,最低为1.11.5 如果低于这个版本,在Nginx的配置中 upstream web_app { server 到达Ip1:端口 max_conns=10; server 到达Ip2:端口 max_conns=10; } server { listen ...

算法之名 ⋅ 今天 ⋅ 0

Spring | IOC AOP 注解 简单使用

写在前面的话 很久没更新笔记了,有人会抱怨:小冯啊,你是不是在偷懒啊,没有学习了。老哥,真的冤枉:我觉得我自己很菜,还在努力学习呢,正在学习Vue.js做管理系统呢。即便这样,我还是不...

Wenyi_Feng ⋅ 今天 ⋅ 0

博客迁移到 https://www.jianshu.com/u/aa501451a235

博客迁移到 https://www.jianshu.com/u/aa501451a235 本博客不再更新

为为02 ⋅ 今天 ⋅ 0

win10怎么彻底关闭自动更新

win10自带的更新每天都很多,每一次下载都要占用大量网络,而且安装要等得时间也蛮久的。 工具/原料 Win10 方法/步骤 单击左下角开始菜单点击设置图标进入设置界面 在设置窗口中输入“服务”...

阿K1225 ⋅ 今天 ⋅ 0

Elasticsearch 6.3.0 SQL功能使用案例分享

The best elasticsearch highlevel java rest api-----bboss Elasticsearch 6.3.0 官方新推出的SQL检索插件非常不错,本文一个实际案例来介绍其使用方法。 1.代码中的sql检索 @Testpu...

bboss ⋅ 今天 ⋅ 0

informix数据库在linux中的安装以及用java/c/c++访问

一、安装前准备 安装JDK(略) 到IBM官网上下载informix软件:iif.12.10.FC9DE.linux-x86_64.tar放在某个大家都可以访问的目录比如:/mypkg,并解压到该目录下。 我也放到了百度云和天翼云上...

wangxuwei ⋅ 今天 ⋅ 0

PHP语言系统ZBLOG或许无法重现月光博客的闪耀历史[图]

最近在写博客,希望通过自己努力打造一个优秀的教育类主题博客,名动江湖,但是问题来了,现在写博客还有前途吗?面对强大的自媒体站点围剿,还有信心和可能型吗? 至于程序部分,我选择了P...

原创小博客 ⋅ 今天 ⋅ 0

IntelliJ IDEA 2018.1新特性

工欲善其事必先利其器,如果有一款IDE可以让你更高效地专注于开发以及源码阅读,为什么不试一试? 本文转载自:netty技术内幕 3月27日,jetbrains正式发布期待已久的IntelliJ IDEA 2018.1,再...

Romane ⋅ 今天 ⋅ 0

浅谈设计模式之工厂模式

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端暴露创建逻...

佛系程序猿灬 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部