Visual C++6.0是开发Windows应用程序的强大工具,但是要通过它实现程序的打印功能,一直是初学者的一个难点,经常有朋友询问如何在VC中实现打印功能,他们往往感到在MFC提供的框架内实现这个问题很复杂,不知道如何下手。本例针对这个问题,介绍一种简单的方法实现文字串的打印功能,读者朋友可以在此基础上稍微改动一下,就可以实现文件、图像的打印功能。

  一、实现方法

  在Windows操作系统下,显示器、打印机和绘图仪都被视为输出设备,正常情况下,系统默认的输出设备是显示器。要使用打印机,首先需要创建一个指向打印机的设备环境句柄,然后通过该句柄调用相关的绘图函数把所需的文字和图形输出至打印机上。当打印结束后,删除这个设备环境句柄即可。

  当Windows系统中安装好打印机后,系统总是自动设置一个打印机为系统的默认打印机,在Windows的启动配置文件Win.ini中的[window]段中列出了带有关键字device的默认打印机。下面是某一机器中Win.ini中的[Windows]字段的内容:

[windows]
load=
run=
NullPort=None
device=HP LaserJet 4050(computer000),HPBFDB1,LPT1

  在上述关键字device后的字符串中,包含了系统中默认打印机的三个重要属性,它们依次是打印机的设备名HP LaserJet 4050(computer000),驱动程序名是HPBFDB1,输出端口为LPT1。

  为了操纵系统默认的打印机,实现程序的打印功能,在程序中可调用API函数GetProfileString()从Win.ini文件中获得device这个设备字符串,该函数的原型为:DWORD GetProfileString( LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize)。函数中lpAppName参数为所要检索的Win.ini文件中的字段名;lpKeyName为字段中的关键字名;lpDefault为默认的字符串;lpReturnedString为检索到的字符串,如果该函数没有从lpKeyName关键字中检索到相应的字符串,则kpRetrunedString返回默认字符串lpDefault;nSize为返回字符串的长度。

  获取上述字符串后,再使用strtok()函数将该字符串进行分解,获得与打印机相关的三个属性,作为API函数CreateDC()创建打印机设备环境句柄的参数,CreateDC()函数如果调用成功,则为默认打印机创建一个设备环境句柄,否则返回一个空值(NULL)。该函数的原形为:HDC CreateDC(LPCTSTR lpszDriver,LPCTSTR lpszDevice,LPCTSTR lpszOutput,CONST DEVMODE *lpinitData)。该函数的前三个参数恰好对应打印机的三个属性,最后一个参数为初始化打印机驱动程序的数据,一般情况下该参数设置为NULL就可以了。

  在具体打印的过程中,调用int StartDoc( HDC hdc, CONST DOCINFO *lpdi )函数来开始一个打印任务,其中参数lpdi为一个指向DOCINFO结构的指针,该结构如下:

typedef struct { 
 int cbSize; //结构的尺寸大小;
 LPCTSTR lpszDocName; //文档的名字;
 LPCTSTR lpszOutput; //输出文档名,一般情况下为NULL;
 LPCTSTR lpszDatatype;//用来记录打印过程的数据类型,一般情况下为NULL;
 DWORD fwType; //用来支持打印工作的额外

信息,一般情况下为NULL;
} DOCINFO, *LPDOCINFO; 
  开始一个打印任务后,再调用StartPage(hdcprint)函数让打印机走纸,通知打印机有文档将要打印;接下来的工作就是输出数据了,这部分工作对于开发人员来说就象往计算机屏幕上输出文字、图像一样容易,只不过是计算机根据当前的设备环境句柄自动将数据输出到打印机罢了。数据打印完后,需要作一些善后处理工作,使用RestoreDC(hdcprint,-1)函数恢复打印机设备句柄、EndPage(hdcprint)函数让打印机停止打印,最后调用EndDoc(hdcprint)函数结束上述的打印作业。

  二、编程步骤

  1、启动Visual C++6.0,新建一个基于对话框的应用程序Test,在程序的对话框窗体中加入一个按钮(Button),设置这个Button的属性:ID=IDC_PRINT,CAPTION="打印";

  2、使用Class Wizard类向导为该按钮添加一个鼠标单击处理函数OnPrint()

  3、修改TestDlg.cpp文件中的OnPrint()函数;

  4、添加代码,编译运行程序。

==========================================================================================================================

在打印预览对话框类中

  1. extern int nPaperSize_X ;
  2. extern int nPaperSize_Y ;
  3. extern int nOneLines;
  4. extern int nNextLines;
  5. //打印结构
  6. typedef struct
  7. {
  8. int  nMaxLine;   //最大行数
  9. int  nCountPage;   //一共页数
  10. int  nCurPage;   //当前页码
  11. BOOL IsPrint;   //是否打印
  12. HWND hWnd;    //窗口句柄
  13. HWND hListView;   //列表控件句柄
  14. TCHAR szTag[256];   //其它数据
  15. int  nTag;    //其它数据
  16. LPVOID lpVoid;    //其它数据
  17. CGridCtrlEx *pObj;   //区分是月报表还是日报表
  18. }PRNINFO, *PPRNINFO;
extern int nPaperSize_X ;
extern int nPaperSize_Y ;
extern int nOneLines;
extern int nNextLines; //打印结构
typedef struct
{
int nMaxLine; //最大行数
int nCountPage; //一共页数
int nCurPage; //当前页码
BOOL IsPrint; //是否打印
HWND hWnd; //窗口句柄
HWND hListView; //列表控件句柄
TCHAR szTag[256]; //其它数据
int nTag; //其它数据
LPVOID lpVoid; //其它数据
CGridCtrlEx *pObj; //区分是月报表还是日报表
}PRNINFO, *PPRNINFO;
  1. //回调函数,设置打印属性
  2. void CPreviewParentDlg::SetCallBackFun( PRINTPREVIEW pFun, PRNINFO &sPrnInfo )
  3. {
  4. memcpy(&m_PrnInfo, &sPrnInfo, sizeof(PRNINFO));
  5. m_pDrawInfoFun = pFun;
  6. m_nCount = m_PrnInfo.nMaxLine;  // 总的行数
  7. m_nCountPage = 1;
  8. int m = m_nCount-m_OneCount;
  9. int n = m/m_NextCount;
  10. m_nCountPage += n;
  11. n = m%m_NextCount;
  12. if(n>0)
  13. m_nCountPage++;   // 页数
  14. m_PrnInfo.nCountPage = m_nCountPage;
  15. sPrnInfo.nCountPage = m_nCountPage;
  16. }
//回调函数,设置打印属性
void CPreviewParentDlg::SetCallBackFun( PRINTPREVIEW pFun, PRNINFO &sPrnInfo )
{
memcpy(&m_PrnInfo, &sPrnInfo, sizeof(PRNINFO));
m_pDrawInfoFun = pFun;
m_nCount = m_PrnInfo.nMaxLine; // 总的行数
m_nCountPage = 1;
int m = m_nCount-m_OneCount;
int n = m/m_NextCount;
m_nCountPage += n;
n = m%m_NextCount;
if(n>0)
m_nCountPage++; // 页数
m_PrnInfo.nCountPage = m_nCountPage;
sPrnInfo.nCountPage = m_nCountPage;
}
  1. void CPreviewChildDlg::PrintDoc()
  2. {
  3. NotifyDlg Ndlg(_T("决定打印当前报表吗?"), TRUE);
  4. if (Ndlg.DoModal() == IDCANCEL)
  5. return;
  6. PRINTDLG printInfo;
  7. ZeroMemory(&printInfo,sizeof(printInfo));  //清空该结构
  8. printInfo.lStructSize = sizeof(printInfo);
  9. printInfo.hwndOwner = 0;
  10. printInfo.hDevMode = 0;
  11. printInfo.hDevNames = 0;
  12. //这个是关键,PD_RETURNDC 如果不设这个标志,就拿不到hDC了
  13. //            PD_RETURNDEFAULT 这个就是得到默认打印机,不需要弹设置对话框
  14. printInfo.Flags = PD_RETURNDC | PD_RETURNDEFAULT | PD_ALLPAGES;
  15. PrintDlg(&printInfo);//调用API拿出默认打印机
  16. DWORD rst = CommDlgExtendedError();//看看出错没有
  17. if(rst != 0)
  18. {//出错了,清空标志再次调用API,此时就会弹出打印设置对话框供用户选择了
  19. printInfo.Flags = 0;
  20. PrintDlg(&printInfo);
  21. }
  22. HDC printDC=printInfo.hDC; //得到打印DC,输出到打印,
  23. CDC MemDc;
  24. MemDc.Attach(printDC);
  25. if(m_pDrawInfoFun!= NULL)
  26. {
  27. m_PrnInfo.IsPrint = TRUE;  // 用打印机打印
  28. m_PrnInfo.nCurPage = m_CurPage;
  29. m_PrnInfo.nCountPage = m_CountPage;
  30. m_pDrawInfoFun(MemDc, m_PrnInfo);
  31. }
  32. MemDc.DeleteDC();}
