Windows Programmierung: Drucken
Willemers Informatik-Ecke

Auswahl des Druckers

Für die Druckerauswahl liefert Windows seit 3.1 die Funktion PrintDlg. Hier kann der Benutzer sich seinen Lieblingsdrucker auswählen. Den Programmierer interessiert in erster Linie der Device-Kontext, in den er gerne später hineinzeichnen möchte. Um diesen zu erhalten, wird vor dem Aufruf von PrintDlg das Element Flags in der Struktur PRINTDLG mit der Konstanten PD_RETURNDC angegeben. Hat der Anwender bestätigt, findet sich der gesuchte Kontext in der Strukturvariablen hDC. Der hwndOwner wird nur für den korrekten Aufbau der Dialogbox benötigt.

PRINTDLG pd;

   memset(&pd, 0, sizeof(PRINTDLG));
   pd.lStructSize = sizeof(PRINTDLG);
   pd.hwndOwner = hWnd;
   pd.Flags     = PD_RETURNDC;

   if (PrintDlg(&pd)) {

Ausdruck durchführen

Der Druck auf Papier unterscheidet sich etwas von dem auf dem Bildschirm. So haben die wenigsten Bildschirme einen Seitenumbruch und sie müssen auch nicht den Druckmanager bemühen. Damit dieser was zu zeigen hat, erhält er einen Namen des Druckes im Feld lpszDocName der DOCINFO-Struktur. Diese wird per StartDoc übergeben. Bei Ende des Druckes braucht der Druckmanager noch ein EndDoc. Die einzelnen Seiten werden mit StartPage und EndPage eingeklammert.

Wie bereits in [1] aufgezeigt, hat StartPage die hinterlistige Eigenart, Einstellungen des Kontextes zurückzusetzen. Dies gilt auch für Aufrufe des SelectFont, so daß man diesen günstigerweise hinter StartPage positioniert.

DOCINFO di;

   memset(&di, 0, sizeof(DOCINFO));
   di.cbSize	= sizeof(DOCINFO);
   di.lpszDocName	= "drucktest";

   // drucken
   StartDoc(pd.hDC, &di);

   StartPage(pd.hDC);
   // Inhalt ausgeben
   SelectObject(pd.hDC, MyFont);
   TextOut(pd.hDC, 70, 70, String, strlen(String));
   TextOut(pd.hDC, 10, 17, String, strlen(String));
   EndPage(pd.hDC);

   EndDoc(pd.hDC);  // Dokument wird geschlossen

Mit etwas Geschick ist es nicht schwer, die Paint-Routine des Bildschirms so zu stricken, daß man sie für die Ausgabe auf dem Drucker mitverwenden kann. Einen Offset braucht man für die Rollbalken des Fensters meist sowieso, so daß nur noch der Rand rechts und unten rechtzeitig gekappt werden muß. Für die Ermittlung der Seitengröße wird wiederum GetDeviceCaps herangezogen.

Aufräumarbeiten

Nach dem Drucken sollte der Drucker-Kontext wieder freigegeben werden. Auch die von PrintDlg gelieferten Handles für Device-Mode und -Name sollten Windows wieder zurückgegeben werden.

      DeleteDC(pd.hDC);
   }
   if (pd.hDevMode != NULL) GlobalFree(pd.hDevMode);
   if (pd.hDevNames != NULL) GlobalFree(pd.hDevNames);

Literatur:

  1. Thomas Hornschuh: Druckmittel nutzen - Druckerprogrammierung unter Windows. c't 8/95, S. 222ff.
  2. Marcellus Buchheit: Windows Programmierbuch. Sybex 1992.
  3. Charles Petzold: Programmierung unter Windows 3.1, Microsoft Press, 1992.
  4. Peter Norton, Paul Yao: Windows 3, Programmiertechniken für Profis, Markt & Technik, 1991.
  5. Thomas Hornschuh: Tuschkasten-Bürokratie - Grafikprogrammierung unter Windows. c't 7/94, S. 206ff.