1. 程式人生 > >vc 實現列印功能

vc 實現列印功能

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. externint nPaperSize_X ;  
  2. externint nPaperSize_Y ;  
  3. externint nOneLines;  
  4. externint nNextLines;  
  5. //列印結構
  6. typedefstruct
  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;  
  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. }  
  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();}  
  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. }  


=============呼叫列印功能類

  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.     elseif ( ((CButton*)GetDlgItem(IDC_RADIO_MONTH))->GetCheck() )  
  11.     {  
  12.         pGridCtrl = m_pMonGridCtrl;  
  13.     }  
  14.     if( pGridCtrl->GetRowCount() <= 1 )    // 沒有記錄
  15.         return;  
  16.     

    相關推薦

    vc 實現列印功能

    Visual C++6.0是開發Windows應用程式的強大工具,但是要通過它實現程式的列印功能,一直是初學者的一個難點,經常有朋友詢問如何在VC中實現列印功能,他們往往感到在MFC提供的框架內實現這個問題很複雜,不知道如何下手。本例針對這個問題,介紹一種簡單的方法實

    VUE實現列印功能的兩種方法

    第一種方法:通過npm 安裝外掛   1,安裝  npm install vue-print-nb --save 2,引入  安裝好以後在main.js檔案中引入       &n

    jQuery外掛實現列印功能

    寫一下jQuery列印外掛用法吧,最近在做一個列印訂單的功能,研究了半天什麼匯出excel,畫X,Y軸之類的,最後發現jQuery一個外掛就能實現生成pdf列印。 首先需要下載兩個外掛: <!-- jQuery --> <script src="js/j

    react + antd 實現列印功能(踩了不少坑)

    最近在有網頁列印需求,嘗試了一下react的列印功能,遇到了不少的坑: 1.react本身有一些列印的元件,但都不好用,都是基於window.print(),但是window.print()如果直接列印的話,沒有樣式。處理直接當前網頁的body設定為你要列印的區域,但是當你取消列印的時候你會發現整個網頁都被

    利用JQuery jqprint實現列印功能

    1,要先引入jquery.js 和 jquery.jqprint.js 2個js檔案 下載連結:jquery.jqprint.js 2,例項程式碼如下 <html> <head> <script type="text/javascript

    jQuery-jqprint實現列印功能

           現今網站的開發越來越多的使用到列印的功能,剛好最近有用到一款超輕量的外掛,使用起來及其方便,現共享出來大家一起學習學習,使用方法如下: 1、首先需要引入必須的js檔案 <scrip

    extjs利用第三方列印外掛實現列印功能

    extjs由於是基於JS語言,其列印是可以按照一般的WEB列印方式來進行。筆者在網路上發現第三方列印外掛Lodop(詳見地址:http://mtsoftware.v053.gokao.net/index.html),因為這個外掛可以實現多種瀏覽器(如:IE FF 谷

    app專案實現列印功能

    1.實現列印圖片的簡單程式碼:    UIPrintInteractionController *printC = [UIPrintInteractionControllersharedPrintController];     UIPrintInfo *printInf

    jsp頁面中實現列印功能

    <boby><!--startprint--><div>要列印的內容</div><!--endprint--></boby><script>window.onload=function(){v

    java實現列印功能並控制列印方向

    AttributeSet方法,其實就是列印屬性的設定,其實在一個列印過程中子介面有四個,其對應的實現類也有四個(貌似有5個,一個是總類)。詳細見連線。這裡需要提一下需要這麼多列印屬性設定介面的原因: a. 包含 DocAttribute 的 DocAttributeSet 指定單個文件的特徵和應用到單個文件

    ASP.NET水晶報表實現列印功能

    ASP.NET下的水晶報表列印,據我所知有以下幾種辦法可以列印:        1.用IE的列印.呼叫window.print(),但這種辦法對於頁面上即有報表,又有其它控制元件情況就無法區分,不能達到只打印報表內容的目的;       2.自已寫列印程式碼. 程式碼如

    在Web中如何運用JavaScript實現列印功能

    概述:在Web中想用JavaScript實現列印功能,需要一個瀏覽器控制元件WebBrowser。WebBrowser是IE內建的瀏覽器控制元件,無需使用者下載,只需要在頁面簡單的設定,就可以Dom方法獲取到該物件. 本文將詳細介紹如何運用WebBrowser實現列印功能

    在html頁面實現列印功能

    首先在head裡面加入下面一段js程式碼: <script language="javascript"> function preview(oper){ if (oper < 10){ bdhtml=window.docu

    web呼叫本地方法,並實現列印功能(螢幕解析度導致列印斷斷續續不清晰)

    問題:java web開發進銷存系統,使用者需求打印出貨單,一開始採取js的window.print方法,測試環境效果不錯,挪移到使用者那裡時列印結果出現字型斷斷續續不清晰的情況,然而用我的電腦列印時卻不會出現如此狀況,進而懷疑是使用者的機器問題,多方查證是因為使用者電腦的

    DevExpress-winform實現列印功能

    建立Windows窗體,拖入richEdtControl(或者GridControl)+列印按鈕(button) 雙擊列印,

    Bootstrap modal彈出框實現列印功能

    頁面上引入bootstrap 相關 js  html 頁面: <div class="modal fade" id="popPrintSheet" role="dialog" aria-labelledby="printSheet" aria-hidden="true" d

    electron + vue專案實現列印小票功能

    前言:該文章需要一定的electron基礎同學。如需瞭解更多相關資訊,請移步electron官方文件。 一、需求: 公司專案需要通過electron呼叫系統印表機,實現列印小票的功能。 複製程式碼 二、分析: electron列印大概有兩種: 第一種:通過window的webcontent物件,使用

    JS:實現頁面列印功能

    利用JS實現列印操作 條件:IE瀏覽器的WebBrowser外掛,WebBrowser是IE的內建外掛,只需IE即可開啟,可自動使用外掛 前提:在html程式碼的body標籤下呼叫WebBrowser外掛,程式碼如下 <object id="WebBrowser"

    js實現區域性列印功能

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>區域性列印案例<

    VUE-實現一個封裝列印功能的插槽元件

    需求 H5頁面提供一個發票機列印按鈕 我想把它封裝一下變成元件 父級頁面只需要在組建內填充要列印的內容就可以了 尚存在的問題 PC端可以了,但是移動端尚未解決。 移動端的Edge和Chrom瀏覽器能夠調起列印功能頁面,但是無法找到印表機。網路上的印表機手機找不到,而且也無法安裝對