2000/Xp下获取打印机状态(主要是缺纸),老问题,一直没解决网上找了一圈,代码试了n段,没一个能成功获取的,9x下的汇编用不了
Enumjobs等函数获得的状态总是“正在打印”,不管是缺纸还是断电,都是这个磨死人了,哎………………那位大侠给指条明路吧

解决方案 »

  1.   

    var   
        PrinterInfo:   TPrinterInfo;   
    begin   
        PrinterInfo   :=   GetCurrentPrinterInformation;   
        memo1.Clear;
        with   memo1.Lines   do   
        begin   
            Add('GENERAL   INFORMATION');   
            Add('');   
            Add('ServerName:   '   +   PrinterInfo.SeverName);   
            Add('PrinterName:   '   +   PrinterInfo.PrinterName);   
            Add('ShareName:   '   +   PrinterInfo.ShareName);   
            Add('PortName:   '   +   PrinterInfo.PortName);   
            Add('DriverName:   '   +   PrinterInfo.DriverName);   
            Add('Comment:   '   +   PrinterInfo.Comment);   
            Add('Location:   '   +   PrinterInfo.Location);   
            Add('SepFile:   '   +   PrinterInfo.SepFile);   
            Add('PrintProcessor:   '   +   PrinterInfo.PrintProcessor);   
            Add('DataType:   '   +   PrinterInfo.DataType);   
            Add('Parameters:   '   +   PrinterInfo.Parameters);   
            Add('Attributes:   '   +   IntToStr(PrinterInfo.Attributes));   
            Add('DefaultPriority:   '   +   IntToStr(PrinterInfo.DefaultPriority));   
            Add('StartTime:   '   +   IntToStr(PrinterInfo.StartTime));   
            Add('UntilTime:   '   +   IntToStr(PrinterInfo.UntilTime));   
            Add('Status:   '   +   IntToStr(PrinterInfo.Status));   
            Add('Jobs:   '   +   IntToStr(PrinterInfo.Jobs));   
            Add('AveragePPM:   '   +   IntToStr(PrinterInfo.AveragePPM));   
            Add('');   
            Add('DEVICEMODE   INFORMATION');   
            Add('');           Add('DeviceName:   '   +   PrinterInfo.DeviceMode.dmDeviceName);   
            Add('SpecVersion:   '   +   IntToStr(PrinterInfo.DeviceMode.dmSpecVersion));   
            Add('DriverVersion:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDriverVersion));   
            Add('Size:   '   +   IntToStr(PrinterInfo.DeviceMode.dmSize));   
            Add('DriverExtra:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDriverExtra));   
            Add('Fields:   '   +   IntToStr(PrinterInfo.DeviceMode.dmFields));   
            Add('Orientation:   '   +   IntToStr(PrinterInfo.DeviceMode.dmOrientation));   
            Add('PaperSize:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPaperSize));   
            Add('PaperLength:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPaperLength));   
            Add('PaperWidth:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPaperWidth));   
            Add('Scale:   '   +   IntToStr(PrinterInfo.DeviceMode.dmScale));   
            Add('Copies:   '   +   IntToStr(PrinterInfo.DeviceMode.dmCopies));   
            Add('DefaultSource:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDefaultSource));   
            Add('PrintQuality:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPrintQuality));   
            Add('Color:   '   +   IntToStr(PrinterInfo.DeviceMode.dmColor));   
            Add('Duplex:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDuplex));   
            Add('YResolution:   '   +   IntToStr(PrinterInfo.DeviceMode.dmYResolution));   
            Add('TTOption:   '   +   IntToStr(PrinterInfo.DeviceMode.dmTTOption));   
            Add('Collate:   '   +   IntToStr(PrinterInfo.DeviceMode.dmCollate));   
            Add('LogPixels:   '   +   IntToStr(PrinterInfo.DeviceMode.dmLogPixels));   
            Add('BitsPerPel:   '   +   IntToStr(PrinterInfo.DeviceMode.dmBitsPerPel));   
            Add('PelsWidth:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPelsWidth));   
            Add('PelsHeight:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPelsHeight));   
            Add('DisplayFlags:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDisplayFlags));   
            Add('DisplayFrequency:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDisplayFrequency));   
            Add('ICMMethod:   '   +   IntToStr(PrinterInfo.DeviceMode.dmICMMethod));   
            Add('ICMintent:   '   +   IntToStr(PrinterInfo.DeviceMode.dmICMIntent));   
            Add('MediaType:   '   +   IntToStr(PrinterInfo.DeviceMode.dmMediaType));   
            Add('DitherType:   '   +   IntToStr(PrinterInfo.DeviceMode.dmDitherType));   
            Add('ICCManufacturer:   '   +   IntToStr(PrinterInfo.DeviceMode.dmICCManufacturer));   
            Add('ICCModel:   '   +   IntToStr(PrinterInfo.DeviceMode.dmICCModel));   
            Add('PanningWidth:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPanningWidth));   
            Add('PanningHeight:   '   +   IntToStr(PrinterInfo.DeviceMode.dmPanningHeight));   
        end;   
      

  2.   

    楼上的代码我试了一下,缺纸状态下Status依然是0,还是获得不了缺纸这个状态
      

  3.   

    wow.... 
    我要。。 谢谢啦。。
      

  4.   

    一、
       首先要說明一下,網上所有採用彙編模式(包括讀0x379埠和調用中斷)獲取印表機狀態的方式均不可以在windows下使用。網上的胡亂轉載誤人子弟。還有的是獲取列印任務(Job)的狀態,跟印表機缺紙檢測是兩回事。
        在windows下讀埠必須在Ring0下才能進行,通常的應用程式都運行在Ring3狀態下,也就是說權力不夠,必須要通過驅動的方式提升自己的級別才能夠讀到,這種程式設計需要一定的功力。幸好有人把這個程式設計做好了,它就是Yariv Kaplan 的 WinIo 2.0。Yariv Kaplan 的主頁: http://www.internals.com/。不過下載有問題,網上有其它的地方可下載。
    以下是調用它的delphi代碼(經測試放心使用):
    //埠讀寫
    function InitializeWinIo():Boolean;stdcall;External'WinIO.dll';    //初始化winio.dll,有返回值
    procedure ShutdownWinIo();stdcall;External'WinIO.dll';             //關閉winio.dll
    function GetPortVal(wPortAddr:word;pdwPortVal:pdword;bSize:byte):Boolean;stdcall;External'WinIO.dll';    //向指定埠寫數據
    function SetPortVal(wPortAddr:word;dwPortVal:dword;bSize:byte):Boolean;stdcall;External'WinIO.dll';      //從指定埠讀數據
    //調用函數
    function GetPrintStatus :Integer;
    var
      portVal :DWORD;
    begin
      if InitializeWinIo then
      begin
        if GetPortVal($379,@portVal,1) then
          Result :=portVal;
      end;
      ShutdownWinIo;
    end;順便把0x379埠的定義也給出來(我的實際測試並非如此,請酌情參考)
    {印表機狀態  LPT1:0x379
     __________________________________ | 7 | 6 | 5 | 4 | 3 | 2  | 1 | 0 |   |   |   |   |   |  not used  |___ 1 = "Time Out" (software)   |   |   |   |   |________________ 1 = "I/O Error" (inv C3+; -Error pin low)     印表機出錯   |   |   |   |____________________ 1 = "Selected"  (C4+; +SelectIn pin high)     連線   |   |   |________________________ 1 = "Paper Out" (C5+; +PaperEnd pin high)     紙盡   |   |____________________________ 1 = "Acknowledge" (inv C6+; -Ack pin low)   |________________________________ 1 = "Not Busy"  (C7-; +Busy pin low)      =0 印表機忙
    }
     winIO的缺陷(未測試)
    1、讓純DOS版本的程式無法接受鍵盤和滑鼠事件
    2、使用winIO.dll的辦法在Win7 64x 上用不了的,根本註冊不了驅動通過GetJob()的到JOB_INFO_1結構,該結構中Status中有JOB_STATUS_PAPEROUT等標誌、還有通過匯編PrinterStatus方法都不可以在windows使用,還有的是獲取列印任務(Job)的狀態,跟印表機缺紙檢測是兩回事...二、以下這個未經測試,LZ可以試試可用CREATEFILE以PRN為檔案名生成一個檔,檢測返回值,若成功則印表機可用,否則顯示印表機故障。生成關於PRN的檔案控制代碼後,可象普通檔一樣向檔寫入內容,比如WRITE,寫完後關閉檔
    //從平行埠讀取印表機狀態
    functionGetPrinterStatus:byte;
    asm
       MOV DX,$379;
      IN AL,DX;
    end;
    //獲取印表機是否出錯
    function CheckPrinter:boolean;
    var
    temp:byte;
    begin
       temp:=GetPrinterStatus;
       Result:=not ( ((temp and $80)=0) //印表機忙
      or ((temp and $20)<>0)  //印表機缺紙
      or ((temp and $10)=0)    //印表機未連線
      or ((temp and $08)=0) ); //印表機出錯;
    end;