void CPreviewChildDlg::PrintDoc()
{
NotifyDlg Ndlg(_T("决定打印当前报表吗?"), TRUE);
if (Ndlg.DoModal() == IDCANCEL)
return; PRINTDLG printInfo;
ZeroMemory(&printInfo,sizeof(printInfo)); //清空该结构
printInfo.lStructSize = sizeof(printInfo);
printInfo.hwndOwner = 0;
printInfo.hDevMode = 0;
printInfo.hDevNames = 0;
//这个是关键,PD_RETURNDC 如果不设这个标志,就拿不到hDC了
// PD_RETURNDEFAULT 这个就是得到默认打印机,不需要弹设置对话框
printInfo.Flags = PD_RETURNDC | PD_RETURNDEFAULT | PD_ALLPAGES; PrintDlg(&printInfo);//调用API拿出默认打印机
DWORD rst = CommDlgExtendedError();//看看出错没有
if(rst != 0)
{//出错了,清空标志再次调用API,此时就会弹出打印设置对话框供用户选择了
printInfo.Flags = 0;
PrintDlg(&printInfo);
} HDC printDC=printInfo.hDC; //得到打印DC,输出到打印, CDC MemDc;
MemDc.Attach(printDC); if(m_pDrawInfoFun!= NULL)
{
m_PrnInfo.IsPrint = TRUE; // 用打印机打印
m_PrnInfo.nCurPage = m_CurPage;
m_PrnInfo.nCountPage = m_CountPage;
m_pDrawInfoFun(MemDc, m_PrnInfo);
} MemDc.DeleteDC();}
  1. //刷新预览区
  2. void CPreviewChildDlg::OnPaint()
  3. {
  4. CPaintDC dc(this); // device context for painting
  5. // TODO: Add your message handler code here
  6. CClientDC dlgDC(this);
  7. SetWindowOrgEx(dlgDC.m_hDC, m_xPt, m_yPt, NULL);
  8. CDC MemDc;
  9. MemDc.CreateCompatibleDC(NULL);
  10. CBitmap cBitmap;
  11. int xP = dlgDC.GetDeviceCaps(LOGPIXELSX);
  12. int yP = dlgDC.GetDeviceCaps(LOGPIXELSY);
  13. DOUBLE xPix = (DOUBLE)xP*10/254;    //每 mm 宽度的像素
  14. DOUBLE yPix = (DOUBLE)yP*10/254;    //每 mm 高度的像素
  15. cBitmap.CreateCompatibleBitmap(&dlgDC, nPaperSize_X*xPix, nPaperSize_Y*yPix);
  16. MemDc.SelectObject(&cBitmap);
  17. if(m_pDrawInfoFun!= NULL)
  18. {
  19. m_PrnInfo.IsPrint = FALSE;  //显示的是 预览窗口
  20. m_PrnInfo.nCurPage = m_CurPage;
  21. m_pDrawInfoFun(MemDc, m_PrnInfo);   //调用回调函数
  22. }
  23. dlgDC.BitBlt(xP/2, yP/2, nPaperSize_X*xPix+xP/2, nPaperSize_Y*yPix+yP/2, &MemDc, 0, 0, SRCCOPY);
  24. MemDc.DeleteDC();
  25. cBitmap.DeleteObject();
  26. // Do not call CDialog::OnPaint() for painting messages
  27. }
//刷新预览区
void CPreviewChildDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here CClientDC dlgDC(this);
SetWindowOrgEx(dlgDC.m_hDC, m_xPt, m_yPt, NULL);
CDC MemDc;
MemDc.CreateCompatibleDC(NULL);
CBitmap cBitmap;
int xP = dlgDC.GetDeviceCaps(LOGPIXELSX);
int yP = dlgDC.GetDeviceCaps(LOGPIXELSY); DOUBLE xPix = (DOUBLE)xP*10/254; //每 mm 宽度的像素
DOUBLE yPix = (DOUBLE)yP*10/254; //每 mm 高度的像素 cBitmap.CreateCompatibleBitmap(&dlgDC, nPaperSize_X*xPix, nPaperSize_Y*yPix);
MemDc.SelectObject(&cBitmap);
if(m_pDrawInfoFun!= NULL)
{
m_PrnInfo.IsPrint = FALSE; //显示的是 预览窗口
m_PrnInfo.nCurPage = m_CurPage;
m_pDrawInfoFun(MemDc, m_PrnInfo); //调用回调函数
}
dlgDC.BitBlt(xP/2, yP/2, nPaperSize_X*xPix+xP/2, nPaperSize_Y*yPix+yP/2, &MemDc, 0, 0, SRCCOPY); MemDc.DeleteDC();
cBitmap.DeleteObject();
// Do not call CDialog::OnPaint() for painting messages
}

