|
Antwort |
Registriert seit: 12. Jun 2002 Ort: BRD umd die ecke links und dann immer gerade aus 31 Beiträge |
#1
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?! |
Zitat |
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.184 Beiträge Delphi 12 Athens |
#2
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?
$2B or not $2B
|
Zitat |
Registriert seit: 12. Jun 2002 Ort: BRD umd die ecke links und dann immer gerade aus 31 Beiträge |
#3
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?
|
Zitat |
Registriert seit: 26. Mär 2007 Ort: Klingenstadt 541 Beiträge Delphi 2007 Enterprise |
#4
Es ist zu wahr um schön zu sein...
|
Zitat |
Registriert seit: 12. Jun 2002 Ort: BRD umd die ecke links und dann immer gerade aus 31 Beiträge |
#5
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:
Vielen Dank!
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. |
Zitat |
nahpets
(Gast)
n/a Beiträge |
#6
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. |
Zitat |
hathor
(Gast)
n/a Beiträge |
#7
Guckst Du hier:
http://www.delphi-forum.de/viewtopic.php?t=78173 und hier: http://cc.codegear.com/Item.aspx?id=20307 |
Zitat |
Ansicht |
Linear-Darstellung |
Zur Hybrid-Darstellung wechseln |
Zur Baum-Darstellung wechseln |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
LinkBack URL |
About LinkBacks |