如何获取打印机信息(是否安装了打印机、打印机缺纸、正在打印、打印机有故障)

解决方案 »

  1.   

    用TPrinter类能通过异常信息知道是否安装打印机或者打印机故障Use TPrinter to manage any printing performed by an application. Obtain an instance of TPrinter by calling the Printer function in the Printers unit.To determine how the printed image of the form appears, use the PrintScale property of a TForm component.A print job is started by a call to BeginDoc. The application sends commands by rendering through a Text variable or the printer’s canvas. You can move to a new page by calling the NewPage method. The job stays open until the application calls EndDoc. If a problem occurs and you need to terminate a print job that was not sent to the printer successfully, call the Abort method.Use the TPrinter properties to configure the print job. For example, the title displayed in the Print Manager (and on network header pages) is determined by the Title property. Copies determines the number of copies to print, and Orientation lets you specify whether to print in portrait or landscape mode.TPrinter includes several read-only properties as well, that let you determine which page is currently being printed, the fonts available on the printer, the paper size, and so on.
      

  2.   

    Printers是专门用来控制打印机的,可是在没有安装打印机时,却会提示I/O错误,所以必须有一个检测是否存在打印机的方法,我试过很多方法,可是I/O错误总是比我的判断早出现,所以采用以下的烂招来检测打印机。首先在uses增加Printers,再准备一个列表框ComboBox1,其属性Visible设为FALSE,然后在打印之前执行下列语句,那么就可以检测到是否存在打印机了:procedure TForm1.ButtonClick(Sender: Tobject);
    begin
    ComboBox1.Clear;
    ComboBox1.Items.Assign(Printer.Printers);
    if ComboBox1.Items.CommaText='' then
    Messagedlg('你需要安装打印机才能打印!',mtError,[mbOk],0);
    else
    Form1.Print; 
    end;如果你想要改变Windows的缺省打印机,你必须在Windows的WIN.INI中改变设备键。发送一条 WM_WININICHANGE 消息:var
    strIni: array[0..MAX_PATH] of Char;
    arrWindows: array[0..64] of Char;
    begin
    GetWindowsDirectory(strIni, SizeOf(strIni));
    StrCat(strIni, '\win.ini');
    with TIniFile.Create(strIni) do
    try
    WriteString('windows', 'device', 'HP LaserJet 4 Plus,HPPCL5MS,LPT1:');
    finally
    Free;
    end;
      

  3.   

    StrCopy(arrWindows, 'windows');
    SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(@arrWindows));
    end;var
      pinfo: pPRINTERINFO2;
      pprt,a: Cardinal;
      b:PDWORD;
    begin
      b:=allocmem(256);
      pinfo:=AllocMem(1000);
      if OpenPrinter('HP DJ 200',pprt,nil) then
      begin
        a:=1000;
        if getprinter(pprt,2,pinfo,a,b) then
          showmessage(pinfo.pPrinterName+' ststus:'+inttostr(pinfo.Status));
      ClosePrinter(pprt);
      end;
      
      freemem(b);
      freemem(pinfo);
    end;PRINTER_INFO_2.Status :
     Windows NT: 
       PRINTER_STATUS_PAUSED
       PRINTER_STATUS_PENDING_DELETION 
     Windows 95: 
       PRINTER_STATUS_BUSY
       PRINTER_STATUS_DOOR_OPEN
       PRINTER_STATUS_ERROR
       PRINTER_STATUS_INITIALIZING
       PRINTER_STATUS_IO_ACTIVE
       PRINTER_STATUS_MANUAL_FEED
       PRINTER_STATUS_NO_TONER
       PRINTER_STATUS_NOT_AVAILABLE
       PRINTER_STATUS_OFFLINE
       PRINTER_STATUS_OUT_OF_MEMORY
       PRINTER_STATUS_OUTPUT_BIN_FULL
       PRINTER_STATUS_PAGE_PUNT
       PRINTER_STATUS_PAPER_JAM
       PRINTER_STATUS_PAPER_OUT
       PRINTER_STATUS_PAPER_PROBLEM
       PRINTER_STATUS_PAUSED
       PRINTER_STATUS_PENDING_DELETION
       PRINTER_STATUS_PRINTING
       PRINTER_STATUS_PROCESSING
       PRINTER_STATUS_TONER_LOW
       PRINTER_STATUS_UNAVAILABLE
       PRINTER_STATUS_USER_INTERVENTION
       PRINTER_STATUS_WAITING
       PRINTER_STATUS_WARMING_UP 
    //////////////////////////////////////////////////////////////////
    unit PrinterStatus;interfaceuses
      Windows, Messages, WinProcs, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
    // TPrinterstatus
    // Komponente zum Abfragen des aktuellen Druckerportstatus
    // Programmiert 2000 von K. Otto
    // funktioniert unter Win 9x, jedoch nicht unter Win NT
    // ---------------------------------
    // Status: Freeware incl. Sourcecode
    // ---------------------------------
    // Diese Komponente beruht auf einem Beitrag von Robert Vivrette
    // f黵 "The unofficial Newsletter of Delphi Users"
    // http://www.undu.com/articles/990228a.htmltype
      TPrinterStatus = class(TComponent)
      private
        { Private-Deklarationen }
        fStatus : Byte;
        fLPT    : Integer;
        Function GetTimeOut : Boolean;
        Function GetIOError : Boolean;
        Function GetPrinterSelected : Boolean;
        Function GetOutOfPaper : Boolean;
        Function GetAcknowledgement : Boolean;
        Function GetPrinterBusy : Boolean;
      protected
        { Protected-Deklarationen }
      public
        { Public-Deklarationen }
        Procedure CheckPrinterStatus; // Liest den Druckerstatus der angegeben LPT-Schnittstelle
        Constructor Create(AOwner : TComponent); Override;
        Property TimeOut : Boolean Read GetTimeOut;
        Property IOError  : Boolean Read GetIOError;
        Property PrinterSelected : Boolean Read GetPrinterSelected;
        Property OutOfPaper : Boolean Read GetOutOfPaper;
        Property Acknowledgement : Boolean Read GetAcknowledgement;
        Property Busy : Boolean Read GetPrinterBusy;
      published
        { Published-Deklarationen }
        Property LPT : Integer Read fLPT Write fLPT;
      end;procedure Register;implementationprocedure Register;
    begin
      RegisterComponents('Eigene', [TPrinterStatus]);
    end;Function TPrinterStatus.GetTimeOut : Boolean;
    Begin
         Result:=(fStatus and $01)=$01;
    End;Function TPrinterStatus.GetIOError : Boolean;
    Begin
         Result:=(fStatus and $08)=$08;
    End;Function TPrinterStatus.GetPrinterSelected : Boolean;
    Begin
         Result:=(fStatus and $10)=$10;
    End;Function TPrinterStatus.GetOutOfPaper : Boolean;
    Begin
         Result:=(fStatus and $20)=$20;
    End;Function TPrinterStatus.GetAcknowledgement : Boolean;
    Begin
         Result:=(fStatus and $40)=$40;
    End;Function TPrinterStatus.GetPrinterBusy : Boolean;
    Begin
         Result:=not ((fStatus and $80)=$80);
    End;Procedure TPrinterStatus.CheckPrinterStatus;
    Var
       Status : Byte;
       CheckLPT : Word;
    Begin
         Status:=0;
         If (fLPT>=1) and (fLPT<=3) Then
         Begin
              CheckLPT:=fLPT-1;
              asm
                mov dx,CheckLPT;
                mov al,0;
                mov ah,2;
                int 17h;
                mov &Status, ah;
              End;
         End;
         fStatus:=Status;
    End;Constructor TPrinterStatus.Create(AOwner : TComponent);
    Begin
         Inherited Create(AOwner);
         fLPT:=1;
         fStatus:=0;
    End;end.
    //////////////////////////////////////////////////////
    用法: if not PrinterStatus1.PrinterReady(0) then  //0 = current printerport
      ShowMessage(PrinterStatus1.StatusMsg) else {print print print} ;unit PrinterStatus;interfaceuses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type
      TPrinterStatus = class(TComponent)
      private
        { Private declarations }
        FPort : Word;
        FStatusStr : string;
      protected
        { Protected declarations }
      public
        { Public declarations }
        function PrinterReady(LPT: Word): boolean;
      published
        { Published declarations }
        property StatusMsg: string read FStatusStr;
      end;procedure Register;implementation
    uses Printers;procedure Register;
    begin
      RegisterComponents('Win95', [TPrinterStatus]);
    end;const
      PrnReady = $90;
      OffLine = $00;
      OffLine2 = $10;             {NEW LINE}
      PaperOut = $20;
      PaperOut2 = $30;            {NEW LINE}
      HookedButOff = $80;         {NEW LINE}
      NoConnect = $B0;            {MODIFIED LINE}  {NOCONNECT = $30 FOR SOME COMPUTERS BY STU}function TPrinterStatus.PrinterReady(LPT: Word): boolean;
    var
      ErrorCode, C : BYTE;
      code, x : integer;
      s : string;           function GetPrinterStatus (LPT: Word): Byte;
               {Pass 1 in LPT for LPT1}
               begin
                 asm
                   mov ah,2
                   mov dx,LPT
                   dec dx
                   int $17
                   mov @Result,ah
                 end;
               end;  {GetPrinterStatus}
    begin
     result := false;  //assume not FPort := LPT;
     if FPort = 0 then begin  {if no port specified then try to set port to current
    printer port}
       {printer name}
       s := Printer.Printers[Printer.PrinterIndex];
       if Pos('FPort',s) <> 0 then begin
         s := Copy(s, Pos('FPort',s) +3, 1);
         Val(s,x,code);
         if code <> 0 then FPort := 1 else FPort := x;
       end else FPort := 1;  {default to LPT1}
     end; {valid LPT is 1..4}
     if (FPort > 4) or (FPort < 1) then begin
       raise ERangeError.CreateFmt(
         'LPT%d is not within the valid range of %d..%d',
         [FPort, 1, 4]);
       exit;
     end;
     ErrorCode := GetPrinterStatus(FPort); ErrorCode := ErrorCode and $B0;       {NEW LINE} C := ERRORCODE shl 6;   {ALWAYS MEANS NOTHING CONNECTED} if C > 0 then ERRORCODE := $B0; {ELEMINATES NO LPT3 AND NOTHING CONNECTED} case ErrorCode of
      PrnReady            : begin FStatusStr := 'Printer Ready'; result := true;
    end;
      NoConnect           : FStatusStr := 'Printer not connected';
      Offline,OffLine2    : FStatusStr := 'Printer off line';     {Modified}
      PaperOut,PaperOut2  : FStatusStr := 'Printer out of paper'; {Modified}
      HookedButOff        : FStatusStr := 'Printer connected but turned off'; {New}
     else
      FStatusStr := 'Printer error code: ' + IntToStr(ErrorCode);
     end;end;