vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Blitzschnelles Erstellen von grafischen Diagrammen!  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Rainer
Datum: 19.12.17 17:01

Hallo,
ich habe eine Routine geschrieben, mit der Datensätze einer DB-Tabelle gedruckt werden. Vor der Druckausgabe erzeuge ich eine Bildschirmübersicht mit dem Steuerelement "PrintPreviewControl". Diese dient in erster Linie dazu die Seitenanzahl der Dokuments zu ermitteln und damit eine Auswahl der zu druckenden Seiten zu ermöglichen. In der Testphase habe ich mit einer DB-Tabelle, die anhand der von PrintPreviewControl erstellten Übersicht insgesamt 99 Druckseiten ergab, gearbeitet. Als ich versuchte die Seite 99 auszudrucken, erhielt ich eine leere Seite. Erst bei Seite 97 erhielt ich das Ende der Liste gedruckt. Ein Vergleich mit dem Inhalt der DB-Tabelle stellte ich fest: es fehlte kein einziger Datensatz.
Daraufhin prüfte ich die Seite 1 genauer und fand heraus, daß diese im Vergleich zur Bildschirmanzeige zwei Datensätze mehr enthielt.
Zur Herangehensweise beim Aufbau der zu druckenden Datenzeile: mit der Graphics-Funktion "MeasureString" ermittle ich die für die Druckausgabe erforderliche Druckraumhöhe (abhängig von der FONT-Einstellung), prüfe ob dieser Platz auf der Seite noch verfügbar ist und führe den Druck ggf. auf der neuen Seite aus.
Bei der Suche nach der Ursache für die unterschiedliche Datensatzanzahl pro Seite stellte ich fest, daß die Graphics-Funktion für die Zeilenhöhe bei gleicher FONT-Einstellung (Schriftart, Style und Size) für die Darstellung im PrintPreviewControl und in der Druckausführung unterschiedliche Werte berechnet.

Beispiel:
Zeilenhöhe bei Arial, 11, mager für Display 19,478 Grafikpunkte und für den Druck 18,978 Grafikpunkte; das sind beim Druck im Vergleich zur Bildschirmdarstellung 2,566 % weniger Grafikpunkte. Dieser Prozentsatz ist stabil, d.h. er gilt für alle von mir getesteten FONT-Einstellungen. Ich konnte dies aber nur an einem Drucker (Brother MFC-J480 DW) testen. Da es sich bei MeasureString um eine Systemfunktion handelt, würde ich eine druckerabhängige Ursache ausschließen.

Bevor ich nun in meinem Algorithmus einen Korrekturfaktor einführe, möchte ich Euch fragen:
1. Hat jemand von Euch auch diese Diskrepanz festgestellt?
2. Welche anderen Möglichkeiten der Umgehung dieser Diskrepanz kennt Ihr?
3. Habe ich ggf. die Graphics-Funktion falsch verwendet?

In der Hoffnung jemand kann mir weiterhelfen, wünsche ich der Forum-Gemeinde schöne Feiertage.
Rainer.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: sv00010
Datum: 20.12.17 19:40

Es gibt noch zu überprüfen, ob die Seitenränder bei der Anzeige und beim Druck eventuell verschieden sind.
Du solltest eventuell von beiden Screenshots machen und dann im Grapfikprogramm auf die höchste Vergrößerung stellen und bei einer gleichen Zeile bei beiden mal die Pixelanzahl zählen und vergleichen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Kuno60
Datum: 21.12.17 00:36

Hallo,
dieses Problem ist mir seit Jahren bekannt und ich wäre auch an einer Lösung interessiert.

MeasureString liefert bei gleichem Font, 3 verschiedene Größen:
- beim zeichnen auf dem Bildschirm
- beim zeichnen im PrintPreviewControl
- beim ausdrucken

Dieses Verhalten ist unabhängig vom Font und vom Drucker.
Es werden nicht nur unterschiedliche Größen gemessen, sondern auch unterschiedliche Größen gezeichnet.

Folgendes habe ich festgestellt:
Bei der Ausgabe an den Drucker wird 100 DPI verwendet und bei der Ausgabe auf den Bildschirm 96 DPI.
Das PrintPreviewControl scheint irgendwie Zoll in Millimeter umzurechnen. Der Wert von 2,566% deutet darauf hin und es werden alle Strings 2,566% größer gezeichnet.
Dies betrifft nur DrawString. Die anderen Funktionen wie DrawRectangle usw. sind davon nicht betroffen.

