【发布时间】:2015-12-02 04:46:35
【问题描述】:
我正在使用 vcl.printers 单元 (delphi XE8),在与打印机“对话”时遇到错误。
我追踪到 vcl.printers 并找到了这段代码(由 EMB 人编写):
if OpenPrinter(ADevice, FPrinterHandle, nil) then
begin
if DeviceMode = 0 then // alloc new device mode block if one was not passed in
begin
DeviceMode := GlobalAlloc(GHND,
DocumentProperties(0, FPrinterHandle, ADevice, nil, nil, 0));
if DeviceMode <> 0 then
begin
DevMode := GlobalLock(DeviceMode);
if DocumentProperties(0, FPrinterHandle, ADevice, DevMode^,
DevMode^, DM_OUT_BUFFER) < 0 then
begin
GlobalUnlock(DeviceMode);
GlobalFree(DeviceMode);
DeviceMode := 0;
DevMode := nil;
end
end;
end;
if DeviceMode <> 0 then
SetPrinterCapabilities(DevMode^.dmFields);
end;
DocumentProperties(0, FPrinterHandle, ADevice, nil, nil, 0)
第一次返回正确的缓冲区大小(我没有在某处写它),然后通过第二次执行时间它返回 4294967295 字节,确实是 -1,因为声明错误,但意味着错误。 如您所见,由于没有错误检查,VCL 代码对错误的处理非常差! 但是我这里有什么错误,为什么?
DocumentProperties 位于 winspool.dll 中
要从中恢复,我需要重新启动 PC,但我不能使用超过一次,这对于调试来说非常烦人。 打印机只是“PDFcreator”
我在其他电脑上试过,即使我运行了很多次也似乎没问题。
我还有两台激光网络打印机。
谢谢
【问题讨论】:
-
在您发布的对
DocumentProperties的两次调用中都有错误检查。首先是对DeviceMode <> 0的测试,通过了;第二个是DocumentProperties() <> 0的测试。第一次调用请求分配适当大小的内存,第二次调用该内存块以供函数填充。贴出的代码没有错误;您对其用途的理解是错误的。 -
看来 DocumentProperties(0, FPrinterHandle, ADevice, DevMode^, DevMode^, DM_OUT_BUFFER) 不正确,这个更好我认为 DocumentProperties(0, FPrinterHandle, ADevice, DevMode^, NIL, DM_OUT_BUFFER)这段代码是Embarcadero的一个库,我没写过。
-
不,代码(如发布的)是正确的。它已经运行了十多年,现在可以在 Windows 10 和 XE 10 Seattle 中运行。根据 MSDN 的文档,这也是正确的。
-
那么为什么我会从这个函数中得到 -1 呢?我找到了这个qc.embarcadero.com/wc/qcmain.aspx?d=107919
-
我不知道你为什么会得到任何东西,因为你还没有发布任何自己的代码。我所能说的只是您发布的代码,它是基于 MSDN 文档的正确性,并且我使用了自 Delphi 1 以来所有操作系统版本和 Delphi 版本中包含的打印机代码,没有问题。在您与打印机“交谈”(无论这意味着什么)的您自己的代码中可能出了什么问题,我无法判断,因为我看不到您的代码。 (您链接的 QC 报告指出了已修复的任何问题。如果确实有修复,它将在西雅图。)
标签: windows api delphi printing delphi-xe8