CreateDC 失败并出现网络打印机 - 错误代码 1801

问题描述 投票:0回答:2

我目前面临 HANDLE 从网络打印机返回 NULL 的问题。

//NOTE:szDriver is the driver location
//my device name  = "\\somelocation\HP Color LaserJet CP3505 PCL 6",
HANDLE hDC;
hDC = CreateDC(szDriver,(char*)pDevMode->dmDeviceName,NULL,pDevMode);

即使我仔细检查了我的打印机并进行了测试打印,hDC 也会返回 NULL。

我调用了 GetLastError(),它返回错误 1801,这意味着打印机名称无效。

然后我又看了一眼 pDevMode->dmDeviceName,它似乎被截断了。它仅显示我实际打印机名称的一部分。

c++ c winapi printing
2个回答
5
投票

我找到了DEVMODE的MSDN参考:

https://msdn.microsoft.com/en-us/library/windows/desktop/dd183565(v=vs.85).aspx

它说:

dm设备名称

一个以零结尾的字符数组,指定打印机或显示器的“友好”名称;例如,如果是 PCL/HP LaserJet,则为“PCL/HP LaserJet”。该字符串在设备驱动程序中是唯一的。请注意,此名称可能会被截断以适合 dmDeviceName 数组。

好像有35个字符的限制,超过它就会被截断。这非常糟糕,因为现在很多网络打印机的名称都很长。

然后我将长名称打印机复制到本地变量中(在将值分配给 dmDeviceName 之前)并将其传递(而不是直接使用 dmDeviceName),然后它对我来说效果很好。

我是这样做的:

//NOTE:szDriver is the driver location
//my device name  = "\\somelocation\HP Color LaserJet CP3505 PCL 6",
HANDLE hDC;

//use local variable
char    szPrinterName [255];
//NOTE:strcpysz is our own function copies a string into its destination with 0 terminator
//You can do it differently
strcpysz (szPrinterName,sizeof(szPrinterName), "\\somelocation\HP Color LaserJet CP3505 PCL 6");

//in this case 
//(char*)pDevMode->dmDeviceName will be "\\somelocation\HP Color Laser" <-TRUNCATED
hDC = CreateDC(szDriver,szPrinterName,NULL,pDevMode);

然后我就可以拿到我的手柄了。


0
投票

您需要做一些更复杂的事情才能获得完整的打印机名称,而不是被截断为 32 个字符:

PG_PRINTDLGW pd;
PrintDlgW(&pd)
LPDEVNAMES dvn;
dvn = (LPDEVNAMES) GlobalLock(pd.hDevNames) ; 
// full name will be at:
(wchar_t *)dvn + dvn->wDeviceOffset;
© www.soinside.com 2019 - 2024. All rights reserved.