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_PAPERSIZE
、DC_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 是正确的 DEVMODE
的 dmPrintQuality
字段将指示负常数之一,以粗略了解分辨率或正值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。
我遇到了一些奇怪的行为 - 似乎无法在 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_PAPERSIZE
、DC_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 是正确的 DEVMODE
的 dmPrintQuality
字段将指示负常数之一,以粗略了解分辨率或正值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。