"PrintableArea" liefert die exakte Größe des druckbaren Bereiches. Damit kann man die genaue Zeilenanzahl berechnen und es wird korrekt gedruckt. Die Darstellung im PrintPreviewControl kann dann aber abweichen.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Manfred X
Datum: 21.12.17 09:08

Hallo!

Das Problem hängt vermutlich an den Unterschieden zwischen
Dot und Pixel.

Ich setze gewöhnlich bei der Aufbereitung des Ausdrucks
harte Seitenumbrüche, um sicherzustellen, daß bestimmte
inhaltliche "Blöcke" jeweils auf einer Seite gedruckt werden.

Das Windows.Forms zugrundeliegende Graphik-System ist veraltet.

Beitrag wurde zuletzt am 21.12.17 um 09:12:10 editiert.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Franki
Datum: 23.12.17 04:20

Hallo Manfred X
Zitat:


Ich setze gewöhnlich bei der Aufbereitung des Ausdrucks
harte Seitenumbrüche, um sicherzustellen, daß bestimmte
inhaltliche Blöcke jeweils auf einer Seite
gedruckt werden.


Und wie ermittelst du die jeweiligen Blöcke bzw. deren Größe? Du gehst das ja bestimmt nich per Hand in der Vorschau durch und verschiebst dann Teile auf eine andere Seite. Und was ist wenn ein Block mal mehrere Seiten lang ist?

Bei den MS Office Programmen hat man ja vorher diverse Einstellmöglichkeiten, die sollte man für die eigene Anwendung auch so gestalten. Ist wie man an der Frage sieht oft schwierig, aber je nach Anwendung kann das passen wie du es beschreibst.

Zitat:


Das Windows.Forms zugrundeliegende Graphik-System ist
veraltet.


Hast du eine Alternative?

Gruß und frohe Weihnachten,
Frank
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Manfred X
Datum: 23.12.17 11:09

Hallo!

Die Größe des druckbaren Bereichs für die gültige Printereinstellung
kann abgefragt werden - die Zahl der Zeilen pro Seite bzw. die Blockhöhe
läßt sich (wie von Kuno60 dargelegt) "ungefähr" ermitteln und der Platzbedarf
wird bei der Seitenaufteilung per Code ggf. automatisch abgerundet.
(Die Seitenanzeige der Druckvorschau ist dafür keine geeignete
Bezugsgröße.)

Da ich - als "Umweltfanatiker" (kein Auto, kaum Fleisch, nur Stromspar-
Computer) - nur selten etwas drucke, habe ich mir über Alternativen zu
den integrierten Net-Druckfunktionen noch keine Gedanken gemacht.
Direkt ausgedruckt wird von mir ohnehin kaum etwas, sondern es werden
gewöhnlich Druckdateien erzeugt. (Die kann man als Druck-Vorschau
verwenden).
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Rainer
Datum: 25.12.17 13:02

