Drucken, Seitengrösse ausrechnen (mehrere Probleme)
-
Ich hänge momentan wieder bei meiner Druckausgabe.
Ich habe alles zu druckende (kein Dokument!) in einem langen String. Dieser String ist von seiner Länge her variabel, passt also mal auf eine Seite drauf, ein anderes Mal nicht.
Um in Abhängigkeit von der Länge des Strings Seiten zu erzeugen möchte ich erstmal wissen, wieviel ich auf eine Seite drucken kann.
Hierzu greife ich auf den DC des Windows zu, von welchem aus ich den Printdialog aufrufe und ermittle die Höhe des verwendeten Fonts (der in diesem Fall ein von System zu System unterschiedlicher Standardfont ist was mich somit auf die sichere Seite bringt) und die durchschnittliche Breite in einer TEXTMETRICS-Struktur.
HDC hdc; TEXTMETRIC tm; DWORD dwCharX, dwCharY, dwLineLen, dwLines; // Get the metrics of the current font hdc = GetDC(hWnd); GetTextMetrics(hdc, &tm); ReleaseDC(hWnd, hdc); // Save the average character width and height dwCharX = tm.tmAveCharWidth; dwCharY = tm.tmHeight;
Mein erstes Problem ist, dass ich nicht weiss in welcher Grösse nun die Angaben über Height und Width sind. MSDN sagt mir "logical unit" womit ich nichts anfangen kann. Sind es Pixel oder Point oder was anderes?
Später ermittle ich mir die Grösse des bedruckbaren Bereichs:
width = GetDeviceCaps(gsPD.hDC, HORZRES); height = GetDeviceCaps(gsPD.hDC, VERTRES);
Die hierbei zurückgelieferten Werte sollten - nach meinem Verständnis - Pixel sein.
Um nun zu wissen wieviel ich drucken kann muss ich die beiden Werte in Abhängigkeit voneinander bringen:
// Calculate the maximum width of a line and the maximum number of lines in the client area dwLineLen = width - dwCharX; dwLines = height / dwCharY;
Dieses haut so nicht hin, da ich die Werte dwCharX und dwCharY erst in Pixel umrechnen muss, was sich allerdings als nahezu unmöglich erweist, wenn ich nicht weiss in welcher Grösse sie sind.
Kann mir da bitte jemand weiterhelfen?
Praktisches Beispiel:
dwCharX liefert mir 7 und dwCharY 16, height liefert mir 3425.
3425 / 16 = 214,0625 Zeilen auf einem A4-Blatt druckbar. Kann nicht.
Hab nachgezählt und es müssten 79 Zeilen als Ergebnis rauskommen.
Wenn ich annehme, dass 16 Point ist und Point in Pixel umrechne (16 / 0,75 = 21,Periode3) kann ich immer noch 160,54 Zeilen ausdrucken, auch zu viel.
Demnach wird es nicht Point sein sondern eine andere Einheit die mir tm.tmHeight und tm.AverageWidth zurückliefert.
Nur welche?Danke.
-
Vielleicht hilft LPtoDP oder SetMapMode
Ein vielleicht auch noch ganz interessanter Artikel aus der MSDN-Library: Paragraph Formatting
-
Vielen Dank, Flenders.
Ich hab jetzt auch die Lösung gefunden.
Und zwar:
*narf*
Also, eigentlich gibt laut MSDN die TEXTMETRIC-Struktur die Grössen immer in Logical Units zurück.
Durch intensive Recherche im Netz hab ich erfahren, dass eine Logical Unit mit einem TWIPS gleichzusetzen ist.
Das kann aber nicht, wenn man es mal einsetzt und nachrechnet (20 TWIPS = 1 Point).Die Lösung sieht nun wie folgt aus:
Ich habe - wie man sehen kann - überhaupt keinen Mapping Mode gesetzt und bin daher davon ausgegangen, dass ich Logical Units zurückbekomme. Logisch, eigentlich.
War aber falsch.
Die Applikation / der Compiler / whatever führt in meinem Falle ohne Angabe eines Mapping Modes automatisch eine Umrechnung von Logical Units in Device Pixel durch, was in diesem Falle bei einem Drucker Points sind
Habe per SetMapMode mal MM_TWIPS angegeben was ja äquivalent zu Logical Units sein müsste und bekomme da auch tatsächlich andere Grössen raus.So.
Die Erklärung zu den 160 Zeilen als Maximum ist wiederrum auch ganz einfach: Zeilenabstand.
Den Zeilenabstand bekomme ich nicht zurückgeliefert, er hat aber die gleiche Höhe des Fonts.
Also nehme ich die gelieferten Punkte mal 2 (=32), setze es in die Formel ein und bekomme, voilá, 80 Zeilen raus.Das, was ich brauche.
Besten Dank