FindNextPrinterChangeNotification // JOB_NOTIFY_FIELD_PAGES_PRINTED bzw. JOB_NOTIFY_FIELD_TOTAL_PAGES



  • Hi ihrse,

    ich möchte einen Status über den Druckauftrag meines Programms ausgeben, habe dort jedoch 2 Problemchen, das eine schlimm, das andere weniger schlimm.

    1. Anzahl der "TOTAL_PAGES" des Druckauftrags, diese werden nicht direkt auf die endgültige Zahl der genauen Anzahl gesetzt, sondern Scheibchenweise, siehe weiter unten in dem Debugfenster.

    2. Hier das schlimmere Problem:
    Die Anzahl der bereits gedruckten Daten. Bei dem Beispiel unten, in welchem 3 Seiten ausgedruckt werden. erhoeht sich PRINTED_PAGES nur auf 2, danach kommt keine Änderung mehr. Dazu kommt, dass sich das bereits ändert sobald der Drucker angefangen hat zu Drucken, d.h. er hat gerade mit Seite 1 begonnen, windows liefert mir jedoch bereits, dass er bereits 2 Seiten gedruckt hat.

    - a) Wo ist Seite 3?
    - b) Ich bekomme die Änderungen zu früh.

    Als Alternative wie man so etwas realisieren kann fällt mir nur ein, nen virtuellen Drucker zu coden, was sich jedoch nicht lohnt, da es einfach zu viel Aufwand für eine solch "unwichtige" Sache ist.

    Ich habe es mit JOB_INFO_2 und JOB_NOTIFY_FIELD_PAGES_PRINTED bzw. JOB_NOTIFY_FIELD_TOTAL_PAGES probiert. Ergebnis bei beidem gleich.

    Vielleicht weiss ja jemand von euch Rat
    Vielen Dank im Voraus

    Marc

    BOOL CPrintJobs::SpyPrinter( LPCTSTR pstrPrinterName )
    {
    	TRACE ( "SpyPrinter entered\n" );
    	HANDLE	hPrinter;
    	HANDLE	hPrinterCN;
    	DWORD	dwChanged;
    
    	JOB_INFO_2 *pJob;
    	DWORD dwNeeded;
    
    	unsigned short		usPrinterJobInfo[4];
    	usPrinterJobInfo[0]		=	JOB_NOTIFY_FIELD_PRINTER_NAME;
    	usPrinterJobInfo[1]		=	JOB_NOTIFY_FIELD_DOCUMENT;
    	usPrinterJobInfo[2]		=	JOB_NOTIFY_FIELD_TOTAL_PAGES;
    	usPrinterJobInfo[3]		=	JOB_NOTIFY_FIELD_PAGES_PRINTED;
    
    	PRINTER_NOTIFY_OPTIONS_TYPE			stgPrinterNotifyOptionsType[1];
    	stgPrinterNotifyOptionsType[0].Type		=	JOB_NOTIFY_TYPE;
    	stgPrinterNotifyOptionsType[0].Count	=	4;
    	stgPrinterNotifyOptionsType[0].pFields	=	usPrinterJobInfo;
    
    	PRINTER_NOTIFY_OPTIONS		stgPrinterOptions;
    	stgPrinterOptions.Flags		=	PRINTER_NOTIFY_OPTIONS_REFRESH ;
    	stgPrinterOptions.Version	=	2;
    	stgPrinterOptions.Count		=	1;
    	stgPrinterOptions.pTypes	=	stgPrinterNotifyOptionsType;
    
    	PPRINTER_NOTIFY_INFO	pPrinterInfo;
    
    	// PrinterHandle initialisieren
    	if( TRUE == OpenPrinter( (LPTSTR) pstrPrinterName, &hPrinter, NULL ) )
    	{
    		TRACE ("PrinterHandel initialisiert\n");
    		// Drucküberwachung anstossen ...
    		hPrinterCN = FindFirstPrinterChangeNotification( hPrinter, PRINTER_CHANGE_ALL, NULL, &stgPrinterOptions );
    
    		// ... hat funktioniert?
    		if( INVALID_HANDLE_VALUE != hPrinterCN )
    		{
    			while( true	)
    			{
    				// Darauf warten, dass sich etwas bei den Druckaufträgen tut
    				WaitForSingleObject( hPrinterCN, INFINITE );
    
    				// Informationen auslesen
    				if( TRUE == FindNextPrinterChangeNotification( hPrinterCN, &dwChanged, NULL, (LPVOID *) &pPrinterInfo ) )
    				{ 
    					// Wenn ein Druckauftrag hinzugefügt wurde
    					if( PRINTER_CHANGE_ADD_JOB & dwChanged )
    					{
    						// Job pausieren
    						SetJob( hPrinter, pPrinterInfo->aData[0].Id, 0, NULL, JOB_CONTROL_PAUSE );
    						TRACE( "ADD_JOB ... Job pausieren\n");
    
    						// Job auslesen
    				/*		GetJob( hPrinter, pPrinterInfo->aData[0].Id, 2, NULL, NULL, &dwNeeded);
    						pJob = new JOB_INFO_2[dwNeeded];
    						GetJob( hPrinter, pPrinterInfo->aData[0].Id, 2, (PBYTE) pJob, dwNeeded, &dwNeeded);
    						TRACE("TotalPages: %ld\n", pJob->TotalPages );*/
    					}
    
    					// Wenn der Druckauftrag geschrieben wird
    					if( PRINTER_CHANGE_WRITE_JOB & dwChanged )
    					{
    						TRACE ("WRITE_JOB gefunden\n");
    						for( unsigned int i = 0; i < pPrinterInfo->Count; i++ )
    						{
    							// Wenn es eine Druckauftragsänderung ist
    							if( JOB_NOTIFY_TYPE == pPrinterInfo->aData[i].Type )
    							{
    								//// Anzahl zu druckender Seiten auslesen
    								if( JOB_NOTIFY_FIELD_TOTAL_PAGES == pPrinterInfo->aData[i].Field )
    								{
    									TRACE ("TotalPages: %ld\n", pPrinterInfo->aData[i].NotifyData.adwData[0] );
    								}
    								//// Anzahl gedruckter Seiten auslesen
    								if( JOB_NOTIFY_FIELD_PAGES_PRINTED == pPrinterInfo->aData[i].Field )
    								{
    									TRACE ("PagesPrinted: %ld\n", pPrinterInfo->aData[i].NotifyData.adwData[0] );
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    		return TRUE;
    	}
    	return FALSE;
    }
    
    SpyPrinter entered
    PrinterHandel initialisiert
    ADD_JOB ... Job pausieren
    WRITE_JOB gefunden
    TotalPages: 1
    WRITE_JOB gefunden
    TotalPages: 3
    
    //Hier stoße ich in der Übersicht der Druckaufträge (von windows) den Druck wieder an
    
    WRITE_JOB gefunden
    PagesPrinted: 0
    WRITE_JOB gefunden
    PagesPrinted: 0
    WRITE_JOB gefunden
    PagesPrinted: 0
    WRITE_JOB gefunden
    PagesPrinted: 1
    WRITE_JOB gefunden
    PagesPrinted: 1
    WRITE_JOB gefunden
    PagesPrinted: 2
    
    //Hier ist der Drucker jedoch gerade erst bei Blatt 1, welches er druckt
    


  • MarcA schrieb:

    Dazu kommt, dass sich das bereits ändert sobald der Drucker angefangen hat zu Drucken, d.h. er hat gerade mit Seite 1 begonnen, windows liefert mir jedoch bereits, dass er bereits 2 Seiten gedruckt hat.

    Ich denke, das liegt am Drucker-Spooler 😉



  • flenders schrieb:

    MarcA schrieb:

    Dazu kommt, dass sich das bereits ändert sobald der Drucker angefangen hat zu Drucken, d.h. er hat gerade mit Seite 1 begonnen, windows liefert mir jedoch bereits, dass er bereits 2 Seiten gedruckt hat.

    Ich denke, das liegt am Drucker-Spooler 😉

    Ja, das denke ich auch, jedoch muss es doch eine Möglichkeit geben, mein Vorhaben umzusetzen ohne gleich einen virtuellen Drucker zu programmieren.

    Gruss
    Marc



  • Willst du jetzt den Drucker-Spooler umgehen und direkt drucken?!


Anmelden zum Antworten