【发布时间】:2021-11-18 00:52:19
【问题描述】:
我正在从对PrintDlgEx() 的 WIN32 调用中获取选定的打印机托盘。这似乎在大多数时间都可以成功运行,但最近我在我的机器上添加了一台新打印机(DYMO LabelWriter 450),这导致我的简单软件失败。
经调查,DC_BINS 对 DeviceCapabilities() 的调用返回 4294967295,而到目前为止我测试过的所有其他打印机都返回个位数的 bin 计数。
我的第一个倾向是在 bin 计数大于给定阈值(比如...20?)时省略 bin 名称,但我不喜欢这个解决方案。
打印机是否会为此返回最大UNSIGNED INT 值?只是驱动程序写得不好,还是有其他含义?或者我完全误解了预期的价值。
如果我必须写一个任意的上限,我会,但我想更好地理解为什么会出现这种情况。显然,这台打印机没有数十亿个不同的打印机托盘。
这是一个 MRE:
HINSTANCE hinst = GetModuleHandle(NULL);
HRESULT hResult;
PRINTDLGEX pdx = {0};
LPPRINTPAGERANGE pPageRanges = NULL;
HWND hWndOwner = GetForegroundWindow();
if(!hWndOwner){
hWndOwner = GetDesktopWindow();
}
// Allocate an array of PRINTPAGERANGE structures.
pPageRanges = (LPPRINTPAGERANGE) GlobalAlloc(GPTR, 10 * sizeof(PRINTPAGERANGE));
if(!pPageRanges){
return wprintf(L"{\"error\": \"%s\"}", GetLastError()); // "Your computer does not have enough memory to complete this operation:"
}
// Initialize the PRINTDLGEX structure.
pdx.lStructSize = sizeof(PRINTDLGEX);
pdx.hwndOwner = hWndOwner;
pdx.hDevMode = NULL;
pdx.hDevNames = NULL;
pdx.hDC = NULL;
pdx.Flags = PD_RETURNDC | PD_COLLATE;
pdx.Flags2 = 0;
pdx.ExclusionFlags = 0;
pdx.nPageRanges = 0;
pdx.nMaxPageRanges = 10;
pdx.lpPageRanges = pPageRanges;
pdx.nMinPage = 1;
pdx.nMaxPage = 1000;
pdx.nCopies = 1;
pdx.hInstance = 0;
pdx.lpPrintTemplateName = NULL;
pdx.lpCallback = NULL;
pdx.nPropertyPages = 0;
pdx.lphPropertyPages = NULL;
pdx.nStartPage = START_PAGE_GENERAL;
pdx.dwResultAction = 0;
// Invoke the Print property sheet.
hResult = PrintDlgEx(&pdx);
DEVMODE * myDevMode = (DEVMODE *)GlobalLock(pdx.hDevMode);
DWORD binCount = DeviceCapabilities((CHAR*)myDevMode->dmDeviceName, nullptr, DC_BINS, nullptr, nullptr);
DWORD binNameCount = DeviceCapabilities((CHAR*)myDevMode->dmDeviceName, nullptr, DC_BINNAMES, nullptr, nullptr);
wprintf(L"\"binCount\":\"%lu\",", binCount);
wprintf(L"\"binNameCount\":\"%lu\",", binNameCount);
【问题讨论】:
-
在没有看到您的代码的情况下,很难回答有关为什么某些东西不能正常工作的问题。您应该发布一个 minimal reproducible example 来演示该问题。很有可能您只是在调用
DeviceCapabilities之前未能初始化某些内容。而且由于纸箱是物理纸盘,即使是大型打印机也很少有超过四个或五个。 -
@KenWhite - 谢谢。请注意,我不是在问为什么代码不起作用,而是在什么情况下打印机驱动程序会返回 4294967295 作为纸盘的数量。也许代码是的原因,但我不相信。
-
你输入的太多了。 :-) 如果您使用
ZeroMemory将整个结构清零,然后只填充您正在使用的结构,您可以将 21 行代码(初始化pdx的代码)减少到 10 行。它还可以确保您不要错过任何东西。不过,我在您的代码中看不到任何明显的问题(除了它不是minimal reproducible example,因为它不完整)。 -
@Kenwhite - 和我的代码完全有问题。现在把我的脚从嘴里拿出来:)
-
是的,我看到 Remy 抓到了一些我没有抓到的东西,比你抓到的更多。 :-) 很高兴你把它整理好了。不过,我对
ZeroMemory的建议仍然适用。