Hallo,
auch Euch allen ein schönes Weihnachtsfest.
Ich habe einige Zeit gebraucht, aber jetzt habe ich eine - zumindest für meine Bedürfnisse eine brauchbare - Lösung, die ich Euch aus Platzgründen (> 5 kB) in den nachfolgenden zwei Antworten präsentiere. Mit dem Bemerkungsteil sind diese zwei Antworten ebenfalls zu groß, sodaß ich die Bemerkungen für beide Funktionen hier anzeige:
   ''' <remarks>Die Parameter TEXT, SCHRIFT und BREITE entsprechen den 
   ' MEAURESTRING-Parametern text, font und width.
   '''  Auf die Verwendung der restlichen Parameter der Graphics-Funktion wurde 
   ' verzichtet, da diese in der Applikation
   '''  keine Verwendung finden.
   '''  Bei Übergabe eines Leerstring ist das Ergebnis SIZEF(0;0).
   '''  Der Schalter ISPRINTEROUT wird in der Ereignisroutine BEGINPRINT mit 
   ' der Anweisung
   '''  'IsPrinterOut = (e.PrintAction = Printing.PrintAction.PrintToPrinter)' 
   ' gesetzt.
   '''  Beim Start des Druckauftrags werden die Vergleichsfelder SizeDispl und 
   ' SizePrint sowie die Variable SizeFakt
   '''  auf SIZEF(0;0) zurückgesetzt. Dieser Nullwert ist das Kennzeichen, daß 
   ' der in der Variablen SizeFakt
   '''  abgelegte Wert nicht aktuell ist und der Korrekturfaktor für das 
   ' Ausgabemedium "Drucker" neu berechnet werden muß.
   '''  Jeweils der erste Aufruf der Funktion nach Start des Druckauftrages 
   ' führt zur Berechnung des Korrekturfaktors.
   '''  Der so berechnete und in SizeFakt gespeicherte Korrekturfaktor wird für 
   ' den gesamten Druckauftrag verwendet.</remarks>
Die beiden Funktionen unterscheiden sich nur in der Ausführung des Parameters BREITE, der dem MEASURESTRING-Parameter WIDTH entspricht. Somit ist in den ersten drei Parametern der Systemfunktion die angestrebte Identität gegeben.
Diese Funktion habe ich an allen Stellen, an denen ich die Systemfunktion "MeasureString" aufrufe, eingefügt. Der zusätzliche Aufwand mit den auf Class-Ebene zu vereinbarenden drei Variablen erscheint mir vertretbar. Außerdem habe ich versucht die zusätzlich zu durchlaufenden Anweisungen und damit den zusätzlichen Zeitaufwand so gering wie möglich zu halten. Auch die Frage einer eventuellen Wertabweichung bei Wechsel des Druckers spielt keine Rolle, da er mit jedem Druckauftrag neu berechnet wird.
Es ist vielleicht nicht der optimale Code, aber ich bin erstmal zufrieden, eine wirksame Lösung gefunden zu haben. Denn jetzt entspricht auch die 99. Seite der Druckausgabe der Anzeige in der Vorschau. Ich bin jedem dankbar, der eine optimalere Lösungsvariante findet und diese hier veröffentlicht.
Ich habe versucht, den Programmcode so ausführlich wie möglich zu kommentieren. Dadurch erscheint dieser in der vorliegenden Zeilenlänge etwas unübersichtlich. Wenn aber, nach dem Kopieren auf IDE-Ebene die überzähligen Fortsetzungszeilen entfernt werden, glaube ich, daß der Code übersichtlich genug ist.
Ich danke allen, die sich an der Diskussion des Problems teilgenommen haben und wünsche Euch einen guten Rutsch ins neue Jahr.
Gruß, Rainer.
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Rainer
Datum: 25.12.17 13:04

Hier die erste Variante:

   ''' <summary>
   ''' Misst die Zeichenfolge TEXT, wenn diese mit der angegebenen SCHRIFT 
   ' dargestellt wird. Bei Vorgabe einer
   '''  verfügbaren BREITE des Darstellungsbereiches ist das Funktionsergebnis 
   ' die erforderliche Bereichshöhe.
   '''  Mit Hilfe der Felder SizeDispl (Ausgabemdium "PrintPreviewControl") und 
   ' SizePrint (Ausgabemedium "Drucker"), die
   '''  als Class-Variable im Datentyp SIZEF definiert sind, wird eine 
   ' abweichende Berechnung der erforderlichen Breite
   '''  und Höhe ermittelt. Das Ausgabemedium "PrintPreviewControl" hat in 
   ' diesem Vergleich das Primat. Der für das
   '''  Ausgabemedium "Drucker" mit der Graphics-Funktion MEASURSTRING 
   ' ermittelte Wert wird mit dem in der Variablen
   '''  hinterlegten Korrekturfaktor angepaßt.
   '''  Die Funktion setzt voraus, daß jeder Ausgabe auf das Medium "Drucker" 
   ' eine Ausgabe auf das Medium
   '''  "PrintPreviewControl" oder "PrintPreviewDialog" vorausgeht.
   ''' </summary>
   ''' <param name="Grafik">Verbindungsglied zum Ereignisargument e.Graphics 
   ' in der Ereignisroutine PRINTDOCUMENT.PRINTPAGE</param>
   ''' <param name="Text">Der im Ausgabemedium darzustellende Text.</param>
   ''' <param name="Schrift">Die FONT-Einstellungen, die bei der 
   ' TEXT-Darstellung Verwendung finden.</param>
   ''' <param name="Breite">Vorgabe einer einzuhaltenden maximalen Breite 
   ' des Darstellungsbereiches in Grafikpunkte.
   '''  Ist die Vorgabe =-1, so wird die Breite den Anforderungen von TEXT und 
   ' FONT in einzeiliger Darstellung berechnet.</param>
   ''' <returns>Beschreibung des Raumes (Höhe und Breite), der zur 
   ' Darstellung von TEXT benötigt wird.</returns>
   Friend Shared Function _MeasureStringKorr(ByVal Grafik As _
     System.Drawing.Graphics, _
                                             ByVal Text As String, _
                                             ByVal Schrift As _
                                             System.Drawing.Font, _
                                             Optional ByVal Breite As Integer = _
                                             -1) As SizeF
      Dim _Font As System.Drawing.Font
      Dim _Ber As SizeF
 
      If (SizeFakt.Width = 0 And SizeFakt.Height = 0) Then              ' Wurde 
      ' der Korrekturfaktor bereits berechnet?
         If Not IsPrinterOut AndAlso _
            (SizeDispl.Width = 0 And SizeDispl.Height = 0) Then            ' ( 
            ' NEIN) Musterwerte für PrintPreviewControl ermittelt?
            _Font = New Font("Arial", 11, FontStyle.Regular)                  ' 
            ' (NEIN)
            SizeDispl = Grafik.MeasureString("GM gm", _Font)                  ' 
            ' Musterwerte für PrintPreviewControl ermitteln
         End If
         If IsPrinterOut AndAlso _
            (SizePrint.Width = 0 And SizePrint.Height = 0) Then            ' ( 
            ' JA) Musterwerte für Drucker ermittelt?
            _Font = New Font("Arial", 11, FontStyle.Regular)                  ' 
            ' (NEIN)
            SizePrint = Grafik.MeasureString("GM gm", _Font)                  ' 
            ' Musterwerte für Drucker ermitteln
         End If
         If (SizeDispl.Width <> 0 And SizeDispl.Height <> 0) AndAlso _
            (SizePrint.Width <> 0 And SizePrint.Height <> 0) Then         _
             ' Musterwerte für die Ausgabemedien ermittelt?
            SizeFakt.Width = ((SizeDispl.Width - SizePrint.Width) / _
            SizePrint.Width) + 1 ' (NEIN) Korrekturfaktoren berechnen
            SizeFakt.Height = ((SizeDispl.Height - SizePrint.Height) / _
            SizePrint.Height) + 1
         End If
      End If
      If IsPrinterOut Then                                              ' 
      ' Ausgabemedium Drucker?
         If (SizeFakt.Width <> 0 And SizeFakt.Height <> 0) Then           _
            ' (JA) Wurde der Korrekturfaktor bereits berechnet?
            If Breite > 0 Then                                               _
             ' (JA) vorgegebene Druckbreite?
               _Ber = Grafik.MeasureString(Text, Schrift, Breite / _
               SizeFakt.Width) ' (JA) 
            Else
               _Ber = Grafik.MeasureString(Text, Schrift)                       _
                  ' (NEIN)
            End If
            Return New SizeF(_Ber.Width * SizeFakt.Width, _Ber.Height * _
              SizeFakt.Height)
         End If
      End If
      If Breite > 0 Then                                                ' 
      ' vorgegebene Druckbreite?
         Return Grafik.MeasureString(Text, Schrift, Breite)                ' ( 
         ' JA)
      Else
         Return Grafik.MeasureString(Text, Schrift)                        ' ( 
         ' NEIN)
      End If
   End Function
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Re: Schrifthöhe mit Graphics-Funktion "MeasureString" für Display und Druck 
Autor: Rainer
Datum: 25.12.17 13:09

und Variante 2:

   ''' <summary>
   ''' Misst die Zeichenfolge TEXT, wenn diese mit der angegebenen SCHRIFT 
   ' dargestellt wird. Bei Vorgabe einer
   '''  verfügbaren BREITE des Darstellungsbereiches ist das Funktionsergebnis 
   ' die erforderliche Bereichshöhe.
   '''  Mit Hilfe der Felder SizeDispl (Ausgabemdium "PrintPreviewControl") und 
   ' SizePrint (Ausgabemedium "Drucker"), die
   '''  als Class-Variable im Datentyp SIZEF definiert sind, wird eine 
   ' abweichende Berechnung der erforderlichen Breite
   '''  und Höhe ermittelt. Das Ausgabemedium "PrintPreviewControl" hat in 
   ' diesem Vergleich das Primat. Der für das
   '''  Ausgabemedium "Drucker" mit der Graphics-Funktion MEASURSTRING 
   ' ermittelte Wert wird mit dem in der Variablen
   '''  hinterlegten Korrekturfaktor angepaßt.
   '''  Die Funktion setzt voraus, daß jeder Ausgabe auf das Medium "Drucker" 
   ' eine Ausgabe auf das Medium
   '''  "PrintPreviewControl" oder "PrintPreviewDialog" vorausgeht.
   ''' </summary>
   ''' <param name="Grafik">Verbindungsglied zum Ereignisargument e.Graphics 
   ' in der Ereignisroutine PRINTDOCUMENT.PRINTPAGE</param>
   ''' <param name="Text">Der im Ausgabemedium darzustellende Text.</param>
   ''' <param name="Schrift">Die FONT-Einstellungen, die bei der 
   ' TEXT-Darstellung Verwendung finden.</param>
   ''' <param name="Breite">Pflichtangabe eines einzuhaltenden Bereiches in 
   ' Grafikpunkte.</param>
   ''' <returns>Beschreibung des Raumes (Höhe und Breite), der zur 
   ' Darstellung von TEXT benötigt wird.</returns>
   Friend Shared Function _MeasureStringKorr(ByVal Grafik As _
     System.Drawing.Graphics, _
                                             ByVal Text As String, _
                                             ByVal Schrift As _
                                             System.Drawing.Font, _
                                             ByVal Breite As SizeF) As SizeF
      Dim _Font As System.Drawing.Font
      Dim _Ber As SizeF
 
      If (SizeFakt.Width = 0 And SizeFakt.Height = 0) Then              ' Wurde 
      ' der Korrekturfaktor bereits berechnet?
         If Not IsPrinterOut AndAlso _
            (SizeDispl.Width = 0 And SizeDispl.Height = 0) Then            ' ( 
            ' NEIN) Musterwerte für PrintPreviewControl ermittelt?
            _Font = New Font("Arial", 11, FontStyle.Regular)                  ' 
            ' (NEIN)
            SizeDispl = Grafik.MeasureString("GM gm", _Font)                  ' 
            ' Musterwerte für PrintPreviewControl ermitteln
         End If
         If IsPrinterOut AndAlso _
            (SizePrint.Width = 0 And SizePrint.Height = 0) Then            ' ( 
            ' JA) Musterwerte für Drucker ermittelt?
            _Font = New Font("Arial", 11, FontStyle.Regular)                  ' 
            ' (NEIN)
            SizePrint = Grafik.MeasureString("GM gm", _Font)                  ' 
            ' Musterwerte für Drucker ermitteln
         End If
         If (SizeDispl.Width <> 0 And SizeDispl.Height <> 0) AndAlso _
            (SizePrint.Width <> 0 And SizePrint.Height <> 0) Then         _
             ' Musterwerte für die Ausgabemedien ermittelt?
            SizeFakt.Width = ((SizeDispl.Width - SizePrint.Width) / _
            SizePrint.Width) + 1 ' (NEIN) Korrekturfaktoren berechnen
            SizeFakt.Height = ((SizeDispl.Height - SizePrint.Height) / _
            SizePrint.Height) + 1
         End If
      End If
      If IsPrinterOut Then                                              ' 
      ' Ausgabemedium Drucker?
         If (SizeFakt.Width <> 0 And SizeFakt.Height <> 0) Then           _
            ' (JA) Wurde der Korrekturfaktor bereits berechnet?
            If (Breite.Width > 0 Or Breite.Height > 0) Then               _
                ' (JA) vorgegebene Druckbreite?
               _Ber = Grafik.MeasureString(Text, _
                                           Schrift, _
                                           New SizeF(Breite.Width / _
                                           SizeFakt.Width, _
                                                     Breite.Height / _
                                                     SizeFakt.Height)) ' (JA) 
            Else
               _Ber = Grafik.MeasureString(Text, Schrift)                       _
                  ' (NEIN)
            End If
            Return New SizeF(_Ber.Width * SizeFakt.Width, _Ber.Height * _
              SizeFakt.Height)
         End If
      End If
      If (Breite.Width > 0 Or Breite.Height > 0) Then                   ' 
      ' vorgegebene Druckbreite?
         Return Grafik.MeasureString(Text, Schrift, Breite)                ' ( 
         ' JA)
      Else
         Return Grafik.MeasureString(Text, Schrift)                        ' ( 
         ' NEIN)
      End If
   End Function
Themenbaum einblendenGesamtübersicht  |  Zum Thema  |  Suchen

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel