zoukankan      html  css  js  c++  java
  • windows下 打印机打印操作类 VS2015

    #include "stdafx.h"
    #include "CPrinter.h"
    
    
    BOOL CPrinter::GetPrinterDevice(LPTSTR pszPrinterName, HGLOBAL* phDevNames, HGLOBAL* phDevMode)
    {
        // if NULL is passed, then assume we are setting app object's
        // devmode and devnames
        if (phDevMode == NULL || phDevNames == NULL)
            return FALSE;
    
        // Open printer
        HANDLE hPrinter;
        if (OpenPrinter(pszPrinterName, &hPrinter, NULL) == FALSE)
            return FALSE;
    
        // obtain PRINTER_INFO_2 structure and close printer
        DWORD dwBytesReturned, dwBytesNeeded;
        GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded);
        PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR,
            dwBytesNeeded);
        if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded,
            &dwBytesReturned) == 0) {
            GlobalFree(p2);
            ClosePrinter(hPrinter);
            return FALSE;
        }
        ClosePrinter(hPrinter);
    
        // Allocate a global handle for DEVMODE
        HGLOBAL  hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) +
            p2->pDevMode->dmDriverExtra);
        ASSERT(hDevMode);
        DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevMode);
        ASSERT(pDevMode);
    
        // copy DEVMODE data from PRINTER_INFO_2::pDevMode
        memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) +
            p2->pDevMode->dmDriverExtra);
        GlobalUnlock(hDevMode);
    
        // Compute size of DEVNAMES structure from PRINTER_INFO_2's data
        DWORD drvNameLen = lstrlen(p2->pDriverName) + 1;  // driver name
        DWORD ptrNameLen = lstrlen(p2->pPrinterName) + 1; // printer name
        DWORD porNameLen = lstrlen(p2->pPortName) + 1;    // port name
    
                                                          // Allocate a global handle big enough to hold DEVNAMES.
        HGLOBAL hDevNames = GlobalAlloc(GHND,
            sizeof(DEVNAMES) +
            (drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR));
        ASSERT(hDevNames);
        DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDevNames);
        ASSERT(pDevNames);
    
        // Copy the DEVNAMES information from PRINTER_INFO_2
        // tcOffset = TCHAR Offset into structure
        int tcOffset = sizeof(DEVNAMES) / sizeof(TCHAR);
        ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));
    
        pDevNames->wDriverOffset = tcOffset;
        memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName,
            drvNameLen*sizeof(TCHAR));
        tcOffset += drvNameLen;
    
        pDevNames->wDeviceOffset = tcOffset;
        memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName,
            ptrNameLen*sizeof(TCHAR));
        tcOffset += ptrNameLen;
    
        pDevNames->wOutputOffset = tcOffset;
        memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName,
            porNameLen*sizeof(TCHAR));
        pDevNames->wDefault = 0;
    
        GlobalUnlock(hDevNames);
        GlobalFree(p2);   // free PRINTER_INFO_2
    
                          // set the new hDevMode and hDevNames
        *phDevMode = hDevMode;
        *phDevNames = hDevNames;
        return TRUE;
    }
    
    
    /*
        首先打印准备工作,获取到设备的操作句柄
    
    */
    
    BOOL CPrinter::PrintStr(CString strMessage,BOOL IsCut,int PrnNum )
    {
    #ifdef DEBUG
        log.Logf("%s","开始打印");
    #endif
        TCHAR  cutStr[4] = { 0x1D,0x53 ,0x31 };
    
        if (!GetPrinterDevice(m_strPrintDevice.GetBuffer(0), &m_hDevNames, &m_hDevMode))
        {
            AfxMessageBox(_T("GetPrinterDevice Called Failed!"));
            return false;
        }
        else
        {
            AfxGetApp()->SelectPrinter(m_hDevMode, m_hDevNames);
        }
        m_strPrintDevice.ReleaseBuffer();
        CPrintDialog printerDlg(FALSE);
        printerDlg.m_pd.hDevMode = m_hDevMode;
        printerDlg.m_pd.hDevNames = m_hDevNames;
     
        CDC dc;
        
        if (printerDlg.CreatePrinterDC() == NULL)
        {
            AfxMessageBox(_T("CreatePrinterDC 失败"));
            return false;
        }
        
        dc.Attach(printerDlg.m_pd.hDC);
    
        DOCINFO di;                                                                             //下面的内容网上很多,就不解释了  
        di.cbSize = sizeof(DOCINFO);
        di.lpszDocName = _T("有驱打印测试");
        di.lpszDatatype = NULL;
        di.lpszOutput = NULL;
        di.fwType = 0;
    
        CRect recPrint(0, 0, dc.GetDeviceCaps(LOGPIXELSX), dc.GetDeviceCaps(LOGPIXELSY));
        dc.DPtoLP(&recPrint);
        dc.SetWindowOrg(0, 0);
    
        CFont newFont;
        //VERIFY(newFont.CreatePointFont(50, _T("宋体"), &dc));
        VERIFY(newFont.CreatePointFont(_ttoi(m_fontsize), m_fontname, &dc));
        CFont* oldFont = dc.SelectObject(&newFont);
    
        dc.SetTextAlign(TA_TOP | TA_LEFT);
    
        CString strPrint;
        int nIndex = 0;
        int x = 0;
        int y = 50;
        CSize textSize;
        textSize = dc.GetTextExtent(_T("00"), 2);
    
        dc.StartDocW(&di);
        dc.StartPage();
        dc.SetMapMode(MM_TEXT);
        
           //根据当前字体的宽、高,后面以此高度为行高  
        
            while (((nIndex = strMessage.Find(_T("
    "))) > -1))                  //将IDC_EDIT1编辑框中内容打印,支持换行,一次换行等于'
    ',所以在开头strMessage += _T("
    ")  
            {
                strPrint = strMessage.Left(nIndex);
                strMessage = strMessage.Mid(nIndex + 2);
    
                dc.TextOutW(x, y, strPrint);
    
                y += textSize.cy;                                               //下移一行,行高为字体高度  
            }
            if (m_cut==L"1")
            {
                y += 20;
                dc.TextOutW(x, y, cutStr);
            }
            else
            {
                y += 20;
                dc.TextOutW(x,y,_T(""));
            }
    
        
    
        dc.SelectObject(oldFont);
        newFont.DeleteObject();
        dc.EndPage();
        dc.EndDoc();
    
        DeleteDC(dc.Detach());
    
        return true;
    }
  • 相关阅读:
    201671010131 2016-2017-2 《Java程序设计》逐渐的进步。
    201671010131 2016-2017-2 《Java程序设计》走向核心。
    201671010131 2016-2017-2 《Java程序设计》艰难的旅程.
    201671010131 2016-2017-2 《Java程序设计》第二周 由简入繁的开始。
    201671010131 2016-2017-2 《Java程序设计》初学Java,所感所学总结。
    ajax提交请求数组时,参数名带[]
    天气接口-高德api
    Lambda 表达式在线程中的使用
    Centos7 下安装和配置 MinDoc
    天气接口 乱码问题
  • 原文地址:https://www.cnblogs.com/lobsterIT/p/5654414.html
Copyright © 2011-2022 走看看