Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

очередь принтера [D7, WinXP]


Senator1979 ©   (2006-01-16 12:30:00) 

Подскажите пожалуйста, как получить кол-во копий документа, посланного на печать? В MSDN в структурах JOB_INFO_ не нашел.
И еще, статус печати PRINTED не всегда появляется при окончании печати.


Senator1979   (2006-01-19 17:28:00) [1]

в общем одкопал, что для корректного подсчета копий страниц необходимо разбирать spool файл spl
что то не получаеться... кто подскажет как это сделать ?


Senator1979   (2006-01-18 15:48:00) [2]

Возвращаясь к вопросу:
почему то у меня в структуре PRINTER_NOTIFY_INFO_DATA
в поле Field появляются не все возможные значения информации, хотя поле  Type = JOB_NOTIFY_TYPE.
В частности нет JOB_NOTIFY_FIELD_DEVMODE, с кот. можно бы было вытянуть кол-во копий.
В чем может быть причина?


Senator1979   (2006-01-16 16:43:00) [3]

ok, спасибо за помощь


Vile   (2006-01-16 15:26:00) [4]

Насчет двухстраничного документа - надо посмотреть в каком формате передается принтеру и тип дров (PS или PCL).

Состояние TotalPages постоянно меняется: грубо говоря напечатанные страницы переходят из корзины "TotalPages" в корзину "PagesPrinted" (это, кстати, в идеальном случае).


Senator1979   (2006-01-16 14:10:00) [5]

и все, таки: набор из каких событий однозначно говорит, что задача распечаталась?
еще интересная особенность: если документ многостраничный, то в TotalPages получается все время разная цифра (приходиться брать max)


Senator1979   (2006-01-16 14:08:00) [6]

и в диспетчере вижу 1 стр. Б.Гейтс сам себя перехитрил :-)


Rouse_   (2006-01-16 14:04:00) [7]


> в DWORD Status из JOB_INFO_2

Он содержит маску состояний возможных для текущей задачи...


Vile   (2006-01-16 14:03:00) [8]

а в диспетчере чего видишь?

приведи кусок кода с отловом (цикл по сообщениям или как?!)


Senator1979   (2006-01-16 13:53:00) [9]

to Rouse_:
в DWORD Status из JOB_INFO_2
и еще, заметил, что при печати 2-х страничного документа из Word с малым содержанием текста - отображается, как 1-страничный документ


Rouse_   (2006-01-16 13:46:00) [10]

Ааа, тебе копии, я про количество страниц подумал :)


> у меня получаеться окончательное значение статуса  DELETING
> PRINTED PRINTING,

В StatusMask ?


Vile   (2006-01-16 13:44:00) [11]

у меня на личном опыте всегда выходило DELETING PRINTING. PRINTED же возможно редко улавливается из-за его мимолетного значения - этот статус ставится и сразу же задача прибивается.


Senator1979   (2006-01-16 13:41:00) [12]

to Vile: спасибо большое (помогло).
Может тогда подскажите:
при нормальной печати документа у меня получаеться окончательное значение статуса  DELETING PRINTED PRINTING, но не всегда.
в чем может быть дело ?


Vile   (2006-01-16 13:27:00) [13]

Количество копий можно получить из DEVMODE который есть в JOB_INFO_2:

typedef struct _JOB_INFO_2 { // ji2  
   DWORD      JobId;  
   LPTSTR     pPrinterName;
   LPTSTR     pMachineName;
   LPTSTR     pUserName;
   LPTSTR     pDocument;
   LPTSTR     pNotifyName;
   LPTSTR     pDatatype;
   LPTSTR     pPrintProcessor;
   LPTSTR     pParameters;
   LPTSTR     pDriverName;
   LPDEVMODE  pDevMode;                  <-----------
   LPTSTR     pStatus;
   PSECURITY_DESCRIPTOR pSecurityDescriptor;
   DWORD      Status;
   DWORD      Priority;

   DWORD      Position;
   DWORD      StartTime;
   DWORD      UntilTime;
   DWORD      TotalPages;
   DWORD      Size;
   SYSTEMTIME Submitted;
   DWORD      Time;
   DWORD      PagesPrinted ;
} JOB_INFO_2;

