打印功能实现

electron实现打印功能,支持静默打印、无感打印 会接受两个参数,第一个参数是事件对象,第二个参数是发布事件时传递的参数,而这个参数最终会通过路由的方式传递到打印的新窗口中。所以会判断时候存在这个新窗口,如果存在就要隐藏并销毁掉,这样可以保证我们每次点击打印按钮时都会是最新的隐藏的窗口。订阅的参数会作为路由的query参数拼接到路径上面,print组件就可以拿到点击组件打印传递的参数。事件中将新窗口隐藏掉,这样做的好处是这个新窗口一直都是隐藏的,从而实现无感打印。窗口,将要打印的内容放进新窗口中,这样我们就可以实现打印指定内容的功能。 阅读详情

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、添加代码,编译运行程序。

 

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

在打印预览对话框类中

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


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

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









不弹出打印对话框直接打印:



char  szprinter[80];
     char  *szDevice,*szDriver,*szOutput;
     HDC  hdcprint;  // 定义一个设备环境句柄
     //定义一个打印作业
     DOCINFO di = { sizeof (DOCINFO), "printer" ,NULL};
     // 得到设备字符串存入数组szprinter中
     GetProfileString( "windows" , "device" , ",,," ,szprinter,80);
     // 将设备字符串分解
     if (NULL != (szDevice =  strtok (szprinter, "," )) 
         && NULL != (szDriver =  strtok (NULL, "," )) 
         && NULL != (szOutput =  strtok (NULL, "," ))) 
     {
         // 创建一个打印机设备句柄 
         if ((hdcprint = CreateDC(szDriver,szDevice,szOutput,NULL)) != 0) 
         { 
             CRect rc, rt1, rt2, rt3, rt4, rt5, rt6;
             if (StartDoc(hdcprint,&di) > 0)  //开始执行一个打印作业 
             { 
                 StartPage(hdcprint);  //打印机走纸,开始打印 
                 SaveDC(hdcprint);  //保存打印机设备句柄 
                 //输出内容
                 TextOut(hdcprint,250,260, "处方号:091-4" ,13); 
                 
                                 ................
                                  RestoreDC(hdcprint,-1);  //恢复打印机设备句柄 
 
                 EndPage(hdcprint);  //打印机停纸,停止打印 
                 EndDoc(hdcprint);  //结束一个打印作业 
                 //MessageBox("打印完毕!","提示",MB_ICONINFORMATION); 
             }
             // 用API函数DeleteDC销毁一个打印机设备句柄 
             DeleteDC(hdcprint); 
         } 
         else 
         { 
             MessageBox( "没有默认打印机,或者没有安装打印机!" ); 
             return ; 
         }








CView::OnPrepareDC

virtual void OnPrepareDC( CDC* pDC, CPrintInfo* pInfo = NULL );

参数:
pDC指向设备环境的指针,用于画出文档的图像。
pInfo指向CPrintInfo结构的指针,如果OnPrepareDC是为打印或打印预览调用的,则该结构描述了当前打印任务,m_nCurPage成员指定了要打印的页数。如果OnPrepareDC是为屏幕显示而调用的,则这个参数为NULL。

说明:
在为屏幕显示而调用OnDraw成员函数或者为打印或打印预览每一页而调用OnPrint成员函数之前,框架调用这个函数。如果这个函数是为屏幕显示而调用的,则这个函数的缺省实现不做任何操作。但是,这个函数在派生类中被重载,例如在CScrollView中,以调整设备环境的属性,因此,在你的重载代码的开始部分,总应该调用基类的实现。
如果这个函数是为打印而调用的,缺省的实现检查保存在pInfo参数中的页面信息。如果没有指定文档的长度,OnPrepareDC假定文档只有一页,并且在打印完一页以后停止打印循环。这个函数通过将结构的m_bContinuePrinting成员设为FALSE来结束打印循环。
如果具有以下的原因,则因重载OnPrepareDC:
·要为指定的页面调整设备环境的属性。例如,如果你想要设置设备环境的映射模式或者其它特征,则应在这个函数中完成这些操作。
·要实现打印时的分页。通常你应当在打印开始时利用OnPreparePrinting成员函数来指定文档的长度。但是,如果你并不准确地知道文档的长度(例如,当打印数据库中未知数量的记录时),则应重载OnPrepareDC函数,以在打印时检测是否到了文档的末尾。如果已经没有文档需要打印了,将CPrintInfo结构的m_bContinuePrinting成员设为FALSE。
·要按页发送打印机的转义序列码。要在OnPrepareDC中发送转义序列码,则应调用pDC成员的Escape成员函数。

ASP里实现打印功能 http://schemas.microsoft.com/intellisense/ie5">.Noprint{ display: none;} .PageNext{ page-break-after: always;}.tdp{    border-bottom: 1 solid #000000;    border-left:  1 solid #000000;    border-right 阅读详情

相关推荐

C#中打印功能的实现

C#打印程序实现完整文档打印功能,我们会介绍打印操作具体包括的四个功能,打印所涉及的类的属性及方法,以及最终实现的样例。最后我们会总结C#打印程序的全部过程。     打印操作通常包括以下四个功能     1 打印设置 设置打印机的一些参数比如更改打印机驱动程序等     2 页面设置 设置页面大小纸张类型等     3 打印预览 类似于word中的打印预览     4 打印 ...

IT汪的博客 546

JAVA打印功能总结文档

JAVA打印功能   总   结   文   档     (博文版)                    作者:尹双双 日期:2015年2月13日   高手请斧正,菜鸟请虚心,引用请注明出处,转发请告知作者,谢谢尊重!   近期农信项目后台系统客户新提出需求的其中一项涉及到“打印”功能,前期技术储备时,发现网上相关资源甚少且混杂,特别是有关web打印技术,被

淡茶的博客 1万+

Java 实现预览与打印功能详解:打印技术的那些事儿!

哈喽,小伙伴们!不知道大家有没有遇到过这样的场景:客户要求一个直接打印功能,并希望在打印之前能够预览,看一下打印的效果?这听起来像一个“复杂又冷门”的需求对吧?但实际上,Java 提供了非常强大的打印 API,不仅可以满足各种打印需求,还可以定制页面格式,插入图片、表格等等!今天我们就来拆解一下,如何用 Java 实现打印预览和打印功能,不仅让打印功能更友好,还能展示打印技术的灵活性和强大。在 Java 中,打印功能主要依赖包。该包提供了与打印相关的一些关键类,比如PrinterJob和。

喵手的博客 1342

实现打印的几种方式

window.print() 这个功能是浏览器自带的api

weixin_43925947的博客 666

C# 打印与打印预览功能实现指南

在当今数字化时代,将信息和数据输出到纸张上的需求依然存在。C#作为.NET平台上的主要编程语言之一,提供了强大的打印功能,使得开发者能够轻松地在应用程序中实现打印功能。这一章节将为你提供一个简单的C#打印功能概览,帮助你理解如何在C#程序中添加打印功能,为后续深入探索打下基础。我们将从打印功能在实际应用中的必要性开始,逐步介绍C#中的打印框架。尽管.NET提供了许多类和命名空间来实现打印任务,但是我们会重点介绍System.Drawing.Printing命名空间,因为它是实现打印功能的核心。

weixin_35414484的博客 1527

CentOS7 安装天气分型软件cost733过程详解

cost733是一款天气分型软件,其内置的一些算法可以帮助气象工作者进行天气类型划分等(我也是初学者,仅仅知道一些皮毛),但是网上找到的安装办法比较少,并且总会出现一些报错,试了一晚上,终于将安装办法调通了,希望可以帮助到大家

weixin_62573024的博客 3562

4种不同编程语言的打印方式

编程语言中的打印方式是指将程序输出到终端或控制台上进行显示。这个功能在编程中非常重要,因为它可以帮助开发人员在调试和测试代码时了解程序的状态和结果。通过输出结果,开发人员可以检查程序是否按照预期运行,并对代码进行修改以修复任何错误或问题。此外,打印也可以用于向用户提供有用的信息,例如进度条、警告消息或结果汇总等。除了在调试过程中使用,打印还可以作为一种记录程序运行状态的方式。例如,程序可以打印出何时开始和结束执行,哪些步骤已经完成以及每个步骤花费的时间等信息。

博客首页 2656

Ansys Icepak:通过 ECAD 导入和非共形网格划分掌握电子冷却

通过将 Icepak 与 HFSS(用于高频电磁学)、Ansys Mechanical(用于结构分析)和 Ansys Fluent(用于流体动力学)等 Ansys 产品相结合,工程师可以在单个工作流程中仿真电子系统的完整行为,从热和电气动力学到机械和流体动力学。精细网格可以应用于关键区域,而在不太重要的区域使用较粗的网格,从而在不牺牲精度的情况下加快仿真速度。这些功能使 Ansys Icepak 成为从事复杂电子设计的工程师不可或缺的工具,可实现更精确的热分析并缩短开发时间。用于高效仿真的非共形网格划分。

jkh920184196的博客 1394

在VC对话框中实现打印功能

    在一般的软件开发中打印和打印预览是经常要用到的功能,对于VC6.0中的文档/视图(Doc/View)框架,可以很方便的使用缺省的打印和打印预览。但是,如果应用程序是基于对话框的就没有办法利用这种便利。而很多情况下,基于对话框的程序也需要打印和打印预览功能。那该怎么办呢?这正是本文将要解决的问题。 1 实现打印    在对话框应用程序中不具备MFC的视和框架交互,要想实现打印和打

yangt1100的专栏 3409

保姆级教程:用NVIDIA Jetson AGX Xavier和GMSL2相机搭建8路车载视觉原型系统

本文提供了一份详细的教程,指导如何使用NVIDIA Jetson AGX Xavier开发板和GMSL2相机搭建8路车载视觉原型系统。内容涵盖硬件选型、系统架构设计、软件环境配置、多路视频采集实现以及性能优化与问题排查,帮助开发者快速掌握GMSL2技术在车载视觉系统中的应用。

weixin_42525005的博客 295

【中兴交换机MC-LAG配置】

​ 中兴mc-lag配置 主设备配置如下: Keepalive链路 interface smartgroup1023 //用作MC-LAG的Keepalive链路接口 switch attribute disable yes description For_Keepalived exit interface xgei-0/1/1/47 switch attribute disable yes description For_Keepalived exit interface

qq_31440733的博客 1万+

可以设置刻度的进度条

        现在做的软件上要用图形来显示串口传过来的信号值大小,最简单的办法,莫过于用进度条显示了。但是在使用的过程中发现一个问题,就是没有刻度。如果有美工,问题也好解决,在没有美工的情况下,只好靠自己动手DIY了。       由于以前没有做过控件,就在网上找了别人做的拿来参考,于是,就发现了颜色渐变进度条的代码。这个代码严格说来并不完全,进度条只能横着不能竖起来。在读懂了颜色渐变进度条

最后一班地铁的专栏 3492

从零开始:Ubuntu 24.04 LTS + Win11双系统安装教程

本文将简单直白介绍如何从零开始在同一台电脑上安装 Ubuntu 24.04 LTS 和 Windows 11,你可以在需要进行专业开发或运维工作时,轻松切换到 Ubuntu,享受其带来的高效与自由;而在日常学习生活和娱乐休闲时,依然可以无缝使用熟悉的 Windows 环境。

萑澈的博客 8116

前端实现打印功能

打印的方式很多,大家选择适合自己项目的即可。就像王者荣耀,哈哈哈(肯定会有人突然疑惑,为什么会突然提到游戏,因为前两天我肯开心自己粉丝在增加,但是感觉自己博客不怎么生动,同事就给了我一个建议,可以说说王者荣耀,嘻嘻嘻,第一次说,以后不一定啥时候说),所以最后总结只有第一句话有用,后边大家随便看看就行,代码机器们,加油,在努力个四五十年,马上就可以退休了!!!

weixin_55846296的博客 2万+

DirectX function “GetDeviceRemovedReason“ failed with DXGI_ERROR_DEVICE_HUNG (“The GPU will not resp

游戏报错"DXGI_ERROR_DEVICE_HUNG"的解决方案 在使用RTX 40系显卡运行FIFA 23等游戏时,可能出现DirectX报错导致游戏崩溃。这主要由于最新显卡驱动与DirectX 12的兼容性问题。解决方法包括: 降级显卡驱动版本 修改游戏配置文件,将DIRECTX_SELECT设为1 在显卡控制面板中关闭垂直同步、抗锯齿、DLSS 3等功能 调整电源模式为性能优先 这些操作可以有效解决因驱动兼容性导致的游戏崩溃问题。

猿小白的博客 3890

基于Simulink的无迹卡尔曼滤波(UKF)SOC高精度估计仿真

本文介绍了基于Simulink的无迹卡尔曼滤波(UKF)在电池SOC高精度估计中的应用。通过无迹变换替代传统EKF的线性化过程,UKF显著提升了SOC估计精度,在强非线性工况下误差可控制在0.5%以内。文章详细阐述了UKF的核心原理,包括Sigma点生成、状态预测和观测更新等关键步骤,并基于Thevenin等效电路模型构建了完整的UKF SOC估算系统。通过Simulink建模和仿真验证,展示了UKF在大电流脉冲、变温工况等复杂场景下的优异性能,其动态响应时间小于30ms,长期累积误差低于0.7%。研究为储

amy_mhd的博客 124

java web 打印功能_JavaWeb实现打印功能

废话不多说了,直接给大家贴代码了,具体代码如下所示:function printsetup(){// 打印页面设置wb.execwb(8,1);}整理的关于打印的内容1、控制"纵打"、 横打”和“页面的边距。(1)function SetPrintSettings() {// -- advanced featuresfactory.printing.SetMarginMeasure(2) // m...

weixin_36417344的博客 874

ACS运动控制器编程 怎么学习

本文介绍了ACS运动控制器编程的完整学习路线,从零基础到实战应用。ACS是以色列高端多轴运动控制平台,适用于自动化设备、精密平台等项目。学习路径包括:1)安装官方软件SPiiPlusControlSuite;2)掌握轴、运动模式和指令三个核心概念;3)学习10个基础指令;4)编写首个运动程序;5)结合C#进行联合编程。进阶内容包括多轴同步、电子凸轮等工业应用,并推荐官方手册作为主要学习资源。通过7天的系统学习,即可掌握单轴运动控制,结合C#实现工业级设备开发。

StevenChen的博客 1316

Qt 打印预览以及打印功能的实现

一、要实现打印功能,首先要在pro文件中加上 QT += printsupport 并且需要重新qmake 二、Qt提供了QPrintPreviewDIalog 类,所以打印功能可以直接通过此对话框实现 三、要唤出 QPrintPreviewDialog 对话框,需要使用  connect(&previewDialog,SIGNAL(paintRequested(QPrinter*)),t

WQ_1996的博客 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

JSP实现打印功能

JSP页面中实现打印功能 需要注意的是:(internet安全选项中自定义级别那里需要启用没有标记为安全的ActiveX控件)那里需要启用没有标记为安全的ActiveX控件)   在实际应用中,打印是一项常用的必备功能。在JSP的项目开发中,如何实现打印功能呢?方法有很多,当然实现的难易也不同。 打印的页面部分,再通过JavaScript函数print()调用浏览器自带的

风清云淡的专栏 1万+

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

用java实现打印功能

用java实现打印功能 用java实现打印,java.awt中提供了一些打印的API,要实现打印,首先要获得打印对象,然后继承Printable实现接口方法print,以便打印机进行打印,最后用用Graphics2D直接输出直接输出。 下面代码实现了简单的打印功能: import java.awt.BasicStroke; import java.awt.Color; import 

Ryan Z 的技术日志 1665

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

WPF 打印功能实现

在WPF中,打印功能的实现可以通过多种方式达成,下面为你详细介绍几种常见的实现方法。

temp0504的博客 1322

electron实现打印功能

方法优点缺点适用场景高度可定制,支持静默打印、高 DPI 配置仅适用于 Electron 的,需确保页面加载完成主进程控制打印,适合复杂打印需求简单易用,直接在渲染进程中调用依赖webview标签,打印功能较基础渲染进程嵌入页面的简单打印embed元素实现简单,适合加载并打印 PDF 文件打印行为不可控,结果可能与复杂页面的预期不符静态内容(PDF、HTML)打印,简单快速实现如果需要高度自定义的打印功能,推荐使用,尤其是在主进程中对打印行为进行精确控制的场景。

gnlhgno的博客 3989

html页面实现打印功能

html页面实现打印功能可用代码效果截图 之前领导让我写一个html页面,可以进行打印,我上网搜了一下,html页面实现打印功能的博客有很多,这里我就不一一介绍了,直接上干货。 可用代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale

weixin_42518717的博客 7041

MFC实现打印功能

使用CPrintDialog类的构造函数: CPrintDialog(BOOL bPrintSetupOnly, // TRUE for Print Setup, FALSE for Print Dialog DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS| PD_HID

两水先木示的博客 1万+

在Web中如何运用JavaScript实现打印功能

概述:在Web中想用JavaScript实现打印功能,需要一个浏览器控件WebBrowser。WebBrowser是IE内置的浏览器控件,无需用户下载,只需要在页面简单的设置,就可以Dom方法获取到该对象. 本文将详细介绍如何运用WebBrowser实现打印功能。 在Web中想用JavaScript实现打印功能,需要一个浏览器控件WebBrowser。WebBrowser是IE内置的浏览器控件,

如果可以,我愿争取 966
上一篇: CoInitializeEx
下一篇: Windows文件操作类函数
htt9931
博客等级 码龄24年 43粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值