讨论:如何获得网络打印机(普通打印机共享的这种打印机)中的打印作业的相关信息,如:打印时间、打印页数、发送人IP地址及计算机名?这样可以建立一个无人值守的电子打印室,不用为不知道如何控制打印成本面发愁了。这对于OA系统是相当有用的。思路:
使用WIN32 API的打印控制函数:
我把所有的与打印相关的函数贴出来供大家参考:Printing and Print Spooler Functions:________________________________
Following are the functions used to print. AbortDoc
DeviceCapabilities
EndDoc
EndPage
Escape
ExtEscape
SetAbortProc
StartDoc
StartPage
--------------------
--------------------Following are the functions used to access the print spooler. 
AbortPrinter
AbortProc
AddForm
AddJob
AddMonitor
AddPort
AddPrinter
AddPrinterConnection
AddPrinterDriver
AddPrintProcessor
AddPrintProvidor
AdvancedDocumentProperties
ClosePrinter
ConfigurePort
ConnectToPrinterDlg
DeleteForm
DeleteMonitor
DeletePort
DeletePrinter
DeletePrinterConnection
DeletePrinterData
DeletePrinterDriver
DeletePrintProcessor
DeletePrintProvidor
DocumentProperties
EndDocPrinter
EndPagePrinter
EnumForms
EnumJobs
EnumMonitors
EnumPorts
EnumPrinterData
EnumPrinterDrivers
EnumPrinters
EnumPrintProcessorDataTypes
EnumPrintProcessors
FindClosePrinterChangeNotification
FindFirstPrinterChangeNotification
FindNextPrinterChangeNotification
FreePrinterNotifyInfo
GetForm
GetJob
GetPrinter
GetPrinterData
GetPrinterDriver
GetPrinterDriverDirectory
GetPrintProcessorDirectory
OpenPrinter
PrinterMessageBox
PrinterProperties
ReadPrinter
ResetPrinter
ScheduleJob
SetForm
SetJob
SetPort
SetPrinter
SetPrinterData
StartDocPrinter
StartPagePrinter
WaitForPrinterChange
WritePrinter

解决方案 »

  1.   

    {以下是解决这一问题的核心源码:
    参数PrinterName是你要监控的打印机名称,需要use winspool,printer
    }
    procedure RefreshJobList(PrinterName:string);
    var mPrintHandle:THandle;               //打印机句柄
        lRet:LongBool;                      //API返回值
        Job_Info:array[0..99] of _JOB_INFO_2;//打印队列信息
        NoJobs:Word;                        //希望获取的作业数
        s:LongWord;                         //Job_Info的字节数
        cbNeeded:Cardinal;
        cReturned:Cardinal;                 //返回的作业数
        i:Integer;
        ListItem: TListItem;
        remain:DWORD;
        Status:string;
    begin
      lRet:=OpenPrinter(PChar(PrinterName), mPrintHandle, nil);
      if lRet=false then
      begin
        showmessage('获取打印机句柄时出错,错误号:'+inttostr(GetlastError));
        exit;
      end;
      //清空原有任务列表
      form1.ListView1.Clear;
      //如果有可用的打印机
      If mPrintHandle <> 0 Then
      begin
        s:=Sizeof(Job_Info);
        cbNeeded:=0;
        cReturned:=0;
        lRet:=EnumJobs(mPrintHandle,0,99,2,@Job_Info,s,cbNeeded,cReturned);
      end;
      if lRet=false then
      begin
        showmessage('获取当前打印机任务列表时出错,错误号:'+inttostr(GetlastError));
        exit;
      end;
      //现在你需要的信息已经存储在Job_Info结构中
      for i:=0 to cReturned-1 do
      begin
        ListItem:= form1.ListView1.Items.Add;
        ListItem.Caption := inttostr(Job_Info[i].JobId);
        ListItem.SubItems.Add(Job_Info[i].pDocument);
        ListItem.SubItems.Add(Job_Info[i].pUserName);
        ListItem.SubItems.Add(Job_Info[i].pMachineName);
        ListItem.SubItems.Add(inttostr(Job_Info[i].TotalPages));
        ListItem.SubItems.Add(inttostr(Job_Info[i].Size));
        ListItem.SubItems.Add(inttostr(Job_Info[i].Submitted.wYear)+'-'+
          inttostr(Job_Info[i].Submitted.wMonth)+'-'+
            inttostr(Job_Info[i].Submitted.wDay)+' '+
              inttostr(Job_Info[i].Submitted.wHour)+':'+
                inttostr(Job_Info[i].Submitted.wMinute)+':'+
                  inttostr(Job_Info[i].Submitted.wSecond));
      //关闭打印机
      ClosePrinter(mPrintHandle);
    end;
      

  2.   

    {在Job_Info中返回的是是计算机名,如果要转换成IP地址,用这个函数:
    需要use winsock
    }
    function HostToIP(Name: string; var Ip: string): Boolean;
    var
      wsdata : TWSAData;
      hostName : array [0..255] of char;
      hostEnt : PHostEnt;
      addr : PChar;
    begin
      WSAStartup ($0101, wsdata);
      try
        gethostname (hostName, sizeof (hostName));
        StrPCopy(hostName, Name);
        hostEnt := gethostbyname (hostName);
        if Assigned (hostEnt) then
          if Assigned (hostEnt^.h_addr_list) then begin
            addr := hostEnt^.h_addr_list^;
            if Assigned (addr) then begin
              IP := Format ('%d.%d.%d.%d', [byte (addr [0]),
              byte (addr [1]), byte (addr [2]), byte (addr [3])]);
              Result := True;
            end
            else
              Result := False;
          end
          else
            Result := False
        else begin
          Result := False;
        end;
      finally
        WSACleanup;  end;end;
      

  3.   

    为什么我得到的Job_Info[i].TotalPages,Job_Info[i].Size总是为0啊,是什么原因?