Windows打印机API封装

前面工作需要对打印机的部分功能进行调用,主要是获取和设置默认打印机,修改纸张尺寸,修改打印方向等。
因此封装了如下的代码。
头文件


	/**
	 * 获取默认打印机名字
	 * @param name: 打印机名字
	 * @param name: 名字buffer长度
	 * @return: 0-获取成功 1-获取失败
	 */
	DLLEXPORT_API int getDefaultPrinter(char *printerName, unsigned int bufferLen);


	/** 设置默认打印机
	 * @param printerName: 打印机名字
	 * @return: 0-获取成功 1-获取失败
	 */
	DLLEXPORT_API int setDefaultPrinter(const char *printerName);

	/*增加规格 自定义纸张
	 * @param printerName: 打印机名字
	 * @param paperName: 纸张名字
	 * @param width: 宽度 单位:cm
	 * @param hight: 高度 单位:cm
	 * @param leftMargin: 左边距 单位:cm
	 * @param topMargin: 上边距 单位:cm
	 * @param rightMargin: 右边距 单位:cm
	 * @param bottomMargin: 下边距 单位:cm
	 * @return: 0-获取成功 1-获取失败
	 */
	DLLEXPORT_API int addCustomPaper(const char *printerName, const char *paperName, unsigned int width, unsigned int hight,
		unsigned leftMargin, unsigned int topMargin, unsigned int rightMargin, unsigned int bottomMargin);

	/* 删除纸张
	* @param printerName: 打印机名字
	* @param paperName: 纸张名字
	* @return: 0-获取成功 1-获取失败
	*/
	DLLEXPORT_API int deleteCustormPaper(const char *printerName, const char *paperName);

	/* 获取纸张尺寸
	* @param printerName: 打印机名字
	* @param paperName: 纸张名字
	* @param bufferLen: 缓冲区长度
	* @return: 0-获取成功 1-获取失败
	*/
	DLLEXPORT_API int getPaperSize(const char *printerName, char *paperName, unsigned int bufferLen);

	/* 设置打印机默认纸张和方向
	* @param printerName: 打印机名字
	* @param paperName: 纸张名字
	* @param orientation: 打印方向 1-纵向 2-横向
	* @return: 0-获取成功 1-获取失败
	*/
	DLLEXPORT_API int setPaper(const char *printerName, const char *paperName, short orientation);

	/* 设置打印机方向
	* @param printerName: 打印机名字
	* @param orientation: 打印方向 1-纵向 2-横向
	* @return: 0-获取成功 1-获取失败
	*/
	DLLEXPORT_API int setOrientation(const char *printerName, short orientation);

实现

#include <Windows.h>
//注意这里必须头文件windows.h在winbase前面
//否则错误error C4430
#include <winbase.h>

typedef TCHAR PAPERNAME[64];

int isWindowsNT() {
	OSVERSIONINFO vi;
	vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	BOOL ret = GetVersionEx(&vi);
	if (!ret) {
		return FALSE;
	}

	return vi.dwPlatformId == VER_PLATFORM_WIN32_NT;
}

HANDLE getPrinterHandle(LPCTSTR printerName)
{
	PRINTER_DEFAULTS pds;
	HANDLE hPrinter = NULL;
	ZeroMemory(&pds, sizeof(PRINTER_DEFAULTS));
	pds.DesiredAccess = PRINTER_ALL_ACCESS;
	OpenPrinter((LPSTR)printerName, &hPrinter, &pds);
	return hPrinter;
}

short getPaperSize1(LPCTSTR szPrinterName, LPCTSTR 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 && strcmp(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;
}


//获取打印机详细信息,返回的指针用后必须以GlobalFree释放
PRINTER_INFO_2 *getInfo2(LPCTSTR 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;
}

//打印机设置
BOOL 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;
}

int getDefaultPrinter(char *name, unsigned int bufferLen) {
	char tempPrinterName[256] = { 0 };
	unsigned long len = 256;

	BOOL result = GetDefaultPrinter(tempPrinterName, &len);
	if (!result || len == 0 || strlen(tempPrinterName) == 0) {
		return 1;
	}

	if (strlen(tempPrinterName) > bufferLen) {
		return 1;
	}

	strncpy_s(name, bufferLen, tempPrinterName, len);
	return 0;
}

/** 设置默认打印机
* @param printerName: 打印机名字
* @return: 0-获取成功 1-获取失败
*/
int setDefaultPrinter(const char *printerName) {
	return SetDefaultPrinter((LPTSTR)printerName) ? 0 : 1;
}

int addCustomPaper(const char *printerName, const char *paperName, unsigned int width, unsigned int hight,
	unsigned int leftMargin, unsigned int topMargin, unsigned int rightMargin, unsigned int bottomMargin)
{
	if (!isWindowsNT()) {
		return 1;
	}

	FORM_INFO_1 fi1;
	fi1.Flags = FORM_USER;
	fi1.pName = (LPTSTR)paperName;
	fi1.Size.cx = width * 100;
	fi1.Size.cy = hight * 100;
	fi1.ImageableArea.left = leftMargin * 100;
	fi1.ImageableArea.top = topMargin * 100;
	fi1.ImageableArea.right = fi1.Size.cx - rightMargin * 100;
	fi1.ImageableArea.bottom = fi1.Size.cy - bottomMargin * 100;
	HANDLE hPrinter = getPrinterHandle(printerName);
	BOOL bOk = false;
	if (hPrinter) {
		//已存在就修改纸张
		//否则添加自定义纸张
		bOk = (SetForm(hPrinter, (LPSTR)paperName, 1, (LPBYTE)&fi1) || AddForm(hPrinter, 1, (LPBYTE)&fi1));
		ClosePrinter(hPrinter);
	}

	return !bOk;
}

int deleteCustormPaper(const char *printerName, const char *paperName)
{
	if (!isWindowsNT()) {
		return 1;
	}

	BOOL bOk = FALSE;
	HANDLE hPrinter = getPrinterHandle(printerName);
	if (hPrinter) {
		bOk = DeleteForm(hPrinter, (LPSTR)paperName);
		ClosePrinter(hPrinter);
	}
	return !bOk;
}

int getPaperSize(const char *printerName, char *paperName, unsigned int bufferLen)
{
	PRINTER_INFO_2 *ppi2 = getInfo2(printerName);
	if (ppi2 == NULL) {
		return 1;
	}

	int retLen = strlen((const char *)ppi2->pDevMode->dmFormName);
	if (retLen > bufferLen) {
		return 1;
	}
	strncpy(paperName, (const char *)ppi2->pDevMode->dmFormName, retLen);
	return 0;
}

int setPaper(const char *printerName, const char *paperName, short orientation)
{
	BOOL bOk = FALSE;
	PRINTER_INFO_2 *ppi2 = getInfo2(printerName);
	if (ppi2) {
		short nPaperSize = getPaperSize1(printerName, ppi2->pPortName, (TCHAR *)paperName);
		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 = orientation;
			bOk = SetInfo2(ppi2);
		}
		GlobalFree((HGLOBAL)ppi2);
	}
	return !bOk;
}

int setOrientation(const char *printerName, short orientation)
{
	BOOL bOk = FALSE;
	PRINTER_INFO_2 *ppi2 = getInfo2(printerName);
	if (ppi2) {
		ppi2->pDevMode->dmFields = DM_ORIENTATION;
		ppi2->pDevMode->dmOrientation = orientation;
		bOk = SetInfo2(ppi2);
	}
	GlobalFree((HGLOBAL)ppi2);

	return !bOk;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值