Kasowanie Bufora Wydruku

0

Czy ktoś wie jak w Delphi napisać procedurę kasującą zawartość bufora wydruku w windows?
Metodę w rodzaju "net stop spooler" znam ale wykonana pod Delphi powoduje pewien problem
bo przy ponownym odpaleniu programu mamy utratę komunikacji z drukarką.

Jak wyczyścić ten bufor?

0

Bo jak stopnąłeś spoolera, to trzeba go startnąć…

0

A myślałem ,że z mojego opisu jest to oczywiste.

Może jednak ktoś potrafi wykasować ten bufor programowo bez zatrzymywania i wznawiania tego serwisu???

0

a usuwanie plików z C:\WINDOWS\SYSTEM32\spool\PRINTERS coś pomoże?

3

check this

Uses Winspool, printers;
 
Function GetCurrentPrinterHandle: THandle;
  Const
    Defaults: TPrinterDefaults = (
      pDatatype : nil;
      pDevMode  : nil;
      DesiredAccess : PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER );
  Var
    Device, Driver, Port : array[0..255] of char;
    hDeviceMode: THandle;
  Begin { GetCurrentPrinterHandle }
    Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
    If not OpenPrinter(@Device, Result, @Defaults) Then
      RaiseLastWin32Error;
  End; { GetCurrentPrinterHandle }
 
{: Kill all pending jobs on the current printer }
Procedure PurgeJobsOnCurrentPrinter;
  Var
    hPrinter: THandle;
  Begin
    hPrinter:= GetCurrentPrinterHandle;
    try
      If not WinSpool.SetPrinter( hPrinter, 0, nil, PRINTER_CONTROL_PURGE )
      Then
        RaiseLastWin32Error;
    finally
      ClosePrinter( hPrinter );
    end;
  End; { PurgeJobsOnCurrentPrinter }

znalezione na efg2.com

0

Dzięki "Misiekd" rozwiązanie działa doskonale!

Przerobiłem trochę jako jedną procedurę: mam nadzieje ,ze komuś się przyda.

//Wymagane: Uses Winspool, printers;
//Procedura kasuje wszystkie dokumenty wprowadzone do bufora wydruku windows
//przez aktualnie ustawioną domyślną drukarkę 

procedure KasujDaneBuforaWydrukuAktualnejDrukarki;
const
     Defaults: TPrinterDefaults = (
               pDatatype : nil;
               pDevMode  : nil;
               DesiredAccess : PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER );
var
     Device, Driver, Port : array[0..255] of char;
     hDeviceMode: THandle;
     hPrinter: THandle;
begin
     try
          //Ustalamy aktualną domyślną drukarkę.
          Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
          ShowMessage(Device);
          if OpenPrinter(@Device, hPrinter, @Defaults) then
          begin
               try
                    if WinSpool.SetPrinter( hPrinter, 0, nil, PRINTER_CONTROL_PURGE ) then
                         Windows.Beep(200,200);
               finally
                    ClosePrinter( hPrinter );
               end;
          end;
     except
     end;
end;

Oczywiście użytkownicy zaraz znaleźli nowy problem... gdy bufor wydruku zawiera dokumenty
wysyłane do różnych drukarek wykasowaniu ulegają tylko przeznaczone dla drukarki do jakiej mamy
pobrany hPrinter: THandle co w efekcie powoduje ,że bufor dalej jest zablokowany.Zupełnie nie wiem
jak to rozwiązać najlepiej gdyby była jakąś funkcja sprawdzająca czy bufor wydruku zawiera jakieś dane
jeśli tak to wykonujemy enumeracje po całej liście drukarek. Ciekawe czy to jest realne?

0
for i := 0 to Printer.Printers.count - 1 do
begin
  Printer.PrinterIndex := i;
  wyczyscBuforDrukarki;
end;
0

Oto finalna wersja procedury "Kasuj kasuj bufor wydruku windows"

Dzięki za pomoc w jej napisaniu.
Pozdrawiam wszystkich.

//Wymagane: Uses Winspool, Printers;
//Procedura kasuje wszystkie dokumenty wprowadzone do bufora wydruku windows
//przez dowolną z drukarek zainstalowanych w systemie windows.
//WYJSCIE: True = jesli wykasowano wszystkie dokumenty bufora wydruku dla wszystkich zainstalowanych drukarek.
//TESTY OK!
function KasujDaneBuforaWydrukuWszystkichDrukarek: boolean;
const
     Defaults: TPrinterDefaults = (
               pDatatype : nil;
               pDevMode  : nil;
               DesiredAccess : PRINTER_ACCESS_USE or PRINTER_ACCESS_ADMINISTER );
var
     Device, Driver, Port : array[0..255] of char;
     hDeviceMode: THandle;
     hPrinter: THandle;
     i:   integer;
begin
     Result:=False;
     try
          //Wyszukujemy kolejne drukarki zainstalowane w windows
          for i := 0 to Printer.Printers.count - 1 do
          begin
               Printer.PrinterIndex := i;
               Printer.GetPrinter(Device, Driver, Port, hDeviceMode);
               //ShowMessage(Device);
               if OpenPrinter(@Device, hPrinter, @Defaults) then
               begin
                    try
                         if Result then Result:= not Result;
                         if WinSpool.SetPrinter( hPrinter, 0, nil, PRINTER_CONTROL_PURGE ) then Result:=True;
                    finally
                         ClosePrinter( hPrinter );
                    end;
              end;
          end;
     except
     end;
end;
0

co to za dziwna konstrukcja??

if Result then Result:= not Result;
if WinSpool.SetPrinter( hPrinter, 0, nil, PRINTER_CONTROL_PURGE ) then Result:=True;
zamień to na
Result := WinSpool.SetPrinter( hPrinter, 0, nil, PRINTER_CONTROL_PURGE )

0

Zakładałem zawieszenie wewnątrz WinSpool.SetPrinter() co przy wcześniejszym uzyskaniu True w wyniku poprzedniego wywołania tej funkcji …wyszło by z Result równym True do sekcji try...finally a to nie było by prawidłowe?
Faktycznie wygląda dziwnie...

0

właściwie powinno być tak

               try
                     Result:=False;
                     Result:=WinSpool.SetPrinter( hPrinter, 0, nil, PRINTER_CONTROL_PURGE );
                finally
                     ClosePrinter( hPrinter );
                end;
0

co znaczy "zawieszenie"? Jak się tam sypnie to dostaniesz exception i result i tak nie jest zwracany. Jak obsługujesz wyjątki to false powinieneś zwracać w except

1 użytkowników online, w tym zalogowanych: 0, gości: 1