AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Gedruckte Seiten zählen

Offene Frage von "nsamaster"
Ein Thema von nsamaster · begonnen am 11. Okt 2008 · letzter Beitrag vom 27. Okt 2008
Antwort Antwort
nsamaster

Registriert seit: 12. Jun 2002
Ort: BRD umd die ecke links und dann immer gerade aus
31 Beiträge
 
#1

Gedruckte Seiten zählen

  Alt 11. Okt 2008, 22:15
Hallo!

Ich suche einen Weg, wie ich die Anzahl der gedruckten Seiten einer Windows-Sitzung (also vom Starten von Windows bis zum herunterfahren) raus bekommen kann.

Vielleicht kann man sich irgendwie in den Druckertreiber einklinken und entsprechende Info's auslesen?!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.195 Beiträge
 
Delphi 12 Athens
 
#2

Re: Gedruckte Seiten zählen

  Alt 11. Okt 2008, 22:31
Ich glaub kaum, daß Windows oder der Treiber das irgendwo mitzählt.

Aber ich weiß, daß mein Drucker es selber macht. (des steht zumindestens auf dem Diagnoseausdruck, also die Anzahl seit er existiert)
Müßte man nur den Wert bei Beginn auslesen und am Ende vom letzen Stand abrechnen (wenn es funktioniert).

Aber selbst wenn mn diesen Wert irgendwie auslesen kann, so wird das doh bestimmt bei jeder Firma und fast jedem Model anders zu machen ein (falls der Drucker es überhaupt mitzählt ... der alte Drucker hier tat das jedenfalls nicht)

Allerdings sollte es möglich sein sich zwischen Windows und Druckertreiber einzuschleußen, oder in die Windows Druckerwarteschlange und selber mitzuzählen?
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
nsamaster

Registriert seit: 12. Jun 2002
Ort: BRD umd die ecke links und dann immer gerade aus
31 Beiträge
 
#3

Re: Gedruckte Seiten zählen

  Alt 12. Okt 2008, 21:52
Und wie kann ich mich bzw. ein Programm einscheußen? Ich gehe mal davon aus, das das mit Messages irgendwie geht aber wie? Hat vielleicht jemand eine Idee?
  Mit Zitat antworten Zitat
Benutzerbild von Dunkel
Dunkel

Registriert seit: 26. Mär 2007
Ort: Klingenstadt
541 Beiträge
 
Delphi 2007 Enterprise
 
#4

Re: Gedruckte Seiten zählen

  Alt 12. Okt 2008, 22:01
Vielleicht kannst Du ja damit was anfangen.

Edit: das scheint auch recht interessant zu sein.
Es ist zu wahr um schön zu sein...
  Mit Zitat antworten Zitat
nsamaster

Registriert seit: 12. Jun 2002
Ort: BRD umd die ecke links und dann immer gerade aus
31 Beiträge
 
#5

Re: Gedruckte Seiten zählen - die zweite!

  Alt 22. Okt 2008, 08:47
Vielen Dank für den Link - der für madshi.net hat mir (mehr oder weniger) schon weiter geholfen. Allerdings komme ich mit dem Code nicht klar. Mein Englisch ist leider auch nicht so exzellent, dass ich im dortigen Forum nachfragen könnte.

Daher habe ich den Code hier abgebildet. Vielleicht kann mir ja jemand erklären wie ich an die entsprechenden Werte ran komme. Ich versteh leider nicht so viel von dem Code.
Das was ich verstehe ist folgendes:

Die Funktion "GetNbPages" liefert mir die gedruckten Seiten zurück, aber wohin? Wie kann ich mit meinem Programm diese Daten auswerten, bzw. die Funktion aufrufen? Da das eine Callback - DLL ist, bin ich mir nicht so ganz sicher, ob ich die Funktion per DLL-Aufruf in meinem Programm so einfach aufrufen kann - mit entsprechenden Anpassungen natürlich.

Ebenso tabbe ich völlig im dunkeln was die Procedure "NotiyApplication" macht. Der Name verheist zwar einiges, aber wie komme ich an die Funktion, bzw. was macht diese Procedure??? Ist mir ein völliges Rätsel...

Scheinbar fängt die DLL Functionen bestimmter Dateien ab, so zum Beispiel:
HookAPI('gdi32.dll', 'CreateDCW', @CreateDCWCallback, @CreateDCWNext); Scheinbar bin ich da auf dem Holzweg, mit meinem Wissen. Ich dachte immer, man kann nur Windows-Messages mittels Hooks abfangen. Vielleicht kennt jemand ein paar Links, mit welchen ich mich etwas tiefer in diese Materie einlesen kann. Nur zum Vorbeugen: Das Tutorial von Assabard kenne ich was Hook's betrifft. Ich glaube aber mich erinnern zu können, dass dort nur von Windows-Messages die Rede war.

So, hier noch der Code:
Delphi-Quellcode:
library ctHook;

{$IMAGEBASE $5a000000}  // <---- Was'n das???

uses
  Windows,
  madCodeHook,
  madStrings,
  Dialogs,
  WinSpool,
  SysUtils,
  classes,
  idUDPClient,
  madRemote,
  Math;
  // Registre in '..\Programme\Borland\Delphi7\Commun\Registre.pas';

type
  TPrintNotification = record
    process : array [0..MAX_PATH] of char;
    api : array [0..MAX_PATH] of char;
    params : array [0..MAX_PATH] of char;
    result : array [0..MAX_PATH] of char;
    pages : array [0..MAX_PATH] of char;
  end;

var EndDocPages,
    DPPages : integer ;
    FileDebug : TStringList;


{
fonction : NotifyApplication
}

procedure NotifyApplication(api: string; deviceA : Pchar; deviceW: pwidechar;Color:boolean;pages:word);
var pn : TPrintNotification;
    arrChA : array [0..MAX_PATH] of char;
    arrChW : array [0..MAX_PATH] of wideChar;
    session : dword;
    UDPClient : TidUDPClient;
    s,ToSend : String;
begin
  // fill the "process" and "api" strings, the format is independent of the API
  if GetVersion and $80000000 = 0 then begin
    GetModuleFileNameW(0, arrChW, MAX_PATH);
    WideToAnsi(arrChW, pn.process);
  end else
    GetModuleFileNameA(0, pn.process, MAX_PATH);
  lstrcpyA(pn.api, pchar(api));
  //addDebug(pn.process);
  if (deviceA <> nil) then
     begin
          lstrcpyA(arrChA, deviceA);
          arrChA[11] := #0;
          if lstrcmpA('\\.\DISPLAY', arrChA) = 0 then
             // no, we don't want to display dcs!
             exit;
          lstrcpyA(arrChA, deviceA);
    end
    else if (DeviceW<>Nil) Then
    begin
         lstrcpyW(arrChW, deviceW);
         arrChW[11] := #0;
         if lstrcmpW('\\.\DISPLAY', arrChW) = 0 then
            exit;
         WideToAnsi(deviceW, arrChA);
    end;
  lstrcpyA(pn.pages, pchar(madStrings.IntToStrEx(integer(Pages),2)));
  if color then
     lstrcpyA(pn.params, pchar('Color'))
  Else
     lstrcpyA(pn.params, pchar('BlackAndWhite'));

  // which terminal server (XP fast user switching) session shall we contact?
  if AmSystemProcess and (GetCurrentSessionId = 0) then
    // some system process are independent of sessions
    // so let's contact the PrintMonitor application instance
    // which is running in the current input session
    session := GetInputSessionId
  else
    // we're an application running in a specific session
    // let's contact the PrintMonitor application instance
    // which runs in the same session as we do
    session := GetCurrentSessionId;
  // now send the composed strings to our log window
  // hopefully there's an instance running in the specified session

  s:=lowercase(Trim(String(pn.api)));

  ToSend:='';
   {if (s=lowercase('EndDoc')) and (CMregistry.GetCountPrint='true') then
       ToSend:='PRINT|'+String(pn.pages)+'|'+String(pn.process)+'|'+String(pn.params); }

  if s=lowercase('EndDoc') then
       ToSend:='PRINT|'+String(pn.pages)+'|'+String(pn.process)+'|'+String(pn.params);

  if ToSend<>'then
  Begin
       UDPClient:=TidUDPClient.Create(Nil);
       UDPClient.Host:='localhost';
       UDPClient.Port:=11020;
       UDPClient.Send(ToSend); // i'm using UDP Notification to a Server
       FreeAndNil(UDPClient);
  End;

end;

// ***************************************************************

var CreateDCANext : function (driver, device, output: pchar; dm: PDeviceModeA) : dword; stdcall;
    CreateDCWNext : function (driver, device, output: pwidechar; dm: PDeviceModeW) : dword; stdcall;
    aDmin, admout : TDeviceModeA;
    wDmin, wdmout : TDeviceModeW;
    StartDocANext : function (dc: dword; const di: TDocInfoA) : integer; stdcall;
    StartDocWNext : function (dc: dword; const di: TDocInfoW) : integer; stdcall;
    EndDocNext : function (dc: dword) : integer; stdcall;
    StartPageNext : function (dc: dword) : integer; stdcall;
    EndPageNext : function (dc: dword) : integer; stdcall;
    AbortDocNext : function (dc: dword) : integer; stdcall;
    DocumentPropertiesNext : function (hWnd: HWND; hPrinter: THandle; pDeviceName: PChar; const pDevModeOutput: TDeviceMode; var pDevModeInput: TDeviceMode; fMode: DWORD): Longint; stdcall;
    DocumentPropertiesANext : function (hWnd: HWND; hPrinter: THandle; pDeviceName: PAnsiChar; const pDevModeOutput: TDeviceModeA; var pDevModeInput: TDeviceModeA; fMode: DWORD): Longint; stdcall;
    DocumentPropertiesWNext : function (hWnd: HWND; hPrinter: THandle; pDeviceName: PWideChar; const pDevModeOutput: TDeviceModeW; var pDevModeInput: TDeviceModeW; fMode: DWORD): Longint; stdcall;
    OpenPrinterNext : function (pPrinterName: PChar; var phPrinter: THandle; pDefault: PPrinterDefaults): BOOL; stdcall;
    OpenPrinterANext : function (pPrinterName: PAnsiChar; var phPrinter: THandle; pDefault: PPrinterDefaultsA): BOOL; stdcall;
    OpenPrinterWNext : function (pPrinterName: PWideChar; var phPrinter: THandle; pDefault: PPrinterDefaultsW): BOOL; stdcall;


{
fonction : GetNbPages
}


function GetNbPages:integer;
Begin
     Result:=IfThen(DPPages=0,1,DPPages)*IfThen(EndDocPages=0,1,EndDocPages);
     ShowMessage(IntToStr(Result));
End;

{
fonction : DocumentPropertiesCallBack
}

function DocumentPropertiesCallBack (hWnd: HWND; hPrinter: THandle; pDeviceName: PChar;
                                     const pDevModeOutput: TDeviceMode;
                                     var pDevModeInput: TDeviceMode;
                                     fMode: DWORD): Longint; stdcall;
Begin
     Result:=DocumentPropertiesNext(hWnd, hPrinter,pDeviceName, pDevModeoutput, pDevModeInput, fMode);
     if (fMode and DM_OUT_BUFFER = DM_OUT_BUFFER) Then
     Begin
          try
             aDmin:=pDevModeinput;
             admout:=pDevModeoutput;
          except
          End;
          try
             if dppages<=pDevModeOutput.dmCopies then
                DPPages:=pDevModeOutput.dmCopies;
             NotifyApplication('DocumentProperties', pDeviceName,Nil, (pDevModeOutput.dmColor AND DMCOLOR_COLOR = DMCOLOR_COLOR),pDevModeOutput.dmCopies);
          Except
          End;
     End;
End;

{
fonction : DocumentPropertiesACallBack
}

function DocumentPropertiesACallBack (hWnd: HWND; hPrinter: THandle; pDeviceName: PAnsiChar; const pDevModeOutput: TDeviceModeA; var pDevModeInput: TDeviceModeA; fMode: DWORD): Longint; stdcall;
Begin
     Result:=DocumentPropertiesANext(hWnd, hPrinter,pDeviceName, pDevModeoutput, pDevModeInput, fMode);
     if (fMode and DM_OUT_BUFFER = DM_OUT_BUFFER) Then
     begin
          try
             aDmin:=pDevModeinput;
             admout:=pDevModeoutput;
          except
          End;
          try
             if dppages<=pDevModeOutput.dmCopies then
                DPPages:=pDevModeOutput.dmCopies;
             NotifyApplication('DocumentPropertiesA', pDeviceName,Nil, (pDevModeOutput.dmColor AND DMCOLOR_COLOR = DMCOLOR_COLOR),pDevModeOutput.dmCopies);
          Except
          End;
     End;
End;

{
fonction : DocumentPropertiesWCallBack
}

function DocumentPropertiesWCallBack (hWnd: HWND; hPrinter: THandle; pDeviceName: PWideChar; const pDevModeOutput: TDeviceModeW; var pDevModeInput: TDeviceModeW; fMode: DWORD): Longint; stdcall;
Begin
     Result:=DocumentPropertiesWNext(hWnd, hPrinter,pDeviceName, pDevModeoutput, pDevModeInput, fMode);
     if (fMode and DM_OUT_BUFFER = DM_OUT_BUFFER) Then
     Begin
          try
             wDmin:=pDevModeinput;
             wdmout:=pDevModeoutput;
          Except
          End;
          try
             if dppages<=pDevModeOutput.dmCopies then
                DPPages:=pDevModeOutput.dmCopies;
             NotifyApplication('DocumentPropertiesW', Nil, pDeviceName, (pDevModeOutput.dmColor AND DMCOLOR_COLOR = DMCOLOR_COLOR),pDevModeOutput.dmCopies);
          Except
          End;
     End;
End;

{
fonction : CreateDCACallBack
}

function CreateDCACallback(driver, device, output: pchar; dm: PDeviceModeA) : dword; stdcall;
begin
  result := CreateDCANext(driver, device, output, dm);
  // we log this call only if it is a printer DC creation
  if (device <> nil) and (not IsBadReadPtr(device, 1)) and (device^ <> #0) then
  Begin
       try
          if (dm=Nil) then dm:=@aDmout;
       except
       End;
       try
          NotifyApplication('CreateDCA', device, Nil, (dm.dmColor AND DMCOLOR_COLOR = DMCOLOR_COLOR),dm.dmCopies);
       Except
       End;
  End;
end;

{
fonction : CreateDCWCallBack
Description : Fonction API Hooké : CreateDCW
}

function CreateDCWCallback(driver, device, output: pwidechar; dm: PDeviceModeW) : dword; stdcall;
begin
  result := CreateDCWNext(driver, device, output, dm);
  if (device <> nil) and (not IsBadReadPtr(device, 2)) and (device^ <> #0) then
  Begin
       try
          if (dm=Nil) then dm:=@wDmout;
       Except
       End;
       try
          NotifyApplication('CreateDCW', Nil, device, (dm.dmColor AND DMCOLOR_COLOR = DMCOLOR_COLOR),dm.dmCopies);
       Except
       End;
  End;
end;

{
fonction : StartDocACallBack
}

function StartDocACallback(dc: dword; const di: TDocInfoA) : integer; stdcall;
begin
  result := StartDocANext(dc, di);
  EndDocPages:=0; // Number Of Pages Initialization
  NotifyApplication('StartDocA', nil, nil, true, Word(EndDocPages));
end;

{
fonction : StartDocWCallBack
}

function StartDocWCallback(dc: dword; const di: TDocInfoW) : integer; stdcall;
begin
  result := StartDocWNext(dc, di);
  EndDocPages:=0; // Number Of Pages Initialization
  NotifyApplication('StartDocW', nil, nil, true, Word(EndDocPages));
end;

{
fonction : EndDocCallBack
}

function EndDocCallback(dc: dword) : integer; stdcall;
begin
  result := EndDocNext(dc);
  NotifyApplication('EndDoc', nil, nil, true, Word(GetNbPages)); // HERE I SEND BACK THE REAL NUMBER OF PAGES
  EndDocPages:=0; // Reinitialization of NbrOfPages (to be sure :)
  DPPages:=0;
end;

{
fonction : StartPage
}

function StartPageCallback(dc: dword) : integer; stdcall;
begin
  result := StartPageNext(dc);
  inc(EndDocPages);
  NotifyApplication('StartPage', nil, nil, true, Word(EndDocPages));
end;

{
fonction : EndPage
}

function EndPageCallback(dc: dword) : integer; stdcall;
begin
  result := EndPageNext(dc);
  NotifyApplication('EndPage', nil, nil, true, Word(EndDocPages));
end;

{
fonction : AbortDocCallBack
}

function AbortDocCallback(dc: dword) : integer; stdcall;
begin
  result := AbortDocNext(dc);
  NotifyApplication('AbortDoc', nil, nil, true, Word(EndDocPages));
end;

// ***************************************************************

{
fonction : libExit
Description : Fonction de sortie de DLL
}

procedure LibExit(Reason: Integer);
begin
  if Reason = DLL_PROCESS_DETACH then
  begin
       FreeAndNil(FileDebug);
  end;
end;

{
fonction : OpenPrinterCallBack
}

function OpenPrinterCallback (pPrinterName: PChar; var phPrinter: THandle; pDefault: PPrinterDefaults): BOOL; stdcall;
Begin
  Result:=openPrinterNext(pPrinterName, phPrinter, pDefault);
  NotifyApplication('OpenPrinter', pPrinterName,Nil, False ,0);
End;
// ***************************************************************

function OpenPrinterACallback (pPrinterName: PChar; var phPrinter: THandle; pDefault: PPrinterDefaults): BOOL; stdcall;
Begin
  Result:=openPrinterANext(pPrinterName, phPrinter, pDefault);
  NotifyApplication('OpenPrinterA', pPrinterName,Nil, False ,0);
End;

function OpenPrinterWCallback (pPrinterName: PWideChar; var phPrinter: THandle; pDefault: PPrinterDefaultsW): BOOL; stdcall;
Begin
  Result:=openPrinterWNext(pPrinterName, phPrinter, pDefault);
  NotifyApplication('OpenPrinterW', PAnsiChar(pPrinterName), Nil, False ,0);
End;

begin
     EndDocPages:=0;
     DPPages:=0;
     // collecting hooks can improve the hook installation performance in win9x
     CollectHooks;

     // Hook sur CreateDCA
     HookAPI('gdi32.dll', 'CreateDCA', @CreateDCACallback, @CreateDCANext);

     // Hook sur Documentproperties et DocumentpropertiesA
     HookAPI('winspool.drv', 'DocumentProperties', @DocumentPropertiesCallback, @DocumentPropertiesNext );
     HookAPI('winspool.drv', 'DocumentPropertiesA', @DocumentPropertiesACallback, @DocumentPropertiesANext );

     // Hook sur les fonctions d'impressions
     HookAPI('gdi32.dll', 'StartDocA', @StartDocACallback, @StartDocANext);
     HookAPI('gdi32.dll', 'EndDoc', @EndDocCallback, @EndDocNext );
     HookAPI('gdi32.dll', 'StartPage', @StartPageCallback, @StartPageNext);
     HookAPI('gdi32.dll', 'EndPage', @EndPageCallback, @EndPageNext );
     HookAPI('gdi32.dll', 'AbortDoc', @AbortDocCallback, @AbortDocNext );


     // Les fonctions Hookées ici sont celles des systèmes réellement
     // 32-Bits : Windows NT, Windows 2000 et Windows XP
     // il s'agit des mêmes que ci-dessus mais en 'Wide' => Concerne les chaînes
     // de caractères unicode
     if Win32Platform = VER_PLATFORM_WIN32_NT then
     Begin
          HookAPI('gdi32.dll', 'CreateDCW', @CreateDCWCallback, @CreateDCWNext);
          HookAPI('winspool.drv', 'DocumentPropertiesW', @DocumentPropertiesWCallback, @DocumentPropertiesWNext );
          HookAPI('winspool.drv', 'OpenPrinter', @OpenPrinterCallback, @OpenPrinterNext );
          HookAPI('winspool.drv', 'OpenPrinterA', @OpenPrinterACallback, @OpenPrinterANext );
          HookAPI('winspool.drv', 'OpenPrinterW', @OpenPrinterWCallback, @OpenPrinterWNext );
          HookAPI('gdi32.dll', 'StartDocW', @StartDocWCallback, @StartDocWNext);
          //HookAPI('kernel32.dll', 'CreateProcessW', @CreateProcessWCallback, @CreateProcessWNext);
     End;

     FlushHooks;

     DllProc := @LibExit; // installer la procédure de sortie LibExit
end.
Vielen Dank!
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#6

Re: Gedruckte Seiten zählen

  Alt 22. Okt 2008, 09:43
Hallo,

Deine Fragen kann ich Dir nicht beantworten, aber bei den Sourcen findest Du unter madCodeHook\Demos\system wide\Printmonitor ein Programm (mit Quelltext), dass zum Teil Deinen gewünschten Aufgaben entspricht.

Wenn Du dort in der Prozedure HandlePrintNotification die Werte von SubItems.Add(api) abgreifst, solltest Du Deinem Ziel näher kommen.
  Mit Zitat antworten Zitat
hathor
(Gast)

n/a Beiträge
 
#7

Re: Gedruckte Seiten zählen

  Alt 27. Okt 2008, 09:52
Guckst Du hier:

http://www.delphi-forum.de/viewtopic.php?t=78173

und hier:

http://cc.codegear.com/Item.aspx?id=20307
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz