前面工作需要对打印机的部分功能进行调用,主要是获取和设置默认打印机,修改纸张尺寸,修改打印方向等。
因此封装了如下的代码。
头文件
/**
* 获取默认打印机名字
* @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;
}