⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printer.cpp

📁 此代码是控制打印机的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Printer.cpp: implementation of the CPrinter class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PrintCtrl.h"
#include "Printer.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPrinter::CPrinter()
{

}

CPrinter::~CPrinter()
{

}

//检测系统是否为Windows NT/2000/XP
BOOL CPrinter::IsWindowsNT()
{
    OSVERSIONINFO vi;
    vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&vi);
    return (vi.dwPlatformId == VER_PLATFORM_WIN32_NT);
}
int CPrinter::GetWindowsVer()
{
	OSVERSIONINFO vi;
    vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&vi);
	//isNT = (vi.dwPlatformId == VER_PLATFORM_WIN32_NT);
	return (int)vi.dwMajorVersion;
	
}
//获得默认打印机名称,端口和默认的纸张 GetComputerName
BOOL CPrinter::GetDefaultPrinterAndPaper(LPTSTR szPrinterName, int nPrintNameBufferLen, LPTSTR szPrinterPort, int nPrinterPortBufferLen, LPTSTR szPaperName)
{
    *szPrinterName = 0;
    *szPaperName = 0;
    CPrintDialog pd(FALSE);

    if (pd.GetDefaults())
    {
        if (pd.m_pd.hDC) 
			DeleteDC(pd.m_pd.hDC);
        if (pd.m_pd.hDevMode)
        {
            LPDEVMODE pdm = (LPDEVMODE)GlobalLock(pd.m_pd.hDevMode);
            *(szPaperName + 63) = 0;
            _tcsncpy(szPaperName, (LPCTSTR)pdm->dmFormName, 63); //打印纸张名称
            GlobalUnlock(pd.m_pd.hDevMode);
            GlobalFree(pd.m_pd.hDevMode);
        }
        if (pd.m_pd.hDevNames)
        {
            LPDEVNAMES pdn = (LPDEVNAMES)GlobalLock(pd.m_pd.hDevNames);
            nPrintNameBufferLen--;
            *(szPrinterName + nPrintNameBufferLen) = 0;
            _tcsncpy(szPrinterName, (LPTSTR)pdn + pdn->wDeviceOffset, nPrintNameBufferLen); //打印机名称
			_tcsncpy(szPrinterPort, (LPTSTR)pdn + pdn->wOutputOffset, nPrinterPortBufferLen); //打印机端口
            GlobalUnlock(pd.m_pd.hDevNames);
            GlobalFree(pd.m_pd.hDevNames);
        }
    }
    return (*szPrinterName && *szPaperName);
}
//增加规格自定义纸张
//szPaperName: 自定义纸张名称
//PaperSize: 纸张的大小,以0.1mm为单位
//rcPrintableMargin: 打印机的最小可打印边界,以0.1mm为单位。
// 可参见GetDeviceCaps函数说明中的PHYSICALOFFSETX及PHYSICALOFFSETY
BOOL CPrinter::AddCustomPaper(LPTSTR szPrinterName, PAPERNAME szPaperName, SIZE PaperSize, RECT rcPrintableMargin)
{
    BOOL bOk = FALSE;
    if (IsWindowsNT()) //Windows NT4/2000/XP才支持
    {
        FORM_INFO_1 fi1;
        fi1.Flags = FORM_USER;
        fi1.pName = (LPTSTR)szPaperName;
        fi1.Size.cx = PaperSize.cx * 100;
        fi1.Size.cy = PaperSize.cy * 100;
        fi1.ImageableArea.left = rcPrintableMargin.left * 100;
        fi1.ImageableArea.top = rcPrintableMargin.top * 100;
        fi1.ImageableArea.right = fi1.Size.cx - rcPrintableMargin.right * 100;
        fi1.ImageableArea.bottom = fi1.Size.cy - rcPrintableMargin.bottom * 100;
        HANDLE hPrinter = GetPrinterHandle(szPrinterName);
        if (hPrinter)
        {
            bOk = (SetForm(hPrinter, (LPSTR)szPaperName, 1, (LPBYTE)&fi1) || //已存在该类型纸张则更改
                   AddForm(hPrinter, 1, (LPBYTE)&fi1)); //否则添加此自定义纸张
            ClosePrinter(hPrinter);
        }
    }
    return bOk;
}
//删除自定义规格纸张
BOOL CPrinter::DeleteCustomPaper(LPTSTR szPrinterName, LPTSTR szPaperName)
{
    BOOL bOk = FALSE;
    if (IsWindowsNT()) //Windows NT4/2000/XP才支持
    {
        HANDLE hPrinter = GetPrinterHandle(szPrinterName);
        if (hPrinter)
        {
            bOk = DeleteForm(hPrinter, (LPSTR)szPaperName);
            ClosePrinter(hPrinter);
        }
    }
    return bOk;
}
//设置自定义纸张的大小,仅对Win95/98有效
BOOL CPrinter::SetUserDefinePaper(LPTSTR szPrinterName, long & nWidth, long & nHeight)
{
    BOOL bOk = FALSE;
    if (!IsWindowsNT()) //Windows 95/98才支持
    {
        PRINTER_INFO_2 *ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			//CString s;
			//s.Format("ppi2->pDevMode->dmPaperSize = %d,ppi2->pDevMode->dmPaperWidth = %d,ppi2->pDevMode->dmPaperLength = %d",ppi2->pDevMode->dmPaperSize,ppi2->pDevMode->dmPaperWidth,ppi2->pDevMode->dmPaperLength);
			//AfxMessageBox(s);
			ppi2->pDevMode->dmFields = DM_PAPERSIZE|DM_PAPERWIDTH|DM_PAPERLENGTH;
			ppi2->pDevMode->dmPaperSize = (WORD)DMPAPER_USER;
			ppi2->pDevMode->dmPaperWidth = (WORD)nWidth;
			ppi2->pDevMode->dmPaperLength = (WORD)nHeight;
			bOk = SetInfo2(ppi2);
			GlobalFree((HGLOBAL)ppi2);
			if(!bOk)
				return bOk;
		}
		ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			nWidth = ppi2->pDevMode->dmPaperWidth;
			nHeight = ppi2->pDevMode->dmPaperLength;
			GlobalFree((HGLOBAL)ppi2);
			bOk = TRUE;
		}
    }
    return bOk;
}
//设置自定义纸张的大小,仅对Win95/98有效
//该函数有问题,暂时不能使用
BOOL CPrinter::GetUserDefinePaperMinMax(LPTSTR szPrinterName, long & nMinWidth, long & nMinHeight, long & nMaxWidth, long & nMaxHeight)
{
    BOOL bOk = FALSE;
	long nOldWidth = 0; 
	long nOldHeight = 0;
	long nOldPaperSize = 0;
	CString s;
    if (!IsWindowsNT()) //Windows 95/98才支持
    {
        PRINTER_INFO_2 *ppi2 = GetInfo2(szPrinterName);
		//获得老的纸张信息
		if (ppi2)
		{
			nOldPaperSize = ppi2->pDevMode->dmPaperSize; 
			nOldWidth = ppi2->pDevMode->dmPaperWidth;
			nOldHeight = ppi2->pDevMode->dmPaperLength;
			s.Format("nOldPaperSize = %d, nOldWidth = %d, nOldHeight = %d",nOldPaperSize, nOldWidth, nOldHeight);
			AfxMessageBox(s);
			GlobalFree((HGLOBAL)ppi2);
		}
		////////////////////////////////////
		//取最小
		ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			ppi2->pDevMode->dmFields = DM_PAPERWIDTH|DM_PAPERLENGTH;
			ppi2->pDevMode->dmPaperWidth = (WORD)1;
			ppi2->pDevMode->dmPaperLength = (WORD)1;
			bOk = SetInfo2(ppi2);
			GlobalFree((HGLOBAL)ppi2);
		}
		ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			nMinWidth = ppi2->pDevMode->dmPaperWidth;
			nMinHeight = ppi2->pDevMode->dmPaperLength;
			s.Format("nMinWidth = %d, nMinHeight = %d",nMinWidth, nMinHeight);
			AfxMessageBox(s);
			GlobalFree((HGLOBAL)ppi2);
		}
		////////////////////////////////////
		//取最大
		ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			ppi2->pDevMode->dmFields = DM_PAPERWIDTH|DM_PAPERLENGTH;
			ppi2->pDevMode->dmPaperWidth = (WORD)10000000;
			ppi2->pDevMode->dmPaperLength = (WORD)10000000;
			bOk = SetInfo2(ppi2);
			GlobalFree((HGLOBAL)ppi2);
		}
		ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			nMaxWidth = ppi2->pDevMode->dmPaperWidth;
			nMaxHeight = ppi2->pDevMode->dmPaperLength;
			s.Format("nMaxWidth = %d, nMaxHeight = %d",nMaxWidth, nMaxHeight);
			AfxMessageBox(s);
			GlobalFree((HGLOBAL)ppi2);
		}
		////恢复原来的
		ppi2 = GetInfo2(szPrinterName);
		if (ppi2)
		{
			ppi2->pDevMode->dmFields = DM_PAPERSIZE|DM_PAPERWIDTH|DM_PAPERLENGTH;
			ppi2->pDevMode->dmPaperSize = (WORD)nOldPaperSize;
			ppi2->pDevMode->dmPaperWidth = (WORD)nOldWidth;
			ppi2->pDevMode->dmPaperLength = (WORD)nOldHeight;
			bOk = SetInfo2(ppi2);
			GlobalFree((HGLOBAL)ppi2);
			bOk = TRUE;
		}
		////

    }
    return bOk;
}
//获取打印机句柄
HANDLE CPrinter::GetPrinterHandle(LPTSTR szPrinterName)
{
    PRINTER_DEFAULTS pds;
    HANDLE hPrinter = NULL;
    ZeroMemory(&pds, sizeof(PRINTER_DEFAULTS));
    pds.DesiredAccess = PRINTER_ALL_ACCESS;
    OpenPrinter(szPrinterName, &hPrinter, &pds); 
	//OpenPrinter(szPrinterName, &hPrinter, NULL);
	return hPrinter;
}
//由纸张名称得到对应的DEVMODE中的那个dmPaperSize值,返回-1表示有错误
short CPrinter::GetPaperSize(LPTSTR szPrinterName, LPTSTR szPortName, PAPERNAME szPaperName)
{
    short nPaperSize = -1;
    //获得可用打印机纸张类型数目
    int nNeeded = DeviceCapabilities(szPrinterName, szPortName, DC_PAPERNAMES, NULL, NULL);
    if (nNeeded)
    {
        PAPERNAME *pszPaperNames = new PAPERNAME[nNeeded]; //分配纸张名称数组
        //获得可用打印机纸张名称数组
        if (DeviceCapabilities(szPrinterName, szPortName, DC_PAPERNAMES, (LPTSTR)pszPaperNames, NULL) != -1)
        {
            int i;
            //查找纸张类型szPaperName在数组中的索引
            for (i = 0; i < nNeeded && _tcscmp(pszPaperNames[i], szPaperName); i++);
            if (i < nNeeded)
            {
                //获得可用打印机纸张尺寸号数目(应该等于打印机纸张类型数目)
                nNeeded = DeviceCapabilities(szPrinterName, szPortName, DC_PAPERS, NULL, NULL);
                if (nNeeded)
                {
                    LPWORD pPapers = new WORD[nNeeded]; //分配纸张尺寸号数组
                    //获得可用打印机纸张尺寸号数组
                    if (DeviceCapabilities(szPrinterName, szPortName, DC_PAPERS, (LPSTR)pPapers, NULL) != -1)
					{
                        nPaperSize = pPapers[i]; //获得纸张类型szPaperName对应的尺寸号
					}
                    delete []pPapers;
                }
            }
        }
        delete []pszPaperNames;
    }
    return nPaperSize;
}
//由纸张编号得到对应的纸张名称,返回FALSE表示有错误,TRUE表示成功,纸张名称在参数szPaperName中返回
BOOL CPrinter::GetPaperName(LPTSTR szPrinterName, LPTSTR szPortName, short nPaperSize, PAPERNAME szPaperName)
{
	BOOL rt = FALSE;
    //获得可用打印机纸张类型数目
    int nNeeded = DeviceCapabilities(szPrinterName, szPortName, DC_PAPERNAMES, NULL, NULL);
    if (nNeeded)
    {
        PAPERNAME *pszPaperNames = new PAPERNAME[nNeeded]; //分配纸张名称数组
        //获得可用打印机纸张名称数组
        if (DeviceCapabilities(szPrinterName, szPortName, DC_PAPERNAMES, (LPTSTR)pszPaperNames, NULL) != -1)
        {
			//获得可用打印机纸张尺寸号数目(应该等于打印机纸张类型数目)
            nNeeded = DeviceCapabilities(szPrinterName, szPortName, DC_PAPERS, NULL, NULL);
            if (nNeeded)
            {
                LPWORD pPapers = new WORD[nNeeded]; //分配纸张尺寸号数组
                //获得可用打印机纸张尺寸号数组
                if (DeviceCapabilities(szPrinterName, szPortName, DC_PAPERS, (LPSTR)pPapers, NULL) != -1)
				{
					int i = 0;
					//查找纸张尺寸nPaperSize在数组中的索引
					BOOL bFind = FALSE;
					int k = 0;
					for(k=0;k<nNeeded;k++)
					{
						if(pPapers[k]==nPaperSize)
						{
							bFind = TRUE;
							break;
						}
					}
					if(bFind)
					{
						//找到指定的纸张Size,返回对应的纸张名称
						_tcsncpy(szPaperName, pszPaperNames[k], 64);
						rt = TRUE;
					}
                    //nPaperSize = pPapers[i]; //获得纸张类型szPaperName对应的尺寸号
				}
                delete []pPapers;
            }
        }
        delete []pszPaperNames;
    }
    //return nPaperSize;
	return rt;
}
BOOL CPrinter::GetDefaultPaper(LPTSTR szPrinterName, LPTSTR szPaperName, long & nPaperSize, long & nOrientation)
{
	BOOL bOk = FALSE;
    PRINTER_INFO_2 *ppi2 = GetInfo2(szPrinterName);
    if (ppi2)
    {
		LPDEVMODE pdm = (ppi2->pDevMode);
		if(pdm)
		{
			//*(szPaperName + 63) = 0;
			memset(szPaperName, 0, 64);
			_tcsncpy(szPaperName, (LPCTSTR)pdm->dmFormName, 63); //打印纸张名称
			nOrientation = (long)pdm->dmOrientation; //打印方向
			nPaperSize = (long)pdm->dmPaperSize;
			//CString s;
			//s.Format("width = %d, height = %d",pdm->dmPaperWidth, pdm->dmPaperLength);
			//AfxMessageBox(s);
			//GlobalUnlock(ppi2->pDevMode);
			bOk = TRUE;
		}
		GlobalFree((HGLOBAL)ppi2);
	}
	return bOk;
}
//设置打印机的默认纸张和方向
BOOL CPrinter::SetPaper(LPTSTR szPrinterName, PAPERNAME szPaperName, short nOrientation)
{
    BOOL bOk = FALSE;
    PRINTER_INFO_2 *ppi2 = GetInfo2(szPrinterName);
    if (ppi2)
    {
        short nPaperSize = GetPaperSize(szPrinterName, ppi2->pPortName, szPaperName);
        if (nPaperSize != -1)
        {
            ppi2->pDevMode->dmFields = DM_PAPERSIZE|DM_PAPERWIDTH|DM_PAPERLENGTH|DM_ORIENTATION;
            ppi2->pDevMode->dmPaperSize = nPaperSize;
            ppi2->pDevMode->dmPaperWidth = 0;
            ppi2->pDevMode->dmPaperLength = 0;
            ppi2->pDevMode->dmOrientation = nOrientation;
			ppi2->pSecurityDescriptor = NULL;
            bOk = SetInfo2(ppi2);
        }
        GlobalFree((HGLOBAL)ppi2);
    }
    return bOk;
}
//获取打印机详细信息,返回的指针用后必须以GlobalFree释放
PRINTER_INFO_2 * CPrinter::GetInfo2(LPTSTR szPrinterName)
{
    HANDLE hPrinter = GetPrinterHandle(szPrinterName);
    PRINTER_INFO_2 *ppi2 = NULL;
    DWORD cbNeeded = 0;
    if (hPrinter)
    {
        GetPrinter(hPrinter, 2, 0, 0, &cbNeeded);
        if (cbNeeded)
        {
            ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, cbNeeded);
            if (ppi2)
            {
                if (!GetPrinter(hPrinter, 2, (LPBYTE)ppi2, cbNeeded, &cbNeeded))
                {
                    GlobalFree((HGLOBAL)ppi2);
                    ppi2 = NULL;
                }
            }
        }
        ClosePrinter(hPrinter);
    }
    return ppi2;
}
PRINTER_INFO_2 * CPrinter::GetInfo2(HANDLE hPrinter)
{
	PRINTER_INFO_2 *ppi2 = NULL;
    DWORD cbNeeded = 0;
	GetPrinter(hPrinter, 2, 0, 0, &cbNeeded);
    if (cbNeeded)
    {
        ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, cbNeeded);
        if (ppi2)
        {
            if (!GetPrinter(hPrinter, 2, (LPBYTE)ppi2, cbNeeded, &cbNeeded))
            {
                GlobalFree((HGLOBAL)ppi2);
                ppi2 = NULL;
            }
        }
    }
	return ppi2;
}
//打印机设置
BOOL CPrinter::SetInfo2(PRINTER_INFO_2 *ppi2)
{
    HANDLE hPrinter = GetPrinterHandle(ppi2->pPrinterName);
    BOOL bOk = FALSE;
    DWORD fMode;
    if (hPrinter)
    {
        fMode = DM_IN_BUFFER | DM_OUT_BUFFER;
        bOk = ((DocumentProperties(NULL, hPrinter,
                                  ppi2->pPrinterName,
                                  ppi2->pDevMode,
                                  ppi2->pDevMode,
                                  fMode) == IDOK) &&
              ::SetPrinter(hPrinter, 2, (LPBYTE)ppi2, 0));

		ClosePrinter(hPrinter);
    }
    return bOk;
}
////////////////////
BOOL CPrinter::GetPrinterPort(LPTSTR szPrinterName, LPTSTR szPrinterPort, int nPortBufferLen, LPTSTR szPrinterDriver, int nDriverBufferLen)
{
	BOOL bOk = FALSE;
    PRINTER_INFO_2 *ppi2 = GetInfo2(szPrinterName);
    if (ppi2)
    {
		_tcsncpy(szPrinterPort, ppi2->pPortName, nPortBufferLen); //打印机端口
		_tcsncpy(szPrinterDriver, ppi2->pDriverName, nDriverBufferLen); //打印机驱动名称

		bOk = TRUE;
        GlobalFree((HGLOBAL)ppi2);
    }
    return bOk;
}
/////////////////////////
BOOL CPrinter::GetPaperList(LPTSTR szPrinterName, LPTSTR szPaperList, long & nBufferLen)
{
	//DMORIENT_PORTRAIT   横向
	//DMORIENT_LANDSCAPE  纵向
	BOOL bOk = FALSE;
	CString s,temp;
    PRINTER_INFO_2 *ppi2 = GetInfo2(szPrinterName);
    if (ppi2)
    {
		//获得可用打印机纸张类型数目
		int nNeeded = DeviceCapabilities(szPrinterName, ppi2->pPortName, DC_PAPERNAMES, NULL, NULL);
		if (nNeeded)
		{
			PAPERNAME *pszPaperNames = new PAPERNAME[nNeeded]; //分配纸张名称数组
			//获得可用打印机纸张名称数组
			if (DeviceCapabilities(szPrinterName, ppi2->pPortName, DC_PAPERNAMES, (LPTSTR)pszPaperNames, NULL) != -1)
			{
				for(int i=0;i<nNeeded;i++)
				{
					temp = pszPaperNames[i];
					s = s+temp+"\t";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -