Delphi检查默认打印机是否失败

时间:2015-12-17 16:27:23

标签: delphi printing

我使用下面的代码来防止有人试图打印但没有默认打印机设置时发生异常。我收到了一位用户使用该软件远程使用该软件的报告,该用户使用网络打印机作为默认打印机。它在调用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;

3 个答案:

答案 0 :(得分:2)

错误发生在您发布的代码可以检查之前,因为它在第一次访问Printer时失败。

在尝试使用全局Printer之前,您应该直接使用WinAPI GetDefaultPrinter函数来查看是否存在默认打印机。这是一个示例控制台应用程序(使用比最近版本的Delphi中包含的函数更容易的声明)来演示如何执行此操作。该示例在XE 10 Seattle中编译,并在Windows 7 64位上进行了测试。

program Project1;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, WinAPI.Windows;

function GetDefaultPrinter(Buffer: PChar; var BufferSize: DWord): BOOL; stdcall;
  external 'winspool.drv' name 'GetDefaultPrinterW'; // GetDefaultPrinterA on pre-Unicode Delphi versions

var
  Buff: string;
  BuffSize, Err: DWord;
begin
  // Get size of buffer needed. 
  GetDefaultPrinter(nil, BuffSize);
  SetLength(Buff, BuffSize);
  // If this call fails, and GetLastError returns
  // ERROR_FILE_NOT_FOUND, there is no default printer assigned.
  if GetDefaultPrinter(PChar(Buff), BuffSize) then
    WriteLn('Default printer: ', Buff)
  else
  begin
    Err := GetLastError();
    if Err = ERROR_FILE_NOT_FOUND then
      WriteLn('No default printer assigned')
    else
      WriteLn('Failed. Error: ', Err);
  end;
  ReadLn;
end.

答案 1 :(得分:0)

在Windows上,您可以假设如果有超过0(零)个打印机,则有一个默认打印机。 除非您的应用程序作为服务运行,否则此配置是安全的。

所以你需要的就是:

if (Printer.Printers.Count=0) then ShowMessage('Please install a printer before attempting to print.');

在访问Printer对象上的大多数其他属性/方法之前,您需要进行此检查。

如果您的应用程序作为服务运行,则不会有默认打印机。这里PrinterIndex将为-1,直到您在代码中分配值。

答案 2 :(得分:-2)

我用Delphi XE6,Win7Pro测试了你的代码。刚换了一行

GetMem (FPort, 255);
 try
  try
    Printer.GetPrinter(FDevice, FDriver, FPort, FHandle); // HERE

except
  on E:Exception do
    ShowMessage(E.Message);
end;

默认使用联网打印机,即使拔下电缆也是如此。