希望有人能提供帮助。在我的Delphi 7应用程序中,有一小部分用户在打印时报告错误,而我正试图用最后一个解决这个问题。我在测试方面略有限制(因为用户距离很远,我们正在通过电子邮件进行处理),但我从EurekaLog获得了一些额外的信息。
无论如何,他得到的第一个错误是“所选打印机不支持操作”,在这行代码中:
Printer.Orientation := AOrientation;
所以,我认为他的打印机不支持Orientation(我从未听说过这个,但我想这是可能的)并尝试没有这行代码。但是现在他在这一行“打印机选择无效”:
Result := Printer.PageWidth / GetDeviceCaps(Printer.Handle, LOGPIXELSX);
据我所知,打印机是正确选择的(它是佳能Pixma iP1500,但其他用户有其他型号,喷墨或激光),他已经尝试更新驱动程序。操作系统也各不相同 - 从XP到Vista SP1。
我建议他尝试使用另一台打印机,但无论他做出什么回应,我都不知道接下来要去哪儿。谷歌搜索没有给出任何有用的结果(至少对我而言)。有没有人有想法?
提前致谢!
答案 0 :(得分:4)
不是直接解决方案,但它可能有助于解决问题。我对这类问题做的第一件事就是从客户那里获得确切的驱动程序版本,然后下载驱动程序并使用LPT1将其安装到我的PC上。然后我可以打印它进行测试,并解决驱动程序的任何问题。显然我实际上无法打印,但这通常不是问题。使用虚拟机也有很大帮助。
答案 1 :(得分:4)
不是解决方案,而是减少错误表面的提示:在该系统上安装(或让用户安装)虚拟打印机并尝试打印到该系统。免费(无论是啤酒还是自由)虚拟PDF打印机都带有优秀的PDFCreator。它肯定支持页面方向。这将为您提供一个已知的良好基准,以便进行测试。
答案 2 :(得分:2)
您说有一小部分用户报告了这些问题。你知道这些用户和其他用户有什么区别吗?
思考:
用户是否有其他应用程序的打印问题?
如果你可以重现这个问题,那将是一个很大的帮助。
答案 3 :(得分:1)
我的客户听起来像是相同(或至少是类似的)问题。我们得到“打印机选择无效”消息的代码行略有不同(在快速报告库中),但它同样是对GetDeviceCaps
的调用。
虽然我们尚未找到真正的解决方案,但我们找到了一种解决方法。如果用户在尝试打印报告之前访问“打印机设置”对话框,则不会出现错误。
您是否在Google的帮助下查看了我找到的这些网站:
http://www.delphipages.com/threads/thread.cfm?ID=19871&G=19828
答案 4 :(得分:1)
我让用户报告过同样的错误,但仅限于Windows Vista。 Windows XP和7似乎没有相同的问题。我发现在Windows Vista上关闭UAC的计算机将消除这个问题。
答案 5 :(得分:1)
这对我有用。我在尝试获取打印机手柄之前使用它。
procedure InvalidatePrinter;
var
dev,
driv,
port: array[0..80] of Char;
deviceMode: THandle;
begin
Printer.GetPrinter(dev, driv, port, deviceMode);
Printer.SetPrinter(dev, driv, port, 0)
end;
答案 6 :(得分:1)
您获得的错误指向SetDefaultPrinter或打印机枚举失败的方向。在Delphi 7中,SetDefaultPrinter看起来有点可怕。例如,它试图从注册表中读取默认打印机。它在较新的Delphi版本中变得更好,但我仍然在每个新版本中修补Printers.pas。
这是我对Delphi 2009的补丁。您可能需要对Delphi 7进行一些调整,但这应该会给您一个想法。原始功能没有多少剩余。
{$IFDEF UNICODE}
function GetDefaultPrinter(DefaultPrinter: PChar; var I: Integer): BOOL; stdcall;
external winspl name 'GetDefaultPrinterW';
{$ELSE}
function GetDefaultPrinter(DefaultPrinter: PChar; var I: Integer): BOOL; stdcall;
external winspl name 'GetDefaultPrinterA';
{$ENDIF}
procedure TPrinter.SetToDefaultPrinter; //@@@ SZ
var
I: Integer;
Err: DWORD;
Device: PChar;
begin
I := 0;
if not GetDefaultPrinter(nil, I) then // (this should return false because the buffer is too small)
begin
Err := GetLastError;
if (Err = ERROR_FILE_NOT_FOUND) or (I = 0) then
RaiseError(SNoDefaultPrinter)
else if Err = ERROR_INSUFFICIENT_BUFFER then
begin
Device := StrAlloc(I);
try
if GetDefaultPrinter(Device, I) then
with Printers do
for I := 0 to Count-1 do
begin
if AnsiSameText(TPrinterDevice(Objects[I]).Device, Device) then
begin
with TPrinterDevice(Objects[I]) do
SetPrinter(PChar(Device), PChar(Driver), PChar(Port), 0);
Exit;
end;
end
else
RaiseLastOSError;
finally
StrDispose(Device);
end;
end
else
RaiseLastOSError;
end;
RaiseError(SNoDefaultPrinter);
end;
如果这不起作用,那么下一步就是检查打印机枚举失败的原因。看看" Device"," Driver"," Port" TPrinterDevice列表。
答案 7 :(得分:0)
http://zpay.com/vbulletin/showthread.php?2310-Printer-selected-is-not-valid,http://support.quickbooks.intuit.com/support/articles/SLN40193和Delphi Win32 Service "Printer Selected is not valid" error on 2008 64bit standard server列出了可能的原因。
简而言之,它们都是配置问题,即您的程序无论出于何种原因都无法访问打印机。
我猜Delphi会在您访问相关属性时尝试按需打开打印机,并且由于框架因此而臭名昭着,因此隐藏了真正的错误。
我建议您尝试尽可能明确地打开打印机(例如使用OpenPrinter
,然后尝试像GetPrinterDataEx
这样的smth),这样您就会得到一些错误信息尽可能暗示究竟出了什么问题。
答案 8 :(得分:0)
这纯粹是轶事,但它可能是相关的。
我刚刚追了一台打印机,选择的打印机无效' Delphi 5应用程序中的错误消息。
该软件正在创建虚拟打印机以生成.pdf文件。我发现了这个“老人”。打印机被其索引存储,这是在pdf操作完成后返回它的不可靠的方法。
通过更改逻辑以便按名称恢复旧打印机,我相信我能够解决我的问题。 (我们将在几天内进行测试)
顺便说一句 - QuickReports参与了。
答案 9 :(得分:-1)
您可能需要调整delphi的printer.pas - 打印机实现中存在一些错误,至少使用较旧的delphi版本,例如:如果网络打印机UNC名称太长,delphi可能会崩溃。