【发布时间】:2015-12-17 16:27:22
【问题描述】:
当有人尝试打印但没有设置默认打印机时,我使用下面的代码来防止出现异常。我收到了一个用户的报告,该用户使用 citrix 远程使用该软件,该用户将网络打印机作为默认打印机。它在调用 GetPrinter 时引发异常,并显示消息“当前未选择默认打印机”。他们从其他应用程序打印没有问题。这里出了什么问题?
function CheckForDefaultPrinter: boolean;
var
FDevice: PChar;
FDriver: PChar;
FPort: PChar;
FHandle: THandle;
CurrentPrinterName: string;
begin
//ensure default printer selected - bypass printer.pas bug
Printer.PrinterIndex := Printer.PrinterIndex;
GetMem (FDevice, 255);
GetMem (FDriver, 255);
GetMem (FPort, 255);
try
try
Printers.Printer.GetPrinter(FDevice, FDriver, FPort, FHandle);
except
on E:Exception do
ShowMessage(E.Message);
end;
CurrentPrinterName := FDevice;
finally
if FDevice <> nil then FreeMem (FDevice, 255);
if FDriver <> nil then FreeMem (FDriver, 255);
if FPort <> nil then FreeMem (FPort, 255);
end;
if CurrentPrinterName = '' then
begin
MessageDlg('You do not have a default printer defined.' +
#13#13 + 'Please select a printer before running a report.'+
#13#13 + 'Or the default printer name is blank. Please assign the printer a name.',
mtError,[mbOK],0);
Result:= False;
end
else
Result:= True;
end;
【问题讨论】:
-
Printer.PrinterIndex的值是多少?是的,当系统中没有默认打印机时很有可能,这是绝对有效的情况,您也必须检查它。您在哪里检查用户没有任何默认打印机?如果没有,您应该向用户显示打印机列表并要求选择一个,至少可以使用带有 TRAdioGroup 的简单表单,或者更好的是标准 Windows PrinterSelect 对话框 -
您的堆分配很奇怪。为什么要在最后测试分配?你知道会的。为什么堆分配?堆栈有什么问题?这也是 RTL 函数,无法知道要为其分配多少空间。
-
@Arioch 'Printer.PrinterIndex 实际上应该设置为 -1 以检查默认打印机,对吗?将其设置为自身似乎没有用。这可能是问题的一部分。我不记得printer.pas 错误是什么或如何绕过它。
-
当您可以调用
Printer.GetPrinter时,问题已经出现(它会在您第一次访问Printer时发生,即使在上面的代码中这是对GetPrinter的调用)。而是直接调用WinAPI函数GetDefaultPrinter。 -
@fullerm 我再次问你 - 当系统中根本没有默认打印机时,你的代码应该做什么?