typedef struct _devicemode {    // dvmd  
   BCHAR  dmDeviceName[CCHDEVICENAME];
   WORD   dmSpecVersion;
   WORD   dmDriverVersion;
   WORD   dmSize;
   WORD   dmDriverExtra;
   DWORD  dmFields;
   short  dmOrientation;
   short  dmPaperSize;
   short  dmPaperLength;
   short  dmPaperWidth;
   short  dmScale;
   short  dmCopies;                            <-------------
   short  dmDefaultSource;
   short  dmPrintQuality;
   short  dmColor;
   short  dmDuplex;
   short  dmYResolution;

   short  dmTTOption;
   short  dmCollate;
   BCHAR  dmFormName[CCHFORMNAME];
   WORD  dmLogPixels;
   DWORD  dmBitsPerPel;
   DWORD  dmPelsWidth;
   DWORD  dmPelsHeight;
   DWORD  dmDisplayFlags;
   DWORD  dmDisplayFrequency;
#if(WINVER >= 0x0400)
   DWORD  dmICMMethod;         // Windows 95 only
   DWORD  dmICMIntent;         // Windows 95 only
   DWORD  dmMediaType;         // Windows 95 only
   DWORD  dmDitherType;        // Windows 95 only

   DWORD  dmReserved1;         // Windows 95 only
   DWORD  dmReserved2;         // Windows 95 only
#endif /* WINVER >= 0x0400 */
} DEVMODE;


Senator1979   (2006-01-16 12:48:00) [14]

а в каком именно поле JOB_INFO_1 содержится количество копий документа ?


Rouse_   (2006-01-16 12:45:00) [15]

Вот тебе примерчик как очистить очередь печати - переделай на вывод информации:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, WinSpool;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   procedure Button1Click(Sender: TObject);
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
 PrintersInfo, TmpPrintersInfo: PPrinterInfo1;
 pcbNeeded, pcReturned, jpcbNeeded, jpcReturned: DWORD;
 I, J: Integer;
 hPrinter: THandle;
 JobInfo, TmpJobInfo: PJobInfo3;
begin
 EnumPrinters(PRINTER_ENUM_LOCAL, nil, 1, PrintersInfo, 0, pcbNeeded,  pcReturned);
 if GetLastError = ERROR_INSUFFICIENT_BUFFER then
 begin
   GetMem(PrintersInfo, pcbNeeded);
   try
     if EnumPrinters(PRINTER_ENUM_LOCAL, nil, 1,
       PrintersInfo, pcbNeeded, pcbNeeded,  pcReturned) then
     begin
       TmpPrintersInfo := PrintersInfo;
       for I := 0 to pcReturned - 1 do
       begin
         if OpenPrinter(TmpPrintersInfo^.pName, hPrinter, nil) then
         begin
           EnumJobs(hPrinter, 0, 100, 1, nil,
             0, jpcbNeeded, jpcReturned);
           if GetLastError in [NO_ERROR, ERROR_INSUFFICIENT_BUFFER] then
           begin
             GetMem(JobInfo, jpcbNeeded);
             try
               if EnumJobs(hPrinter, 0, 100, 3, JobInfo,
                 jpcbNeeded, jpcbNeeded, jpcReturned) then
               begin
                 TmpJobInfo := JobInfo;
                 for J := 0 to jpcReturned - 1 do
                 begin
                   if not SetJob(hPrinter, TmpJobInfo^.JobId, 0,
                     nil, JOB_CONTROL_DELETE) then RaiseLastOSError;
                   Inc(TmpJobInfo);
                 end;
               end
               else
                 RaiseLastOSError;
             finally
               FreeMem(JobInfo);
             end;
           end
           else
             RaiseLastOSError;
         end
         else
           RaiseLastOSError;
         Inc(TmpPrintersInfo);
       end;
     end
     else
       RaiseLastOSError;
   finally
     FreeMem(PrintersInfo);
   end;
 end
 else
   RaiseLastOSError;
end;

end.


Тебе нужно JOB_INFO_1


Наверх

Титульная страница Поиск, карта сайта Написать письмо