Noch 'ne Druckerfrage

langer1801

Erfahrenes Mitglied
Hi,
ich arbeite an einem Projekt, bei dem aus einer Datenbank (nur eine Windows-Datei, nix mit Access oder so) unterschiedliche Dokumente generiert und gedruckt werden. Nun habe ich nach dem Erstellen des Projektes die Standard-Windows-Druckfunktionen zur Verfügung. Soweit so gut. Aber wie mache ich es, diesen Standardfunktionen ein Argument zu übergeben, welches Dokument nun gerade gedruckt werden soll? Im Moment behelfe ich mir so, daß ich dieses Dokument generiere, über die CView-Klasse auf dem Bildschirm anzeige und dann über die OnDraw- oder OnPrint-Methode drucke. Ich möchte aber diesen Weg gern umgehen. Also Button anklicken - und dann wird das gewünschte Dokument gedruckt - ohnen es erst auf dem Bildschirm zu zeichnen. :confused:

Mfg

langer
 
Mit einem DOCINFO und dann StartDoc, StartPage, in HDC reinzeichen, EndPage, EndDoc kannst du das machen. Das etwas kniffligere ist, den HDC vom Drucker zu bekommen.

Hier ein Codeschnipsel, dem du den genauen Namen des Druckers übergibst, und dafür das HDC vom Drucker bekommst. Die genauen Druckernamen kannst du über EnumPrinters herausfinden.

Code:
HDC CreateHandleForPrinter( const char* printerName )
{

  HANDLE             hPrinter;

  if ( ( ::OpenPrinter( const_cast<TCHAR*>( printerName ), &hPrinter, NULL ) ) )
  {
    LPPRINTER_INFO_2  lpPrinterInfo2 = NULL;
    DWORD             sizeOfPrintInfo = 0;
    DWORD             cbReturned = 0;

    ::GetPrinter( hPrinter, 2, NULL, 0, &sizeOfPrintInfo );

    lpPrinterInfo2 = (LPPRINTER_INFO_2)new char[sizeOfPrintInfo];

    if ( ::GetPrinter( hPrinter,              // handle to printer
                       2,                        // information level
                       (LPBYTE)lpPrinterInfo2,   // printer information buffer
                       sizeOfPrintInfo,          // size of buffer
                       &cbReturned ) )             // bytes received or required
    {
      m_hDC = ::CreateDC( lpPrinterInfo2->pDriverName, 
                          lpPrinterInfo2->pPrinterName, 
                          NULL, 
                          lpPrinterInfo2->pDevMode );
    }

    delete[] lpPrinterInfo2;
    lpPrinterInfo2=NULL;

    ClosePrinter( hPrinter );
  }
  return m_hDC;

}

Den HDC im Anschluss an das Drucken mit DeleteDC wieder zerstören.
 
Hi, habe noch eine Frage zu EnumPrinters. Das Aufrufen der Funktion klappt mittlerweile prima, auch das Abfragen der Daten der verfügbaren Drucker ist kein Problem, solange ich die Flags auf PRINTER_ENUM_NAME oder PRINTER_ENUM_LOCAL setze. Leider kann ich so aber nicht herausfinden, welcher der angebotenen Drucker der Standarddrucker ist. Ich hatte eigentlich vermutet, das die Funktion mit dem gesetzten Flag PRINTER_ENUM_DEFAULT den Standarddrucker zurückgibt. Aber da bekomme ich überhaupt keinen Rückgabewert. Weder bei Level 1 noch bei Level 2.

Hier das Codebeispiel:

Code:
	DWORD gdwEnumFlags=PRINTER_ENUM_DEFAULT;
	DWORD dwBytesNeeded;
	DWORD dwPrtRet2;
	DWORD dwMaxPrt;
	LPTSTR lpName=NULL;
	LPPRINTER_INFO_2 pPrinterInfo2;

	EnumPrinters(gdwEnumFlags,lpName,2,NULL,0,&dwBytesNeeded,&dwPrtRet2);
	pPrinterInfo2=(LPPRINTER_INFO_2)new char[dwBytesNeeded];
	EnumPrinters(gdwEnumFlags,lpName,2,(LPBYTE)pPrinterInfo2,dwBytesNeeded,&dwBytesNeeded,&dwPrtRet2);
	if(dwPrtRet2)
		dwMaxPrt=dwPrtRet2;
	delete[] pPrinterInfo2;
	pPrinterInfo2=0;

Oder liege ich da falsch? Wozu gibt es denn dieses Flag?

Mfg

langer
 
Da hat MS ganz schon oft dran rumgedreht. Dieses PRINTER_ENUM_DEFAULT funktioniert nur auf der 9x-Schiene, ab 2000 gibt es die Funktion GetDefaultPrinter.
Und bei NT hat man so wie es aussieht die Ar***-Karte gezogen. Da kann ich mir langsam ein Quartett-Set zusammenstellen.
 
Danke für die Antwort. Hab mir schon sowas gedacht. Leider unterstützt meine Winspool.lib die Funktion nicht, muß ich mal sehen, wo ich ne neuere Version herbekommen.

Mfg

langer
 
Hi,
habe das Projekt mal in C++.net konvertiert und compiliert. Da gibts die Funktion. Da ich aber lieber mit C++ 6 arbeite, meine Frage: Kann mir jemand sagen, wo ich die neueste Winspool.lib und Winspool.h für C++ 6 herbekomme, die auch diese Funktion unterstützt?

Danke

langer
 
Du kannst dir das neueste Platform SDK von Microsoft runterladen und in deinem Compiler einrichten. Prüf aber vorsichtshalber vorher mal, ob das VC6 noch komplett unterstützt.
 
Nein, wird nicht mehr unterstützt. Da bin ich nun auf C++.NET umgestiegen. Läßt sich ja auch mit in C++ arbeiten :rolleyes: . Den Standarddrucker zu ermitteln, ist nun kein Problem. Auch OpenPrinter klappt, zumindest bekomme ich ein gültiges Handle zurück. Jetzt wollte ich mir mit GetPrinter die PrintInfo anzeigen lassen. Aber ich kann schreiben, was ich will, entweder meckert gleich der Compiler oder aber ich bekomme die PrintInfo nicht zurückgegeben. Hier mal der Code:
Code:
	DWORD dwBytesNeeded;
	LPBYTE pPrinterInfo2;
	HANDLE phPrinter;

	pPrinterInfo2= new BYTE [sizeof PRINTER_INFO_2];


	char szPrinter[50];
	DWORD zeichen = 50;
	GetDefaultPrinter(szPrinter, &zeichen);
	OpenPrinter(szPrinter,&phPrinter,NULL);
	if(!GetPrinter(phPrinter,2,pPrinterInfo2,sizeof PRINTER_INFO_2,&dwBytesNeeded))
	{
		delete[] pPrinterInfo2;
		pPrinterInfo2=NULL;
		pPrinterInfo2= new BYTE [dwBytesNeeded];
		GetPrinter(phPrinter,2,pPrinterInfo2,dwBytesNeeded,&dwBytesNeeded);
	}

Was mache ich denn da falsch?

Mfg

langer
 
Welche der Funktion schlägt denn daneben? OpenPrinter klappt?
Was gibt GetLastError zurück, nachdem die Funktion fehlgeschlagen ist?
 

Neue Beiträge

Zurück