=============调用打印功能类

  1. void CAttendReportDlg::PrintData()
  2. {
  3. CGridCtrlEx *pGridCtrl = NULL;
  4. BOOL bDay = FALSE;
  5. if ( ((CButton*)GetDlgItem(IDC_RADIO_DAY))->GetCheck() )
  6. {
  7. pGridCtrl = m_pDayGridCtrl;
  8. bDay = TRUE;
  9. }
  10. else if ( ((CButton*)GetDlgItem(IDC_RADIO_MONTH))->GetCheck() )
  11. {
  12. pGridCtrl = m_pMonGridCtrl;
  13. }
  14. if( pGridCtrl->GetRowCount() <= 1 )    // 没有记录
  15. return;
  16. ///选择打印机对话框
  17. CDC MemDc;
  18. HDC hdcPrint = NULL;
  19. CPrintDialog dlg(FALSE);
  20. if (m_bPrint)  //打印按钮,不弹出选择对话框,获取默认打印设备
  21. {
  22. PRINTDLG printInfo;
  23. ZeroMemory(&printInfo,sizeof(printInfo));  //清空该结构
  24. printInfo.lStructSize = sizeof(printInfo);
  25. printInfo.hwndOwner = 0;
  26. printInfo.hDevMode = 0;
  27. printInfo.hDevNames = 0;
  28. //这个是关键,PD_RETURNDC 如果不设这个标志,就拿不到hDC了
  29. //PD_RETURNDEFAULT 这个就是得到默认打印机,不需要弹出设置对话框
  30. printInfo.Flags = PD_RETURNDC | PD_RETURNDEFAULT | PD_ALLPAGES;
  31. PrintDlg(&printInfo);//调用API拿出默认打印机
  32. DWORD rst = CommDlgExtendedError();//看看出错没有
  33. if(rst != 0)
  34. {//出错了,清空标志再次调用API,此时就会弹出打印设置对话框供用户选择了
  35. printInfo.Flags = 0;
  36. PrintDlg(&printInfo);
  37. }
  38. hdcPrint=printInfo.hDC; //得到打印DC,输出到打印
  39. }
  40. else  //弹出对话框选择打印设备
  41. {
  42. dlg.DoModal();
  43. hdcPrint = dlg.GetPrinterDC();
  44. }
  45. if(hdcPrint == NULL)
  46. {
  47. NotifyDlg Ndlg(_T("打印机初始化失败!"));
  48. Ndlg.DoModal();
  49. return;
  50. }
  51. MemDc.Attach(hdcPrint);
  52. nPaperSize_X = MemDc.GetDeviceCaps(HORZSIZE);    // 纸张宽度
  53. nPaperSize_Y = MemDc.GetDeviceCaps(VERTSIZE);    // 纸张高度
  54. int xP = GetDeviceCaps(MemDc.m_hDC, LOGPIXELSX);    //x方向每英寸像素点数
  55. int yP = GetDeviceCaps(MemDc.m_hDC, LOGPIXELSY);    //y方向每英寸像素点数
  56. int xPix = (DOUBLE)xP*10/254;   //每 mm 宽度的像素
  57. int yPix = (DOUBLE)yP*10/254;   //每 mm 高度的像素
  58. DOUBLE fAdd = 5*yPix;       //每格递增量
  59. nOneLines = (nPaperSize_Y * 0.85*yPix)/fAdd;
  60. nNextLines = (nPaperSize_Y * 0.85*yPix)/fAdd+1;
  61. PRNINFO PrnInfo = {0};
  62. PrnInfo.hListView = NULL;
  63. PrnInfo.hWnd = this->m_hWnd;
  64. PrnInfo.IsPrint = m_bPrint;
  65. PrnInfo.nCurPage = 1;
  66. PrnInfo.nMaxLine = pGridCtrl->GetRowCount()-1;
  67. PrnInfo.pObj = pGridCtrl;
  68. CPreviewParentDlg DlgPreView;
  69. CPreviewChildDlg DlgChildPreView;
  70. if (bDay)
  71. {
  72. DlgPreView.SetCallBackFun(PrintDayInfo, PrnInfo);  //回调函数,设置打印或预览函数,及纸张排版信息
  73. DlgChildPreView.SetCallBackFun(PrintDayInfo, PrnInfo);
  74. }
  75. else
  76. {
  77. DlgPreView.SetCallBackFun(PrintMonInfo, PrnInfo);
  78. DlgChildPreView.SetCallBackFun(PrintMonInfo, PrnInfo);
  79. }
  80. if (!m_bPrint)
  81. {
  82. DlgPreView.DoModal();
  83. }
  84. else
  85. {
  86. DlgChildPreView.PrintDoc();
  87. }
  88. MemDc.DeleteDC();
  89. }
  90. void CAttendReportDlg::PrintDayInfo( CDC &memDC, PRNINFO PrnInfo )
  91. {
  92. if(memDC.m_hDC == NULL)
  93. return;
  94. int nCurPage = PrnInfo.nCurPage;    //当前页
  95. BOOL IsPrint = PrnInfo.IsPrint;     //是否打印
  96. int nMaxPage = PrnInfo.nCountPage;  //最大页码
  97. HWND hWnd = PrnInfo.hWnd;
  98. CString csLFinality, csRFinality;
  99. CGridCtrlEx *pGridCtrl = PrnInfo.pObj;
  100. CTime time = CTime::GetCurrentTime();
  101. csLFinality = time.Format(_T("%Y-%m-%d %H:%M:%S"));
  102. csLFinality = _T("报表日期:") + csLFinality;
  103. csRFinality.Format(_T("第 %i 页/共 %i 页"), nCurPage, nMaxPage);
  104. TCHAR szTitle[] = _T("考 勤 日 报 表");
  105. CRect rc, rt1, rt2, rt3, rt4, rt5, rt6, rt7, rt8, rt9, rt10;
  106. CPen *hPenOld;
  107. CPen cPen;
  108. CFont TitleFont, DetailFont, *oldfont;
  109. //标题字体
  110. TitleFont.CreateFont(-MulDiv(14,memDC.GetDeviceCaps(LOGPIXELSY),72),
  111. 0,0,0,FW_NORMAL,0,0,0,GB2312_CHARSET,
  112. OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY,
  113. VARIABLE_PITCH|FF_SWISS,_T("黑体"));
  114. //细节字体
  115. DetailFont.CreateFont(-MulDiv(10,memDC.GetDeviceCaps(LOGPIXELSY),92),
  116. 0,0,0,FW_NORMAL,0,0,0,GB2312_CHARSET,
  117. OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY,
  118. VARIABLE_PITCH|FF_SWISS,_T("宋体"));
  119. //粗笔
  120. cPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0));
  121. int xP = GetDeviceCaps(memDC.m_hDC, LOGPIXELSX);    //x方向每英寸像素点数
  122. int yP = GetDeviceCaps(memDC.m_hDC, LOGPIXELSY);    //y方向每英寸像素点数
  123. DOUBLE xPix = (DOUBLE)xP*10/254;    //每 mm 宽度的像素
  124. DOUBLE yPix = (DOUBLE)yP*10/254;    //每 mm 高度的像素
  125. DOUBLE fAdd = 5*yPix;       //每格递增量
  126. DOUBLE nTop = 30*yPix;      //第一页最上线
  127. int   iStart = 0;           //从第几行开始读取
  128. DOUBLE nBottom = nTop+nOneLines*fAdd;
  129. if(nCurPage != 1)
  130. nTop = 30*yPix-fAdd;    //非第一页最上线
  131. if(nCurPage == 2)
  132. iStart = nOneLines;
  133. if(nCurPage>2)
  134. iStart = nOneLines+(nCurPage - 2)*nNextLines;
  135. DOUBLE nLeft = 15*xPix;         //最左线
  136. DOUBLE nRight = xPix*(nPaperSize_X-15); //最右线
  137. DOUBLE nItemWide = ((nPaperSize_X-30)/14)*xPix;
  138. DOUBLE nTextAdd = 1.5*xPix;
  139. if(IsPrint)
  140. {
  141. //真正打印部分
  142. static DOCINFO di = {sizeof (DOCINFO),  szTitle} ;
  143. //开始文档打印/////////////////////////////////////////     start print
  144. //////////////////////////////////////////////////////////
  145. if(memDC.StartDoc( &di ) < 0) // startdoc-----enddoc
  146. {
  147. NotifyDlg dlg(_T("连接到打印机化败!"));
  148. dlg.DoModal();
  149. }
  150. else
  151. {
  152. iStart = 0;
  153. nTop = 30*yPix;     //第一页最上线
  154. for(int iTotalPages = 1; iTotalPages<=nMaxPage; iTotalPages++)
  155. {
  156. int nCurPage = iTotalPages;
  157. csRFinality.Format(_T("第 %i 页/共 %i 页"), nCurPage, nMaxPage);
  158. time=CTime::GetCurrentTime();
  159. csLFinality = time.Format(_T("%Y-%m-%d %H:%M:%S"));
  160. csLFinality = _T("报表日期:") + csLFinality;
  161. if(nCurPage != 1)
  162. nTop = 30*yPix-fAdd;    //非第一页最上线
  163. if(nCurPage == 2)
  164. iStart = nOneLines;
  165. if(nCurPage>2)
  166. iStart = nOneLines+(nCurPage - 2)*nNextLines;
  167. //开始页
  168. if(memDC.StartPage() < 0)
  169. {
  170. NotifyDlg dlg(_T("打印失败!"));
  171. dlg.DoModal();
  172. memDC.AbortDoc();
  173. return;
  174. }
  175. else
  176. {
  177. //打印
  178. //标题
  179. oldfont = memDC.SelectObject(&TitleFont);
  180. int nItem = nNextLines;
  181. if(nCurPage == 1)
  182. {
  183. nItem = nOneLines;
  184. rc.SetRect(0, yPix*15, nPaperSize_X*xPix, yPix*25);
  185. memDC.DrawText(szTitle, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  186. }
  187. //细节
  188. memDC.SelectObject(&DetailFont);
  189. rc.SetRect(nLeft, nTop, nRight, nTop+fAdd);
  190. //上横线
  191. memDC.MoveTo(rc.left, rc.top);
  192. memDC.LineTo(rc.right, rc.top);
  193. rt1.SetRect(nLeft, nTop, rc.right -12.4*nItemWide , nTop+fAdd);     //编 号
  194. rt2.SetRect(rt1.right, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom); //姓名
  195. rt3.SetRect(rt2.right, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom); //考勤日期
  196. rt4.SetRect(rt3.right, rt1.top, rt3.right + 2.2*nItemWide, rt1.bottom); //班次
  197. rt5.SetRect(rt4.right, rt1.top, rt4.right + 1.6*nItemWide, rt1.bottom); //时段
  198. rt6.SetRect(rt5.right, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom); //考勤时间
  199. rt7.SetRect(rt6.right, rt1.top, rt6.right + nItemWide, rt1.bottom); //迟到(分)
  200. rt8.SetRect(rt7.right, rt1.top, rt7.right + nItemWide, rt1.bottom); //早退(分)
  201. rt9.SetRect(rt8.right, rt1.top, rt8.right + nItemWide, rt1.bottom); //旷工(分)
  202. rt10.SetRect(rt9.right, rt1.top, rc.right, rt1.bottom); //请假(分)
  203. memDC.DrawText(_T("编 号"), &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  204. memDC.DrawText(_T("姓 名"), &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  205. memDC.DrawText(_T("考勤日期"), &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  206. memDC.DrawText(_T("班 次"), &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  207. memDC.DrawText(_T("时 段"), &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  208. memDC.DrawText(_T("考勤时间"), &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  209. memDC.DrawText(_T("迟到(分)"), &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  210. memDC.DrawText(_T("早退(分)"), &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  211. memDC.DrawText(_T("旷工(分)"), &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  212. memDC.DrawText(_T("请假(分)"), &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  213. memDC.MoveTo(rt1.right, rt1.top);
  214. memDC.LineTo(rt1.right, rt1.bottom);
  215. memDC.MoveTo(rt2.right, rt1.top);
  216. memDC.LineTo(rt2.right, rt1.bottom);
  217. memDC.MoveTo(rt3.right, rt1.top);
  218. memDC.LineTo(rt3.right, rt1.bottom);
  219. memDC.MoveTo(rt4.right, rt1.top);
  220. memDC.LineTo(rt4.right, rt1.bottom);
  221. memDC.MoveTo(rt5.right, rt1.top);
  222. memDC.LineTo(rt5.right, rt1.bottom);
  223. memDC.MoveTo(rt6.right, rt1.top);
  224. memDC.LineTo(rt6.right, rt1.bottom);
  225. memDC.MoveTo(rt7.right, rt1.top);
  226. memDC.LineTo(rt7.right, rt1.bottom);
  227. memDC.MoveTo(rt8.right, rt1.top);
  228. memDC.LineTo(rt8.right, rt1.bottom);
  229. memDC.MoveTo(rt9.right, rt1.top);
  230. memDC.LineTo(rt9.right, rt1.bottom);
  231. memDC.MoveTo(rc.left, rt1.bottom);
  232. memDC.LineTo(rc.right, rt1.bottom);
  233. CString strID, strName, strDate, strSID, strTime, strAttTime, strLate, strEarlier, strAbsent, strLeave;
  234. rc.SetRect(nLeft, nTop+fAdd, nRight, nTop+2*fAdd);
  235. rt1.SetRect(nLeft+nTextAdd, rc.top, rc.right-12.4*nItemWide, rc.bottom);
  236. rt2.SetRect(rt1.right+nTextAdd, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom);
  237. rt3.SetRect(rt2.right+nTextAdd, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom);
  238. rt4.SetRect(rt3.right+nTextAdd, rt1.top, rt3.right + 2.2*nItemWide, rt1.bottom);
  239. rt5.SetRect(rt4.right+nTextAdd, rt1.top, rt4.right +1.6*nItemWide, rt1.bottom);
  240. rt6.SetRect(rt5.right+nTextAdd, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom);
  241. rt7.SetRect(rt6.right+nTextAdd, rt1.top, rt6.right + nItemWide, rt1.bottom);
  242. rt8.SetRect(rt7.right+nTextAdd, rt1.top, rt7.right + nItemWide, rt1.bottom);
  243. rt9.SetRect(rt8.right+nTextAdd, rt1.top, rt8.right + nItemWide, rt1.bottom);
  244. rt10.SetRect(rt9.right+nTextAdd, rt1.top, rc.right, rt1.bottom);
  245. int nCountItem = pGridCtrl->GetRowCount();
  246. for(int i=1;i<nItem; i++)
  247. {
  248. strID = pGridCtrl->GetItemText(i+iStart, 1);
  249. strName = pGridCtrl->GetItemText(i+iStart, 2);
  250. strDate = pGridCtrl->GetItemText(i+iStart, 3);
  251. strSID = pGridCtrl->GetItemText(i+iStart, 4);
  252. strTime = pGridCtrl->GetItemText(i+iStart, 5);
  253. strAttTime = pGridCtrl->GetItemText(i+iStart, 6);
  254. strLate = pGridCtrl->GetItemText(i+iStart, 7);
  255. strEarlier = pGridCtrl->GetItemText(i+iStart, 8);
  256. strAbsent = pGridCtrl->GetItemText(i+iStart, 9);
  257. strLeave = pGridCtrl->GetItemText(i+iStart, 10);
  258. memDC.DrawText(strID, &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  259. memDC.DrawText(strName, &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  260. memDC.DrawText(strDate, &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  261. memDC.DrawText(strSID, &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  262. memDC.DrawText(strTime, &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  263. memDC.DrawText(strAttTime, &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  264. memDC.DrawText(strLate, &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  265. memDC.DrawText(strEarlier, &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  266. memDC.DrawText(strAbsent, &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  267. memDC.DrawText(strLeave, &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  268. //下横线
  269. memDC.MoveTo(rc.left, rc.bottom);
  270. memDC.LineTo(rc.right, rc.bottom);
  271. memDC.MoveTo(rt1.right, rt1.top);
  272. memDC.LineTo(rt1.right, rt1.bottom);
  273. memDC.MoveTo(rt2.right, rt1.top);
  274. memDC.LineTo(rt2.right, rt1.bottom);
  275. memDC.MoveTo(rt3.right, rt1.top);
  276. memDC.LineTo(rt3.right, rt1.bottom);
  277. memDC.MoveTo(rt4.right, rt1.top);
  278. memDC.LineTo(rt4.right, rt1.bottom);
  279. memDC.MoveTo(rt5.right, rt1.top);
  280. memDC.LineTo(rt5.right, rt1.bottom);
  281. memDC.MoveTo(rt6.right, rt1.top);
  282. memDC.LineTo(rt6.right, rt1.bottom);
  283. memDC.MoveTo(rt7.right, rt1.top);
  284. memDC.LineTo(rt7.right, rt1.bottom);
  285. memDC.MoveTo(rt8.right, rt1.top);
  286. memDC.LineTo(rt8.right, rt1.bottom);
  287. memDC.MoveTo(rt9.right, rt1.top);
  288. memDC.LineTo(rt9.right, rt1.bottom);
  289. memDC.MoveTo(rc.left, rt1.bottom);
  290. memDC.LineTo(rc.right, rt1.bottom);
  291. rc.top += fAdd;
  292. rc.bottom += fAdd;
  293. rt1.top = rc.top;
  294. rt1.bottom = rc.bottom;
  295. rt2.top = rt1.top;
  296. rt2.bottom = rt1.bottom;
  297. rt3.top = rt1.top;
  298. rt3.bottom = rt1.bottom;
  299. rt4.top = rt1.top;
  300. rt4.bottom = rt1.bottom;
  301. rt5.top = rt1.top;
  302. rt5.bottom = rt1.bottom;
  303. rt6.top = rt1.top;
  304. rt6.bottom = rt1.bottom;
  305. rt7.top = rt1.top;
  306. rt7.bottom = rt1.bottom;
  307. rt8.top = rt1.top;
  308. rt8.bottom = rt1.bottom;
  309. rt9.top = rt1.top;
  310. rt9.bottom = rt1.bottom;
  311. rt10.top = rt1.top;
  312. rt10.bottom = rt1.bottom;
  313. if((i+iStart+1)>=nCountItem)
  314. break;
  315. }
  316. //结尾
  317. memDC.MoveTo(rc.left, nTop);
  318. memDC.LineTo(rc.left, rc.top);
  319. memDC.MoveTo(rc.right, nTop);
  320. memDC.LineTo(rc.right, rc.top);
  321. memDC.DrawText(csLFinality, &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
  322. memDC.DrawText(csRFinality, &rc, DT_RIGHT| DT_VCENTER | DT_SINGLELINE);
  323. memDC.EndPage();
  324. memDC.SelectObject(oldfont);
  325. }
  326. }
  327. memDC.EndDoc();
  328. }
  329. }
  330. else
  331. {
  332. ////////////////////打印预览
  333. //边框线
  334. hPenOld = memDC.SelectObject(&cPen);
  335. rc.SetRect(0, 0, nPaperSize_X*xPix, nPaperSize_Y*yPix);
  336. memDC.Rectangle(&rc);
  337. memDC.SelectObject(hPenOld);
  338. //标题
  339. oldfont = memDC.SelectObject(&TitleFont);
  340. int nItem = nNextLines;
  341. if(nCurPage == 1)
  342. {
  343. nItem = nOneLines;
  344. rc.SetRect(0, yPix*15, nPaperSize_X*xPix, yPix*25);
  345. memDC.DrawText(szTitle, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  346. }
  347. //细节
  348. memDC.SelectObject(&DetailFont);
  349. rc.SetRect(nLeft, nTop, nRight, nTop+fAdd);
  350. //上横线
  351. memDC.MoveTo(rc.left, rc.top);
  352. memDC.LineTo(rc.right, rc.top);
  353. rt1.SetRect(nLeft, nTop, rc.right -12.2*nItemWide, nTop+fAdd);      //编 号
  354. rt2.SetRect(rt1.right, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom); //姓名
  355. rt3.SetRect(rt2.right, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom); //考勤日期
  356. rt4.SetRect(rt3.right, rt1.top, rt3.right + 2*nItemWide, rt1.bottom);   //班次
  357. rt5.SetRect(rt4.right, rt1.top, rt4.right + 1.6*nItemWide, rt1.bottom); //时段
  358. rt6.SetRect(rt5.right, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom); //考勤时间
  359. rt7.SetRect(rt6.right, rt1.top, rt6.right + nItemWide, rt1.bottom); //迟到(分)
  360. rt8.SetRect(rt7.right, rt1.top, rt7.right + nItemWide, rt1.bottom); //早退(分)
  361. rt9.SetRect(rt8.right, rt1.top, rt8.right + nItemWide, rt1.bottom); //旷工(分)
  362. rt10.SetRect(rt9.right, rt1.top, rc.right, rt1.bottom); //请假(分)
  363. memDC.DrawText(_T("编 号"), &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  364. memDC.DrawText(_T("姓 名"), &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  365. memDC.DrawText(_T("考勤日期"), &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  366. memDC.DrawText(_T("班 次"), &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  367. memDC.DrawText(_T("时 段"), &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  368. memDC.DrawText(_T("考勤时间"), &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  369. memDC.DrawText(_T("迟到(分)"), &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  370. memDC.DrawText(_T("早退(分)"), &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  371. memDC.DrawText(_T("旷工(分)"), &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  372. memDC.DrawText(_T("请假(分)"), &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  373. memDC.MoveTo(rt1.right, rt1.top);
  374. memDC.LineTo(rt1.right, rt1.bottom);
  375. memDC.MoveTo(rt2.right, rt1.top);
  376. memDC.LineTo(rt2.right, rt1.bottom);
  377. memDC.MoveTo(rt3.right, rt1.top);
  378. memDC.LineTo(rt3.right, rt1.bottom);
  379. memDC.MoveTo(rt4.right, rt1.top);
  380. memDC.LineTo(rt4.right, rt1.bottom);
  381. memDC.MoveTo(rt5.right, rt1.top);
  382. memDC.LineTo(rt5.right, rt1.bottom);
  383. memDC.MoveTo(rt6.right, rt1.top);
  384. memDC.LineTo(rt6.right, rt1.bottom);
  385. memDC.MoveTo(rt7.right, rt1.top);
  386. memDC.LineTo(rt7.right, rt1.bottom);
  387. memDC.MoveTo(rt8.right, rt1.top);
  388. memDC.LineTo(rt8.right, rt1.bottom);
  389. memDC.MoveTo(rt9.right, rt1.top);
  390. memDC.LineTo(rt9.right, rt1.bottom);
  391. memDC.MoveTo(rc.left, rt1.bottom);
  392. memDC.LineTo(rc.right, rt1.bottom);
  393. CString strID, strName, strDate, strSID, strTime, strAttTime, strLate, strEarlier, strAbsent, strLeave;
  394. rc.SetRect(nLeft, nTop+fAdd, nRight, nTop+2*fAdd);
  395. rt1.SetRect(nLeft+nTextAdd, rc.top, rc.right-12.2*nItemWide, rc.bottom);
  396. rt2.SetRect(rt1.right+nTextAdd, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom);
  397. rt3.SetRect(rt2.right+nTextAdd, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom);
  398. rt4.SetRect(rt3.right+nTextAdd, rt1.top, rt3.right + 2*nItemWide, rt1.bottom);
  399. rt5.SetRect(rt4.right+nTextAdd, rt1.top, rt4.right + 1.6*nItemWide, rt1.bottom);
  400. rt6.SetRect(rt5.right+nTextAdd, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom);
  401. rt7.SetRect(rt6.right+nTextAdd, rt1.top, rt6.right + nItemWide, rt1.bottom);
  402. rt8.SetRect(rt7.right+nTextAdd, rt1.top, rt7.right + nItemWide, rt1.bottom);
  403. rt9.SetRect(rt8.right+nTextAdd, rt1.top, rt8.right + nItemWide, rt1.bottom);
  404. rt10.SetRect(rt9.right+nTextAdd, rt1.top, rc.right, rt1.bottom);
  405. int nCountItem = pGridCtrl->GetRowCount();
  406. for(int i=1;i<nItem; i++)
  407. {
  408. strID = pGridCtrl->GetItemText(i+iStart, 1);
  409. strName = pGridCtrl->GetItemText(i+iStart, 2);
  410. strDate = pGridCtrl->GetItemText(i+iStart, 3);
  411. strSID = pGridCtrl->GetItemText(i+iStart, 4);
  412. strTime = pGridCtrl->GetItemText(i+iStart, 5);
  413. strAttTime = pGridCtrl->GetItemText(i+iStart, 6);
  414. strLate = pGridCtrl->GetItemText(i+iStart, 7);
  415. strEarlier = pGridCtrl->GetItemText(i+iStart, 8);
  416. strAbsent = pGridCtrl->GetItemText(i+iStart, 9);
  417. strLeave = pGridCtrl->GetItemText(i+iStart, 10);
  418. memDC.DrawText(strID, &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  419. memDC.DrawText(strName, &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  420. memDC.DrawText(strDate, &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  421. memDC.DrawText(strSID, &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  422. memDC.DrawText(strTime, &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  423. memDC.DrawText(strAttTime, &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  424. memDC.DrawText(strLate, &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  425. memDC.DrawText(strEarlier, &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  426. memDC.DrawText(strAbsent, &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  427. memDC.DrawText(strLeave, &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  428. //下横线
  429. memDC.MoveTo(rc.left, rc.bottom);
  430. memDC.LineTo(rc.right, rc.bottom);
  431. memDC.MoveTo(rt1.right, rt1.top);
  432. memDC.LineTo(rt1.right, rt1.bottom);
  433. memDC.MoveTo(rt2.right, rt1.top);
  434. memDC.LineTo(rt2.right, rt1.bottom);
  435. memDC.MoveTo(rt3.right, rt1.top);
  436. memDC.LineTo(rt3.right, rt1.bottom);
  437. memDC.MoveTo(rt4.right, rt1.top);
  438. memDC.LineTo(rt4.right, rt1.bottom);
  439. memDC.MoveTo(rt5.right, rt1.top);
  440. memDC.LineTo(rt5.right, rt1.bottom);
  441. memDC.MoveTo(rt6.right, rt1.top);
  442. memDC.LineTo(rt6.right, rt1.bottom);
  443. memDC.MoveTo(rt7.right, rt1.top);
  444. memDC.LineTo(rt7.right, rt1.bottom);
  445. memDC.MoveTo(rt8.right, rt1.top);
  446. memDC.LineTo(rt8.right, rt1.bottom);
  447. memDC.MoveTo(rt9.right, rt1.top);
  448. memDC.LineTo(rt9.right, rt1.bottom);
  449. memDC.MoveTo(rc.left, rt1.bottom);
  450. memDC.LineTo(rc.right, rt1.bottom);
  451. rc.top += fAdd;
  452. rc.bottom += fAdd;
  453. rt1.top = rc.top;
  454. rt1.bottom = rc.bottom;
  455. rt2.top = rt1.top;
  456. rt2.bottom = rt1.bottom;
  457. rt3.top = rt1.top;
  458. rt3.bottom = rt1.bottom;
  459. rt4.top = rt1.top;
  460. rt4.bottom = rt1.bottom;
  461. rt5.top = rt1.top;
  462. rt5.bottom = rt1.bottom;
  463. rt6.top = rt1.top;
  464. rt6.bottom = rt1.bottom;
  465. rt7.top = rt1.top;
  466. rt7.bottom = rt1.bottom;
  467. rt8.top = rt1.top;
  468. rt8.bottom = rt1.bottom;
  469. rt9.top = rt1.top;
  470. rt9.bottom = rt1.bottom;
  471. rt10.top = rt1.top;
  472. rt10.bottom = rt1.bottom;
  473. if((i+iStart+1)>=nCountItem)
  474. break;
  475. }
  476. //结尾
  477. memDC.MoveTo(rc.left, nTop);
  478. memDC.LineTo(rc.left, rc.top);
  479. memDC.MoveTo(rc.right, nTop);
  480. memDC.LineTo(rc.right, rc.top);
  481. memDC.DrawText(csLFinality, &rc, DT_LEFT| DT_VCENTER | DT_SINGLELINE);
  482. memDC.DrawText(csRFinality, &rc, DT_RIGHT| DT_VCENTER | DT_SINGLELINE);
  483. memDC.SelectObject(oldfont);
  484. memDC.SelectObject(hPenOld);
  485. }
  486. TitleFont.DeleteObject();
  487. DetailFont.DeleteObject();
  488. cPen.DeleteObject();
  489. }
void CAttendReportDlg::PrintData()
{
CGridCtrlEx *pGridCtrl = NULL;
BOOL bDay = FALSE;
if ( ((CButton*)GetDlgItem(IDC_RADIO_DAY))->GetCheck() )
{
pGridCtrl = m_pDayGridCtrl;
bDay = TRUE;
}
else if ( ((CButton*)GetDlgItem(IDC_RADIO_MONTH))->GetCheck() )
{
pGridCtrl = m_pMonGridCtrl;
} if( pGridCtrl->GetRowCount() <= 1 ) // 没有记录
return; ///选择打印机对话框
CDC MemDc;
HDC hdcPrint = NULL;
CPrintDialog dlg(FALSE);
if (m_bPrint) //打印按钮,不弹出选择对话框,获取默认打印设备
{
PRINTDLG printInfo;
ZeroMemory(&printInfo,sizeof(printInfo)); //清空该结构
printInfo.lStructSize = sizeof(printInfo);
printInfo.hwndOwner = 0;
printInfo.hDevMode = 0;
printInfo.hDevNames = 0;
//这个是关键,PD_RETURNDC 如果不设这个标志,就拿不到hDC了
//PD_RETURNDEFAULT 这个就是得到默认打印机,不需要弹出设置对话框
printInfo.Flags = PD_RETURNDC | PD_RETURNDEFAULT | PD_ALLPAGES; PrintDlg(&printInfo);//调用API拿出默认打印机
DWORD rst = CommDlgExtendedError();//看看出错没有
if(rst != 0)
{//出错了,清空标志再次调用API,此时就会弹出打印设置对话框供用户选择了
printInfo.Flags = 0;
PrintDlg(&printInfo);
} hdcPrint=printInfo.hDC; //得到打印DC,输出到打印
}
else //弹出对话框选择打印设备
{
dlg.DoModal();
hdcPrint = dlg.GetPrinterDC();
} if(hdcPrint == NULL)
{
NotifyDlg Ndlg(_T("打印机初始化失败!"));
Ndlg.DoModal();
return;
} MemDc.Attach(hdcPrint);
nPaperSize_X = MemDc.GetDeviceCaps(HORZSIZE); // 纸张宽度
nPaperSize_Y = MemDc.GetDeviceCaps(VERTSIZE); // 纸张高度
int xP = GetDeviceCaps(MemDc.m_hDC, LOGPIXELSX); //x方向每英寸像素点数
int yP = GetDeviceCaps(MemDc.m_hDC, LOGPIXELSY); //y方向每英寸像素点数
int xPix = (DOUBLE)xP*10/254; //每 mm 宽度的像素
int yPix = (DOUBLE)yP*10/254; //每 mm 高度的像素
DOUBLE fAdd = 5*yPix; //每格递增量
nOneLines = (nPaperSize_Y * 0.85*yPix)/fAdd;
nNextLines = (nPaperSize_Y * 0.85*yPix)/fAdd+1; PRNINFO PrnInfo = {0};
PrnInfo.hListView = NULL;
PrnInfo.hWnd = this->m_hWnd;
PrnInfo.IsPrint = m_bPrint;
PrnInfo.nCurPage = 1;
PrnInfo.nMaxLine = pGridCtrl->GetRowCount()-1;
PrnInfo.pObj = pGridCtrl; CPreviewParentDlg DlgPreView;
CPreviewChildDlg DlgChildPreView;
if (bDay)
{
DlgPreView.SetCallBackFun(PrintDayInfo, PrnInfo); //回调函数,设置打印或预览函数,及纸张排版信息
DlgChildPreView.SetCallBackFun(PrintDayInfo, PrnInfo);
}
else
{
DlgPreView.SetCallBackFun(PrintMonInfo, PrnInfo);
DlgChildPreView.SetCallBackFun(PrintMonInfo, PrnInfo);
} if (!m_bPrint)
{
DlgPreView.DoModal();
}
else
{
DlgChildPreView.PrintDoc();
}
MemDc.DeleteDC();
} void CAttendReportDlg::PrintDayInfo( CDC &memDC, PRNINFO PrnInfo )
{
if(memDC.m_hDC == NULL)
return; int nCurPage = PrnInfo.nCurPage; //当前页
BOOL IsPrint = PrnInfo.IsPrint; //是否打印
int nMaxPage = PrnInfo.nCountPage; //最大页码
HWND hWnd = PrnInfo.hWnd;
CString csLFinality, csRFinality;
CGridCtrlEx *pGridCtrl = PrnInfo.pObj;
CTime time = CTime::GetCurrentTime();
csLFinality = time.Format(_T("%Y-%m-%d %H:%M:%S"));
csLFinality = _T("报表日期:") + csLFinality;
csRFinality.Format(_T("第 %i 页/共 %i 页"), nCurPage, nMaxPage); TCHAR szTitle[] = _T("考 勤 日 报 表");
CRect rc, rt1, rt2, rt3, rt4, rt5, rt6, rt7, rt8, rt9, rt10;
CPen *hPenOld;
CPen cPen;
CFont TitleFont, DetailFont, *oldfont;
//标题字体
TitleFont.CreateFont(-MulDiv(14,memDC.GetDeviceCaps(LOGPIXELSY),72),
0,0,0,FW_NORMAL,0,0,0,GB2312_CHARSET,
OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY,
VARIABLE_PITCH|FF_SWISS,_T("黑体"));
//细节字体
DetailFont.CreateFont(-MulDiv(10,memDC.GetDeviceCaps(LOGPIXELSY),92),
0,0,0,FW_NORMAL,0,0,0,GB2312_CHARSET,
OUT_STROKE_PRECIS,CLIP_STROKE_PRECIS,DRAFT_QUALITY,
VARIABLE_PITCH|FF_SWISS,_T("宋体"));
//粗笔
cPen.CreatePen(PS_SOLID, 2, RGB(0, 0, 0)); int xP = GetDeviceCaps(memDC.m_hDC, LOGPIXELSX); //x方向每英寸像素点数
int yP = GetDeviceCaps(memDC.m_hDC, LOGPIXELSY); //y方向每英寸像素点数 DOUBLE xPix = (DOUBLE)xP*10/254; //每 mm 宽度的像素
DOUBLE yPix = (DOUBLE)yP*10/254; //每 mm 高度的像素
DOUBLE fAdd = 5*yPix; //每格递增量
DOUBLE nTop = 30*yPix; //第一页最上线
int iStart = 0; //从第几行开始读取
DOUBLE nBottom = nTop+nOneLines*fAdd;
if(nCurPage != 1)
nTop = 30*yPix-fAdd; //非第一页最上线
if(nCurPage == 2)
iStart = nOneLines;
if(nCurPage>2)
iStart = nOneLines+(nCurPage - 2)*nNextLines; DOUBLE nLeft = 15*xPix; //最左线
DOUBLE nRight = xPix*(nPaperSize_X-15); //最右线
DOUBLE nItemWide = ((nPaperSize_X-30)/14)*xPix; DOUBLE nTextAdd = 1.5*xPix; if(IsPrint)
{
//真正打印部分
static DOCINFO di = {sizeof (DOCINFO), szTitle} ;
//开始文档打印///////////////////////////////////////// start print
//////////////////////////////////////////////////////////
if(memDC.StartDoc( &di ) < 0) // startdoc-----enddoc
{
NotifyDlg dlg(_T("连接到打印机化败!"));
dlg.DoModal();
}
else
{
iStart = 0;
nTop = 30*yPix; //第一页最上线
for(int iTotalPages = 1; iTotalPages<=nMaxPage; iTotalPages++)
{
int nCurPage = iTotalPages;
csRFinality.Format(_T("第 %i 页/共 %i 页"), nCurPage, nMaxPage);
time=CTime::GetCurrentTime();
csLFinality = time.Format(_T("%Y-%m-%d %H:%M:%S"));
csLFinality = _T("报表日期:") + csLFinality; if(nCurPage != 1)
nTop = 30*yPix-fAdd; //非第一页最上线
if(nCurPage == 2)
iStart = nOneLines;
if(nCurPage>2)
iStart = nOneLines+(nCurPage - 2)*nNextLines;
//开始页
if(memDC.StartPage() < 0)
{
NotifyDlg dlg(_T("打印失败!"));
dlg.DoModal();
memDC.AbortDoc();
return;
}
else
{
//打印
//标题
oldfont = memDC.SelectObject(&TitleFont);
int nItem = nNextLines;
if(nCurPage == 1)
{
nItem = nOneLines;
rc.SetRect(0, yPix*15, nPaperSize_X*xPix, yPix*25);
memDC.DrawText(szTitle, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
//细节
memDC.SelectObject(&DetailFont);
rc.SetRect(nLeft, nTop, nRight, nTop+fAdd);
//上横线
memDC.MoveTo(rc.left, rc.top);
memDC.LineTo(rc.right, rc.top); rt1.SetRect(nLeft, nTop, rc.right -12.4*nItemWide , nTop+fAdd); //编 号
rt2.SetRect(rt1.right, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom); //姓名
rt3.SetRect(rt2.right, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom); //考勤日期
rt4.SetRect(rt3.right, rt1.top, rt3.right + 2.2*nItemWide, rt1.bottom); //班次
rt5.SetRect(rt4.right, rt1.top, rt4.right + 1.6*nItemWide, rt1.bottom); //时段
rt6.SetRect(rt5.right, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom); //考勤时间
rt7.SetRect(rt6.right, rt1.top, rt6.right + nItemWide, rt1.bottom); //迟到(分)
rt8.SetRect(rt7.right, rt1.top, rt7.right + nItemWide, rt1.bottom); //早退(分)
rt9.SetRect(rt8.right, rt1.top, rt8.right + nItemWide, rt1.bottom); //旷工(分)
rt10.SetRect(rt9.right, rt1.top, rc.right, rt1.bottom); //请假(分)
memDC.DrawText(_T("编 号"), &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("姓 名"), &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("考勤日期"), &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("班 次"), &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("时 段"), &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("考勤时间"), &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("迟到(分)"), &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("早退(分)"), &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("旷工(分)"), &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("请假(分)"), &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE); memDC.MoveTo(rt1.right, rt1.top);
memDC.LineTo(rt1.right, rt1.bottom);
memDC.MoveTo(rt2.right, rt1.top);
memDC.LineTo(rt2.right, rt1.bottom);
memDC.MoveTo(rt3.right, rt1.top);
memDC.LineTo(rt3.right, rt1.bottom);
memDC.MoveTo(rt4.right, rt1.top);
memDC.LineTo(rt4.right, rt1.bottom);
memDC.MoveTo(rt5.right, rt1.top);
memDC.LineTo(rt5.right, rt1.bottom);
memDC.MoveTo(rt6.right, rt1.top);
memDC.LineTo(rt6.right, rt1.bottom);
memDC.MoveTo(rt7.right, rt1.top);
memDC.LineTo(rt7.right, rt1.bottom);
memDC.MoveTo(rt8.right, rt1.top);
memDC.LineTo(rt8.right, rt1.bottom);
memDC.MoveTo(rt9.right, rt1.top);
memDC.LineTo(rt9.right, rt1.bottom);
memDC.MoveTo(rc.left, rt1.bottom);
memDC.LineTo(rc.right, rt1.bottom); CString strID, strName, strDate, strSID, strTime, strAttTime, strLate, strEarlier, strAbsent, strLeave;
rc.SetRect(nLeft, nTop+fAdd, nRight, nTop+2*fAdd);
rt1.SetRect(nLeft+nTextAdd, rc.top, rc.right-12.4*nItemWide, rc.bottom);
rt2.SetRect(rt1.right+nTextAdd, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom);
rt3.SetRect(rt2.right+nTextAdd, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom);
rt4.SetRect(rt3.right+nTextAdd, rt1.top, rt3.right + 2.2*nItemWide, rt1.bottom);
rt5.SetRect(rt4.right+nTextAdd, rt1.top, rt4.right +1.6*nItemWide, rt1.bottom);
rt6.SetRect(rt5.right+nTextAdd, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom);
rt7.SetRect(rt6.right+nTextAdd, rt1.top, rt6.right + nItemWide, rt1.bottom);
rt8.SetRect(rt7.right+nTextAdd, rt1.top, rt7.right + nItemWide, rt1.bottom);
rt9.SetRect(rt8.right+nTextAdd, rt1.top, rt8.right + nItemWide, rt1.bottom);
rt10.SetRect(rt9.right+nTextAdd, rt1.top, rc.right, rt1.bottom); int nCountItem = pGridCtrl->GetRowCount();
for(int i=1;i<nItem; i++)
{
strID = pGridCtrl->GetItemText(i+iStart, 1);
strName = pGridCtrl->GetItemText(i+iStart, 2);
strDate = pGridCtrl->GetItemText(i+iStart, 3);
strSID = pGridCtrl->GetItemText(i+iStart, 4);
strTime = pGridCtrl->GetItemText(i+iStart, 5);
strAttTime = pGridCtrl->GetItemText(i+iStart, 6);
strLate = pGridCtrl->GetItemText(i+iStart, 7);
strEarlier = pGridCtrl->GetItemText(i+iStart, 8);
strAbsent = pGridCtrl->GetItemText(i+iStart, 9);
strLeave = pGridCtrl->GetItemText(i+iStart, 10); memDC.DrawText(strID, &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strName, &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strDate, &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strSID, &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strTime, &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strAttTime, &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strLate, &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strEarlier, &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strAbsent, &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strLeave, &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
//下横线
memDC.MoveTo(rc.left, rc.bottom);
memDC.LineTo(rc.right, rc.bottom);
memDC.MoveTo(rt1.right, rt1.top);
memDC.LineTo(rt1.right, rt1.bottom);
memDC.MoveTo(rt2.right, rt1.top);
memDC.LineTo(rt2.right, rt1.bottom);
memDC.MoveTo(rt3.right, rt1.top);
memDC.LineTo(rt3.right, rt1.bottom);
memDC.MoveTo(rt4.right, rt1.top);
memDC.LineTo(rt4.right, rt1.bottom);
memDC.MoveTo(rt5.right, rt1.top);
memDC.LineTo(rt5.right, rt1.bottom);
memDC.MoveTo(rt6.right, rt1.top);
memDC.LineTo(rt6.right, rt1.bottom);
memDC.MoveTo(rt7.right, rt1.top);
memDC.LineTo(rt7.right, rt1.bottom);
memDC.MoveTo(rt8.right, rt1.top);
memDC.LineTo(rt8.right, rt1.bottom);
memDC.MoveTo(rt9.right, rt1.top);
memDC.LineTo(rt9.right, rt1.bottom);
memDC.MoveTo(rc.left, rt1.bottom);
memDC.LineTo(rc.right, rt1.bottom); rc.top += fAdd;
rc.bottom += fAdd;
rt1.top = rc.top;
rt1.bottom = rc.bottom;
rt2.top = rt1.top;
rt2.bottom = rt1.bottom;
rt3.top = rt1.top;
rt3.bottom = rt1.bottom;
rt4.top = rt1.top;
rt4.bottom = rt1.bottom;
rt5.top = rt1.top;
rt5.bottom = rt1.bottom;
rt6.top = rt1.top;
rt6.bottom = rt1.bottom;
rt7.top = rt1.top;
rt7.bottom = rt1.bottom;
rt8.top = rt1.top;
rt8.bottom = rt1.bottom;
rt9.top = rt1.top;
rt9.bottom = rt1.bottom;
rt10.top = rt1.top;
rt10.bottom = rt1.bottom; if((i+iStart+1)>=nCountItem)
break;
}
//结尾
memDC.MoveTo(rc.left, nTop);
memDC.LineTo(rc.left, rc.top);
memDC.MoveTo(rc.right, nTop);
memDC.LineTo(rc.right, rc.top);
memDC.DrawText(csLFinality, &rc, DT_LEFT | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(csRFinality, &rc, DT_RIGHT| DT_VCENTER | DT_SINGLELINE);
memDC.EndPage();
memDC.SelectObject(oldfont);
}
}
memDC.EndDoc();
}
}
else
{
////////////////////打印预览
//边框线
hPenOld = memDC.SelectObject(&cPen);
rc.SetRect(0, 0, nPaperSize_X*xPix, nPaperSize_Y*yPix);
memDC.Rectangle(&rc);
memDC.SelectObject(hPenOld);
//标题
oldfont = memDC.SelectObject(&TitleFont);
int nItem = nNextLines;
if(nCurPage == 1)
{
nItem = nOneLines;
rc.SetRect(0, yPix*15, nPaperSize_X*xPix, yPix*25);
memDC.DrawText(szTitle, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
//细节
memDC.SelectObject(&DetailFont);
rc.SetRect(nLeft, nTop, nRight, nTop+fAdd);
//上横线
memDC.MoveTo(rc.left, rc.top);
memDC.LineTo(rc.right, rc.top); rt1.SetRect(nLeft, nTop, rc.right -12.2*nItemWide, nTop+fAdd); //编 号
rt2.SetRect(rt1.right, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom); //姓名
rt3.SetRect(rt2.right, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom); //考勤日期
rt4.SetRect(rt3.right, rt1.top, rt3.right + 2*nItemWide, rt1.bottom); //班次
rt5.SetRect(rt4.right, rt1.top, rt4.right + 1.6*nItemWide, rt1.bottom); //时段
rt6.SetRect(rt5.right, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom); //考勤时间
rt7.SetRect(rt6.right, rt1.top, rt6.right + nItemWide, rt1.bottom); //迟到(分)
rt8.SetRect(rt7.right, rt1.top, rt7.right + nItemWide, rt1.bottom); //早退(分)
rt9.SetRect(rt8.right, rt1.top, rt8.right + nItemWide, rt1.bottom); //旷工(分)
rt10.SetRect(rt9.right, rt1.top, rc.right, rt1.bottom); //请假(分)
memDC.DrawText(_T("编 号"), &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("姓 名"), &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("考勤日期"), &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("班 次"), &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("时 段"), &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("考勤时间"), &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("迟到(分)"), &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("早退(分)"), &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("旷工(分)"), &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(_T("请假(分)"), &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE); memDC.MoveTo(rt1.right, rt1.top);
memDC.LineTo(rt1.right, rt1.bottom);
memDC.MoveTo(rt2.right, rt1.top);
memDC.LineTo(rt2.right, rt1.bottom);
memDC.MoveTo(rt3.right, rt1.top);
memDC.LineTo(rt3.right, rt1.bottom);
memDC.MoveTo(rt4.right, rt1.top);
memDC.LineTo(rt4.right, rt1.bottom);
memDC.MoveTo(rt5.right, rt1.top);
memDC.LineTo(rt5.right, rt1.bottom);
memDC.MoveTo(rt6.right, rt1.top);
memDC.LineTo(rt6.right, rt1.bottom);
memDC.MoveTo(rt7.right, rt1.top);
memDC.LineTo(rt7.right, rt1.bottom);
memDC.MoveTo(rt8.right, rt1.top);
memDC.LineTo(rt8.right, rt1.bottom);
memDC.MoveTo(rt9.right, rt1.top);
memDC.LineTo(rt9.right, rt1.bottom);
memDC.MoveTo(rc.left, rt1.bottom);
memDC.LineTo(rc.right, rt1.bottom); CString strID, strName, strDate, strSID, strTime, strAttTime, strLate, strEarlier, strAbsent, strLeave;
rc.SetRect(nLeft, nTop+fAdd, nRight, nTop+2*fAdd);
rt1.SetRect(nLeft+nTextAdd, rc.top, rc.right-12.2*nItemWide, rc.bottom);
rt2.SetRect(rt1.right+nTextAdd, rt1.top, rt1.right + 1.5*nItemWide, rt1.bottom);
rt3.SetRect(rt2.right+nTextAdd, rt1.top, rt2.right + 1.5*nItemWide, rt1.bottom);
rt4.SetRect(rt3.right+nTextAdd, rt1.top, rt3.right + 2*nItemWide, rt1.bottom);
rt5.SetRect(rt4.right+nTextAdd, rt1.top, rt4.right + 1.6*nItemWide, rt1.bottom);
rt6.SetRect(rt5.right+nTextAdd, rt1.top, rt5.right + 1.6*nItemWide, rt1.bottom);
rt7.SetRect(rt6.right+nTextAdd, rt1.top, rt6.right + nItemWide, rt1.bottom);
rt8.SetRect(rt7.right+nTextAdd, rt1.top, rt7.right + nItemWide, rt1.bottom);
rt9.SetRect(rt8.right+nTextAdd, rt1.top, rt8.right + nItemWide, rt1.bottom);
rt10.SetRect(rt9.right+nTextAdd, rt1.top, rc.right, rt1.bottom); int nCountItem = pGridCtrl->GetRowCount();
for(int i=1;i<nItem; i++)
{
strID = pGridCtrl->GetItemText(i+iStart, 1);
strName = pGridCtrl->GetItemText(i+iStart, 2);
strDate = pGridCtrl->GetItemText(i+iStart, 3);
strSID = pGridCtrl->GetItemText(i+iStart, 4);
strTime = pGridCtrl->GetItemText(i+iStart, 5);
strAttTime = pGridCtrl->GetItemText(i+iStart, 6);
strLate = pGridCtrl->GetItemText(i+iStart, 7);
strEarlier = pGridCtrl->GetItemText(i+iStart, 8);
strAbsent = pGridCtrl->GetItemText(i+iStart, 9);
strLeave = pGridCtrl->GetItemText(i+iStart, 10); memDC.DrawText(strID, &rt1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strName, &rt2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strDate, &rt3, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strSID, &rt4, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strTime, &rt5, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strAttTime, &rt6, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strLate, &rt7, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strEarlier, &rt8, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strAbsent, &rt9, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(strLeave, &rt10, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
//下横线
memDC.MoveTo(rc.left, rc.bottom);
memDC.LineTo(rc.right, rc.bottom);
memDC.MoveTo(rt1.right, rt1.top);
memDC.LineTo(rt1.right, rt1.bottom);
memDC.MoveTo(rt2.right, rt1.top);
memDC.LineTo(rt2.right, rt1.bottom);
memDC.MoveTo(rt3.right, rt1.top);
memDC.LineTo(rt3.right, rt1.bottom);
memDC.MoveTo(rt4.right, rt1.top);
memDC.LineTo(rt4.right, rt1.bottom);
memDC.MoveTo(rt5.right, rt1.top);
memDC.LineTo(rt5.right, rt1.bottom);
memDC.MoveTo(rt6.right, rt1.top);
memDC.LineTo(rt6.right, rt1.bottom);
memDC.MoveTo(rt7.right, rt1.top);
memDC.LineTo(rt7.right, rt1.bottom);
memDC.MoveTo(rt8.right, rt1.top);
memDC.LineTo(rt8.right, rt1.bottom);
memDC.MoveTo(rt9.right, rt1.top);
memDC.LineTo(rt9.right, rt1.bottom);
memDC.MoveTo(rc.left, rt1.bottom);
memDC.LineTo(rc.right, rt1.bottom); rc.top += fAdd;
rc.bottom += fAdd;
rt1.top = rc.top;
rt1.bottom = rc.bottom;
rt2.top = rt1.top;
rt2.bottom = rt1.bottom;
rt3.top = rt1.top;
rt3.bottom = rt1.bottom;
rt4.top = rt1.top;
rt4.bottom = rt1.bottom;
rt5.top = rt1.top;
rt5.bottom = rt1.bottom;
rt6.top = rt1.top;
rt6.bottom = rt1.bottom;
rt7.top = rt1.top;
rt7.bottom = rt1.bottom;
rt8.top = rt1.top;
rt8.bottom = rt1.bottom;
rt9.top = rt1.top;
rt9.bottom = rt1.bottom;
rt10.top = rt1.top;
rt10.bottom = rt1.bottom; if((i+iStart+1)>=nCountItem)
break;
}
//结尾
memDC.MoveTo(rc.left, nTop);
memDC.LineTo(rc.left, rc.top);
memDC.MoveTo(rc.right, nTop);
memDC.LineTo(rc.right, rc.top);
memDC.DrawText(csLFinality, &rc, DT_LEFT| DT_VCENTER | DT_SINGLELINE);
memDC.DrawText(csRFinality, &rc, DT_RIGHT| DT_VCENTER | DT_SINGLELINE); memDC.SelectObject(oldfont);
memDC.SelectObject(hPenOld);
}
TitleFont.DeleteObject();
DetailFont.DeleteObject();
cPen.DeleteObject();
}

MFC 实现打印机打印功能的更多相关文章

  1. 【转】Android打印机--没有设备驱动sdk,自己实现USB打印功能

    原文:http://blog.csdn.net/johnwcheung/article/details/71576833 Android下的设备调试,如果设备提供了驱动,按照厂家的驱动调试即可:设备未 ...

  2. vc 实现打印功能

    Visual C++6.0是开发Windows应用程序的强大工具,但是要通过它实现程序的打印功能,一直是初学者的一个难点,经常有朋友询问如何在VC中实现打印功能,他们往往感到在MFC提供的框架内实现这 ...

  3. C#程序调用CodeSoft预先设计好的标签模块实现打印功能

    if (this.tbSetLabel.Text.Trim() == "") { MessageBox.Show("请先 Enter 选择标签模板文件!", & ...

  4. 根据第三方库spire.pdf使用指定打印机打印pdf文件

    private void button1_Click(object sender, EventArgs e) { PdfDocument doc = new PdfDocument(); string ...

  5. 完美演绎DevExpress XtraPrinting Library 的打印功能

    完美演绎DevExpress XtraPrinting Library 的打印功能 2010-05-14 17:40:49|  分类: 默认分类|字号 订阅     设计报告不仅费时间,而且还乏味!但 ...

  6. aspose调用打印机打印文档

    aspose很不错的插件,功能非常强大,用到了其中的aspose.word. 如何生成word文档,点击. 下面说说如何如何通过打印机打印文档. aspose提供了一个print方法,通过该方法可以直 ...

  7. JS达到Web指定保存的和打印功能的内容

    背景 首先,说说文章的背景.近期手中的一个项目,因为需求中要求提供Web界面的打印功能.当然假设没有打印机,还能够提供保存到本地.项目组长把这个"小任务"分给了我.本着努力为组长分 ...

  8. 网站开发进阶(十二)JS实现打印功能(包括打印预览、打印设置等)

    JS实现打印功能(包括打印预览.打印设置等) 绪 最近在进行项目开发时,需要实现后台管理端打印功能,遂在网上一阵搜索,搜到了很多相关的文章.其中绝大部分文章都是使用的Lodop5.0(Web打印和套打 ...

  9. WPF备忘录(6)WPF实现打印功能

    在WPF 中可以通过PrintDialog 类方便的实现应用程序打印功能,本文将使用一个简单实例进行演示.首先在VS中编辑一个图形(如下图所示). 将需要打印的内容放入同一个<Canvas> ...

随机推荐

  1. 统计输入任意的字符中中英文字母,空格和其他字符的个数 python

    这里用到了三个函数: #判断是否为数字:str.isdigit()#是否为字母:str.isalpha()#是否为空格:str.isspace() def tongji(str): alpha = 0 ...

  2. redis学习1(nosql)

    一. 互联网时代背景下大机遇,为什么用nosql 1.单机MySQL的美好年代 在90年代,一个网站的访问量一般都不大,用单个数据库完全可以轻松应付.在那个时候,更多的都是静态网页,动态交互类型的网站 ...

  3. Git ---游离状态下的commit 分支切换与找回,commit之后无法找到历史记录

    commit之后无法找到历史记录 https://blog.csdn.net/zyb2017/article/details/78307688

  4. 通过IIS共享文件夹来实现静态资源"本地分布式"部署

    以下以文件型数据库(如sqlite)为例 楼主话:以下内容,若有不专业处,大胆喷,虚心求教. 起因:要进行一个项目的分布式部署,而这个项目所涉及的其中一个数据库为sqlite(经测试,同为文件型数据库 ...

  5. 大话CNN经典模型:LeNet

        近几年来,卷积神经网络(Convolutional Neural Networks,简称CNN)在图像识别中取得了非常成功的应用,成为深度学习的一大亮点.CNN发展至今,已经有很多变种,其中有 ...

  6. Java密码学综述---密码学基本功能

    机密性 只有发送方与指定接收方才能理解报文的内容,监听者只能截取到加密后的报文信息,但不能还原报文的内容,做到了保密 鉴别 发送方与接收方都应该能证实通信过程所涉及的另一方,通信的另一方确实具有它们所 ...

  7. 【02】webstorm配置babel转换器+截图(by魔芋)

    [02]webstorm配置babel转换器+截图(by魔芋)   [02]魔芋的安装过程     01,配置babel.   02,用webstorm.注意webstorm的版本号.   03,使用 ...

  8. Eclipse 菜单---Eclipse教程第04课

    Eclipse 查看的菜单栏通常包含以下几个菜单: File 菜单 Edit 菜单 Navigate 菜单 Search 菜单 Project 菜单 Run 菜单 Window 菜单 Help 菜单 ...

  9. Windows系统安装测试redis

    因本人电脑是windows系统,从https://github.com/ServiceStack/redis-windows下载了兼容windows系统的redis 下载后直接解压到D:\redis目 ...

  10. 《Cracking the Coding Interview》——第9章:递归和动态规划——题目1

    2014-03-20 02:55 题目:小朋友跳台阶,每次跳1层或2层,那么跳N层总共有多少种跳法. 解法:斐波那契数列. 代码: // 9.1 A child can run up the stai ...