WinAPI 调用 DeviceCapabilities(DC_ENUMRESOLUTIONS) for Epson P50 总是报错

WinAPI call to DeviceCapabilities(DC_ENUMRESOLUTIONS) for Epson P50 always report error

我遇到了一些奇怪的行为 - 似乎无法在 Windows 中枚举 Epson 墨水打印机的分辨率。 特别是这段代码总是报告错误:

int r, err;
char szBuffer[0x4000];
String prnName = "EPSON P50 Series";
String portName = "USB002";

r = DeviceCapabilities(prnName.c_str(), portName.c_str(), DC_ENUMRESOLUTIONS, NULL, NULL);
err = GetLastError();
printf("\n 1.DevCap.result = %d, err = %d", r, err);

r = DeviceCapabilities(prnName.c_str(), portName.c_str(), DC_ENUMRESOLUTIONS, szBuffer, NULL);
err = GetLastError();
printf("\n 2.DevCap.result = %d, err = %d", r, err);

在输出中我看到以下内容:

1.DevCap.result = -1, err = 0
2.DevCap.result = -1, err = 13

注意:Windows 错误 13 是 ERROR_INVALID_DATA

你能帮我理解 - 如何正确解释吗? 这是否意味着 Epson 墨水打印机的驱动程序不提供有关支持的打印分辨率的任何信息? 还是真的传递了一些无效的参数?如果是,那可能是哪一个?

提前致谢。

PS。 请注意以下内容:

1) 打印机和端口名称正确。它们是通过 EnumPrinters() WinAPI 调用获得的。在此代码示例中,我删除了所有不相关的代码,因此只保留失败的函数。

2) 打印机本身工作正常,我可以用它打印文档和照片。

3) 我还添加了一台 "Epson Stylus 300" 打印机,配置为使用 "FILE:" 端口进行打印。有趣的是 - 为此类打印机调用 DeviceCapabilities(DC_ENUMRESOLUTIONS) 也会报告错误#13。这就是为什么我倾向于认为所有 Epson 墨水打印机都不提供任何关于打印分辨率的信息...

4) 所有其他对 DeviceCapabilities() 函数的调用(对于 DC_PAPERS, DC_PAPERSIZEDC_PAPERNAMES 等)都适用于这些打印机(Epson P50 和 Epson Stylus 300)。因此,打印机名称和端口名称是正确的,问题仅存在于 DeviceCapabilities(DC_ENUMRESOLUTIONS) 调用。

这似乎是那些 Epson 打印机的错误。然而,分辨率值取决于设备,无论如何你都不应该需要它。

您可能希望通过 DEVMODE 获取打印机分辨率,并将其报告给用户:

PRINTDLG pdlg = { sizeof PRINTDLG };
pdlg.Flags = PD_RETURNDEFAULT | PD_RETURNDC;
PrintDlg(&pdlg);

DEVMODE* dm = (DEVMODE*)::GlobalLock(pdlg.hDevMode);
cout << "dm->dmDeviceName: " << dm->dmDeviceName << endl;

if (dm->dmFields & DM_PRINTQUALITY)
{
    cout << "dm->dmPrintQuality: " << dm->dmPrintQuality << endl;
}

::GlobalUnlock(pdlg.hDevMode);

dmPrintQuality 是打印机分辨率或这些设备独立值之一:

#define DMRES_DRAFT         (-1)
#define DMRES_LOW           (-2)
#define DMRES_MEDIUM        (-3)
#define DMRES_HIGH          (-4)

如果用户想要更改此值,最好允许访问打印机自己的设置对话框。

我用 EPSON Stylus Photo RX595 系列确认了这个问题。

Barmak Shenmi运行i 是正确的 DEVMODEdmPrintQuality 字段将指示负常数之一,以粗略了解分辨率或正值pixels-per-inch 水平分辨率。在后一种情况下,您可以从 DEVMODE.

dmYResolution 字段中获取垂直分辨率

如果您在级别 2 (PRINTER_INFO_2) 中使用 EnumPrinters 来获取名称和端口,那么您已经拥有默认 DEVMODE.

的副本

假设任何失败的打印机 DC_ENUMRESOLUTIONS 只有一个分辨率似乎是一种合理的启发式方法,并且它是默认 DEVMODE 中的分辨率。您可以尝试打开打印对话框并调整它提供的各种质量旋钮,以查看结果 DEVMODE 中的分辨率是否不同,但我怀疑它会改变。

就我的打印机而言,DEVMODE 中报告的 360×360 pixels-per-inch 分辨率似乎是一个抽象值,因为打印机的规格声称“5760×1440 优化 dpi” .据推测,驱动程序抖动所有这些点以实现 360×360 像素的有效密度。

为了确保这不仅仅是我的编码错误,我还 运行 我的激光打印机(兄弟),它报告了两种分辨率:600×600 和 300×300。