如何用win32api修改纸张大小

Author:  kagula

Last update data: 2015-10-09

为了代码不依赖MFC,用Win32API 实现了一遍。


		HGLOBAL hDevNames = NULL;
		HGLOBAL hDevMode = NULL;
		if (FALSE == GetPrinterDevice(const_cast<LPTSTR>(StringHelper::s2ws(body.GetPrinterName()).c_str()),
			&hDevNames, &hDevMode))
		{
			::MessageBox(NULL,L"打印机无法使用,请重新选择打印机!",L"Error",MB_OK);
			return;
		} //else//AfxGetApp()->SelectPrinter(hDevNames, hDevMode); 

		//set paper width and height
		LPDEVMODE lpDevMode=(LPDEVMODE)GlobalLock(hDevMode); 
		if(lpDevMode)
		{ 
			lpDevMode->dmPaperSize = DMPAPER_USER;  //自定义纸张    A4 = 9; A5 = 11; B5 = 13;
			lpDevMode->dmFields |= DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH | lpDevMode->dmFields;
			lpDevMode->dmPaperWidth = body.GetBarcode_paper_width();//新的纸张宽度
			lpDevMode->dmPaperLength = body.GetBarcode_paper_height();//新的纸张高度
		}
		GlobalUnlock(hDevMode);


		HDC hdcPrinter = CreateDC(NULL, StringHelper::s2ws(body.GetPrinterName()).c_str(), NULL, lpDevMode);


GetPrinterDevice函数清单

// returns a DEVMODE and DEVNAMES for the printer name specified
	BOOL 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);
		
		DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevMode);
		

		// 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));
		
		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;
	}


你可能感兴趣的:(如何用win32api修改纸张大小)