当我们在windows系统中打印时,就会在系统的右下角出现一个打印机的小图标,双击这个图标就会打开打印任务窗口,可以看到有几个打印任务。我想在程序中按一个按钮就出现这个打印任务窗口,请问怎样可以实现?谢谢!

解决方案 »

  1.   

    获取打印机的打印任务列表 
           如何在程序里判断一个打印作业已经进入打印队列(也就是可以在打印管理程序里看到该作业的信息),或者说如何察看打印队列里已有的作业信息? 
    看下面的这个例程。还有测试代码。uses WinSpool;type JOB_INFO_1_ARRAY = Array of JOB_INFO_1;Function GetSpoolerJobs(sPrinterName : String) : JOB_INFO_1_ARRAY;vari : Integer;hPrinter : THandle;bResult : Boolean;cbBuf : DWORD;pcbNeeded : DWORD;pcReturned : DWORD;aJobs : Array[0..99] of JOB_INFO_1;begincbBuf := 1000;bResult := OpenPrinter(PChar(sPrinterName), hPrinter, Nil);if NOT bResult then beginShowMessage('Error opening the printer');exit;end;bResult := EnumJobs(hPrinter,0,Length(aJobs),1,@aJobs,cbBuf,pcbNeeded,pcReturned);if NOT bResult then beginShowMessage('Error Getting Jobs information');exit;end;for i:=0 to pcReturned-1 do beginif aJobs[i].pDocument <> Nil then beginSetLength(Result, Length(Result)+1);Result[Length(Result)-1] := aJobs[i];end;end;end;测试例子:1- 创建工程有 StringGrid 和一个 Timer.2- StringGrid 'ColCount' and “RowCount” 值为 203- Timer的 “Interval” 属性值 500.4- “OnTime” 实践中写这个代码procedure TForm1.Timer1Timer(Sender: TObject);vari, ii : Integer;aJobs : JOB_INFO_1_ARRAY;beginfor i:=0 to StringGrid1.ColCount-1 dofor ii:=0 to StringGrid1.RowCount-1 do StringGrid1.Cells[i,ii] := '';aJobs := GetSpoolerJobs('\ibmserverLaserJet 1100');//正在打印的打印机名字,这里我的打印机时网打。这里你要自己改for i:=0 to Length(aJobs)-1 do beginStringGrid1.Cells[i,0] := aJobs[i].pPrinterName;StringGrid1.Cells[i,1] := aJobs[i].pMachineName;StringGrid1.Cells[i,2] := aJobs[i].pUserName;StringGrid1.Cells[i,3] := aJobs[i].pDocument;StringGrid1.Cells[i,4] := aJobs[i].pDatatype;StringGrid1.Cells[i,5] := aJobs[i].pStatus;StringGrid1.Cells[i,6] := IntToStr(aJobs[i].Status);case aJobs[i].Status ofJOB_STATUS_PAUSED: StringGrid1.Cells[i,6] := 'JOB_STATUS_PAUSED';JOB_STATUS_ERROR: StringGrid1.Cells[i,6] := 'JOB_STATUS_ERROR';JOB_STATUS_DELETING: StringGrid1.Cells[i,6] := 'JOB_STATUS_DELETING';JOB_STATUS_SPOOLING: StringGrid1.Cells[i,6] := 'JOB_STATUS_SPOOLING';JOB_STATUS_PRINTING: StringGrid1.Cells[i,6] := 'JOB_STATUS_PRINTING';JOB_STATUS_OFFLINE: StringGrid1.Cells[i,6] := 'JOB_STATUS_OFFLINE';JOB_STATUS_PAPEROUT: StringGrid1.Cells[i,6] := 'JOB_STATUS_PAPEROUT';JOB_STATUS_PRINTED: StringGrid1.Cells[i,6] := 'JOB_STATUS_PRINTED';JOB_STATUS_DELETED: StringGrid1.Cells[i,6] := 'JOB_STATUS_DELETED';JOB_STATUS_BLOCKED_DEVQ: StringGrid1.Cells[i,6] := 'JOB_STATUS_BLOCKED_DEVQ';JOB_STATUS_USER_INTERVENTION: StringGrid1.Cells[i,6] := 'JOB_STATUS_USER_INTERVENTION';JOB_STATUS_RESTART: StringGrid1.Cells[i,6] := 'JOB_STATUS_RESTART';JOB_POSITION_UNSPECIFIED: StringGrid1.Cells[i,6] := 'JOB_POSITION_UNSPECIFIED';else StringGrid1.Cells[i,6] := 'Unknown status...';end;end;StringGrid1.Refresh;end;5- 运行程序,打印程序测之 
     
     
     
     
      

  2.   

    zhangheaaa:我想的是有没有什么直接用winexec()调用的方法,不过我会参考你的例程,谢谢!
      

  3.   

    其实我就是想删除打印任务列表中的所有的任务,有没有API函数可以实现呢?
    怎么没有人删除过打印任务吗?
      

  4.   

    打印任务窗口程序好像和打印机有关,不同的打印机有不同的程序,呵呵,我在XP的进程列表看到我的打印任务窗口名叫HPZSTC09.exe,我的打印机是HP的...
      

  5.   

    uses ActiveX,ShlObj, Printers;
    function ExecuteContextMenuCommand(hParent: THandle; sf: IShellFolder; childPidl: PItemIDList;
      verb: string = ''; propPage: string = ''; pidlCount: UInt = 1): Boolean;
    var
      cm, cm2, cm3: IContextMenu;
      ici: TCMInvokeCommandInfo;
      pop : HMenu;
      c: Cardinal;
    begin
      Result := False;
      if sf.GetUIObjectOf(hParent, pidlCount, childPidl, IID_IContextMenu,nil, Pointer(cm)) <> NOERROR then Exit;
      try
        cm2 := cm as IContextMenu2;
        cm := cm2;
        try
          cm3 := cm as IContextMenu3;
          cm := cm3;
        except
        end;
      except
      end;
      ZeroMemory(@ici, sizeOf(ici));
      with ici do
      begin
        cbSize := sizeOf(TCMInvokeCommandInfo);
        fMask := CMIC_MASK_FLAG_NO_UI;
        hWnd := hParent;
        lpVerb := PChar(verb);
        lpParameters := PChar(propPage); //'Settings';
        nShow := SW_SHOW;
      end;
      if verb <> '' then
        Result := cm.InvokeCommand(ici) = NOERROR
      else
      begin
        pop := CreatePopupMenu;
        try
          if Succeeded(cm.QueryContextMenu(pop, 0, 1, $7FFF, CMF_DEFAULTONLY)) then
          begin
            c := GetMenuDefaultItem(pop, 0, 0);
            if c <> 0 then
            begin
              ici.lpVerb := MakeIntResource(c - 1);
              Result := cm.InvokeCommand(ici) = NOERROR;
            end;
          end;
        finally
          DestroyMenu(pop)
        end;
      end
    end;function PidlToStr(sf: IShellFolder; childPidl: PItemIDList): string;
    var
      sr: _StrRet;
    begin
      Result := '';
      if (sf = nil) or (childPidl = nil) then Exit;
      sr.uType := STRRET_CSTR;
      if sf.GetDisplayNameOf(childPidl,SHGDN_NORMAL,sr) = NOERROR then
        case sr.uType of
          STRRET_CSTR   : Result := string(sr.cStr);
          STRRET_OFFSET : Result := string(PChar(Cardinal(childPidl) + sr.uOffset));
          STRRET_WSTR   : Result := string(sr.pOleStr);
        end;
    end;function DefaultPrinterDevice: string;
    var
      Device, Driver, Port: array [0..255] of Char;
      Mode: THandle;
    begin
      Device := '';
      with Printer do
        if Printers.Count > 0 then
          GetPrinter(Device, Driver, Port, Mode);
      Result := Device;
    end;procedure ShowPrintSpool;
    var
      pidl1, pidl2: PItemIDList;
      sf1, sf2: IShellFolder;
      malloc: IMalloc;
      el: IEnumIDList;
      c: Cardinal;
      sDefaultPrinter: string;
    begin
      if (SHGetSpecialFolderLocation(INVALID_HANDLE_VALUE, CSIDL_PRINTERS, pidl1) = NOERROR) and
        (SHGetMalloc(malloc) = NOERROR) then
        try
          if (pidl1^.mkid.cb <> 0) and (SHGetDesktopFolder(sf1) = NOERROR) and
            (sf1.BindToObject(pidl1, nil, IID_IShellFolder, Pointer(sf2)) = NOERROR) and
            (sf2.EnumObjects(Application.Handle, High(Cardinal), el) = NOERROR) then
          begin
            sDefaultPrinter := DefaultPrinterDevice;
            el.Reset;
            while el.Next(1, pidl2, c) = NOERROR do
            begin
              //if PidlToStr(sf2, pidl2) = sDefaultPrinter then
                ExecuteContextMenuCommand(Application.Handle, sf2, pidl2);
              malloc.Free(pidl2);
            end;
          end;
        finally
          malloc.Free(pidl1);
        end;
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowPrintSpool;
    end;
      

  6.   

    谢谢kingron,你提供的代码解决了问题。不过如果可以在程序中删除打印任务就更好了^-^