Gegenteil von GraQueryTextBox
Moderator: Moderatoren
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2470
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Gegenteil von GraQueryTextBox
Über GraQueryTextBox() kann ja die Textlänge (in was ?) festgestellt werden.
Ich möchte jetzt den anderen Weg gehen und die maximal verfügbare Textlänge
für einen Druckbereich vorher ermitteln.
Hintergrund: Es gibt 2 verschiedene Rechnungsformulare. Bei einem Formular kann die Artikelbezeichnung ca. 40 Stellen lang sein,
bei dem anderen können dies bis zu 70 Stellen.
Welches Formular zum Einsatz kommt und den Font wählt der Anwender aus und ist demzufolge bekannt.
Ich möchte jetzt bei der Erfassung der Rechnung schon die Anzahl der maximalen Stellen in der Artikelbezeichnung
vorgeben.
Kann mir jemand einen Tipp geben, wie ich das angehen könnte ?
Ich möchte jetzt den anderen Weg gehen und die maximal verfügbare Textlänge
für einen Druckbereich vorher ermitteln.
Hintergrund: Es gibt 2 verschiedene Rechnungsformulare. Bei einem Formular kann die Artikelbezeichnung ca. 40 Stellen lang sein,
bei dem anderen können dies bis zu 70 Stellen.
Welches Formular zum Einsatz kommt und den Font wählt der Anwender aus und ist demzufolge bekannt.
Ich möchte jetzt bei der Erfassung der Rechnung schon die Anzahl der maximalen Stellen in der Artikelbezeichnung
vorgeben.
Kann mir jemand einen Tipp geben, wie ich das angehen könnte ?
Gruß
Klaus
Klaus
-
- Der Entwickler von "Deep Thought"
- Beiträge: 2829
- Registriert: Fr, 08. Feb 2008 21:29
- Hat sich bedankt: 97 Mal
- Danksagung erhalten: 13 Mal
Re: Gegenteil von GraQueryTextBox
Hallo, Klaus -
wenn Du einen fixed Font verwendest, also keinen proportionalen Font, dann kannst Du mit GraQueryTextBox() ermitteln, wie "breit" ein Zeichen ist, und dann die Länge des Feldes / Breite = Anzahl druckbarer Zeichen.
Wenn aber ein proportionaler Font zum Einsatz kommt, musst Du eine Schleife aufbauen:
GraQueryTextBox(cArtikelname)
Wenn die Breite die des Ausgabebereichs unterschreitet, reduzierst Du die Länge von cArtikelname um jeweils ein Zeichen im Loop, bis entweder die Breite 0 ist (Leerstring), oder die Breite, welche GraQueryTextBox() zurückmeldet, kleiner ist als der Ausgabebereich.
wenn Du einen fixed Font verwendest, also keinen proportionalen Font, dann kannst Du mit GraQueryTextBox() ermitteln, wie "breit" ein Zeichen ist, und dann die Länge des Feldes / Breite = Anzahl druckbarer Zeichen.
Wenn aber ein proportionaler Font zum Einsatz kommt, musst Du eine Schleife aufbauen:
GraQueryTextBox(cArtikelname)
Wenn die Breite die des Ausgabebereichs unterschreitet, reduzierst Du die Länge von cArtikelname um jeweils ein Zeichen im Loop, bis entweder die Breite 0 ist (Leerstring), oder die Breite, welche GraQueryTextBox() zurückmeldet, kleiner ist als der Ausgabebereich.
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9374
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Hallo, Klaus.
Das Problem ist, dass die Textlänge abhängig vom Inhalt unterschiedlich ausfallen kann. Eine Artikelbezeichnung "WWWW" benötigt mehr Platz als "iiii", obwohl beides vier Zeichen sind. Du müsstest also entweder das Eingabefeld dynamisch anpassen (SetSize), was es bei jedem getippten Buchstaben flackern lassen würde, oder eine Marke anzeigen, die die Stelle markiert, ab der abgeschnitten würde. Du könntest natürlich auch in einem größenfixierten Feld einfach jede Eingabe verweigern, die über die passende Länge hinausgeht, aber dann müsstest Du nicht nur auf Tastatureingaben reagieren, sondern zusätzlich auf Mausaktionen (Cut&Paste usw.). Ganz schön kompliziert. Viel einfacher wäre es, unterhalb des Eingabefeldes eine GraBox zu zeichnen, die den Font reflektiert, auf jedes Event reagiert und in der Box den Text so wiedergibt, wie er auf der Rechnung erscheinen würde. Das ist vermutlich auch leichter verständlich als ein magisches Eingabefeld, das bei jedem Tippen fluktuiert.
Das Problem ist, dass die Textlänge abhängig vom Inhalt unterschiedlich ausfallen kann. Eine Artikelbezeichnung "WWWW" benötigt mehr Platz als "iiii", obwohl beides vier Zeichen sind. Du müsstest also entweder das Eingabefeld dynamisch anpassen (SetSize), was es bei jedem getippten Buchstaben flackern lassen würde, oder eine Marke anzeigen, die die Stelle markiert, ab der abgeschnitten würde. Du könntest natürlich auch in einem größenfixierten Feld einfach jede Eingabe verweigern, die über die passende Länge hinausgeht, aber dann müsstest Du nicht nur auf Tastatureingaben reagieren, sondern zusätzlich auf Mausaktionen (Cut&Paste usw.). Ganz schön kompliziert. Viel einfacher wäre es, unterhalb des Eingabefeldes eine GraBox zu zeichnen, die den Font reflektiert, auf jedes Event reagiert und in der Box den Text so wiedergibt, wie er auf der Rechnung erscheinen würde. Das ist vermutlich auch leichter verständlich als ein magisches Eingabefeld, das bei jedem Tippen fluktuiert.
Herzlich,
Tom
Tom
- brandelh
- Foren-Moderator
- Beiträge: 15697
- Registriert: Mo, 23. Jan 2006 20:54
- Wohnort: Germersheim
- Hat sich bedankt: 66 Mal
- Danksagung erhalten: 33 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Die Rückgabe entspricht der eingestellten Einheit, wobei nicht nur EINE Breite ermittelt wird, sondern eine Array einer BOX um den Text mit PEN Position (Schreiblinie).
Eine genaue Vorausberechnung geht nur mit den von Georg verwendeten fixen Fonts.
Die sehen aber nicht schön aus, daher kann man ein "n" als "Normalbreiter" Buchstabe nutzen, um den ungefähren Platz zu ermitteln
und kürzere Texte einfach drucken ... es kann natürlich zu Überschreitungen kommen ...
In meiner DruckerKlasse kann man mit PrintMemo() Blocksatz drucken, dort ermittle ich die Breite eines Textes einmal MIT und OHNE Blanks
und die Anzahl der nötigen Blanks. Ist der Text zu breit, wird bis zum letzten Blank gekürzt, bis die Zeile mit Blanks passt und dann Wort für Wort OHNE
Blanks jeweils mit nPlatzFuerBlanks/nAnzahlBlanks Versatz gedruckt.
Eine genaue Vorausberechnung geht nur mit den von Georg verwendeten fixen Fonts.
Die sehen aber nicht schön aus, daher kann man ein "n" als "Normalbreiter" Buchstabe nutzen, um den ungefähren Platz zu ermitteln
und kürzere Texte einfach drucken ... es kann natürlich zu Überschreitungen kommen ...
In meiner DruckerKlasse kann man mit PrintMemo() Blocksatz drucken, dort ermittle ich die Breite eines Textes einmal MIT und OHNE Blanks
und die Anzahl der nötigen Blanks. Ist der Text zu breit, wird bis zum letzten Blank gekürzt, bis die Zeile mit Blanks passt und dann Wort für Wort OHNE
Blanks jeweils mit nPlatzFuerBlanks/nAnzahlBlanks Versatz gedruckt.
Gruß
Hubert
Hubert
- Herbert
- Der Entwickler von "Deep Thought"
- Beiträge: 1991
- Registriert: Do, 14. Aug 2008 0:22
- Wohnort: Gmunden am Traunsee, Österreich
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Da die Differenz der 2 Formulare derart gross ist, weisst du bestimmt aufgrund anderer Parameter, welches Formular zum Zug kommt.Koverhage hat geschrieben:Hintergrund: Es gibt 2 verschiedene Rechnungsformulare. Bei einem Formular kann die Artikelbezeichnung ca. 40 Stellen lang sein, bei dem anderen können dies bis zu 70 Stellen.
Will jemand mehr als 40 stellen eingeben, darf aber dies nicht, kannst du tatsächlich nach der Anzahl Zeichen prüfen, ohne auf den Font zu achten. Oder rechnest nach dem 40. Zeichen mit graquerytextbox die Grösse des Strings.
Grüsse Herbert
Immer in Bewegung...
Immer in Bewegung...
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9374
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Der Font ist bekannt, und es ist auch bekannt, welches Formular verwendet wird. Die einzige Variable ist die Art des Textes, der als Kurzbezeichnung erfasst wird. Je nach verwendeten Buchstaben können es mal 20, mal 50, mal x-und-neunzig Zeichen sein, die in das Formularfeld passen würden. Und dafür gibt es m.E. den folgenden vernünftigen Weg: Man reagiert ständig auf den EditBuffer (z.B. im Keyboard-Slot) und errechnet über eine eigene Funktion, welche Höhe und Breite dafür nötig sind. Diese Funktion generiert ein unsichtbares Static ohne Größe, setzt für dieses den gewählten Font und ruft dann mit GraQueryTextBox ab, wie groß es werden müsste: aSize := GraQueryTextBox(oStatic:lockPs(),cKurzbezeichnung) (cKurzbezeichnung ist der getrimmte EditBuffer). aSize[3,1]-aSize[1,1] ergibt die Breite des Statics. Anschließend erfolgen oStatic:unlockPS() und oStatic:Destroy(), danach kann die Funktion die Breite zurückreichen. Ist diese größer als das Formularfeld, zeigt man neben dem Eingabefeld ein Warnicon an, ist sie kleiner, zeigt man ein "OK"-Icon. Wenn dann trotz des Warnicons erfasst wird, kann man eben auch nichts mehr machen. Oder man veranlasst ein Undo auf die letzte Eingabe bzw. ignoriert das zuletzt eingegebene Zeichen im Handler.
Der Keyboard-Slot ruft GetTextWidth mit dem EditBuffer des Eingabefelds auf.
Code: Alles auswählen
FUNCTION GetTextWidth(cText,cFontName)
LOCAL oStatic, aSize, nWidth
oStatic := XbpStatic():New(AppDeskTop())
oStatic:Create()
oStatic:SetFontCompoundName(cFontName)
aSize := GraQueryTextBox(oStatic:lockPS(),cText)
nWidth := aSize[3,1]-aSize[1,1]
oStatic:unLockPS()
oStatic:Destroy()
RETURN nWidth
Zuletzt geändert von Tom am Mi, 18. Jun 2014 13:31, insgesamt 1-mal geändert.
Herzlich,
Tom
Tom
- Martin Altmann
- Foren-Administrator
- Beiträge: 16517
- Registriert: Fr, 23. Sep 2005 4:58
- Wohnort: Berlin
- Hat sich bedankt: 111 Mal
- Danksagung erhalten: 48 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Eine super Idee
Viele Grüße,
Martin
Viele Grüße,
Martin
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/
Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
- Koverhage
- Der Entwickler von "Deep Thought"
- Beiträge: 2470
- Registriert: Fr, 23. Dez 2005 8:00
- Wohnort: Aalen
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 3 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Hallo Tom,
die Idee gefällt mir auch.
der richtige Weg ?
die Idee gefällt mir auch.
Ich weiß noch nicht wie aber in dem Fall wäre wohl DCGET cKurz GETEVAL ???Man reagiert ständig auf den EditBuffer
der richtige Weg ?
Gruß
Klaus
Klaus
- Tom
- Der Entwickler von "Deep Thought"
- Beiträge: 9374
- Registriert: Do, 22. Sep 2005 23:11
- Wohnort: Berlin
- Hat sich bedankt: 102 Mal
- Danksagung erhalten: 361 Mal
- Kontaktdaten:
Re: Gegenteil von GraQueryTextBox
Wenn Du mit DCGET arbeitest:
Und mit DCSAY ... GET:
"o" ist das Get-Objekt, Trim(o:EditBuffer()) liefert also den aktuellen Inhalt. "oIcon" wäre beispielsweise ein direkt neben dem Eingabefeld positioniertes Icon, dessen Caption man je nach Rückgabewert der Textlängenkalkulation austauscht.
Code: Alles auswählen
@ 1,1 DCGET cKurzBezeichnung EVAL {|o|o:Keyboard := {|a,b,o|CheckText(a,b,o,oIcon)}}
Code: Alles auswählen
@ 1,1 DCSAY "Kurzbezeichnung:" GET cKurzBezeichnung GETEVAL {|o|o:Keyboard := {|a,b,o|CheckText(a,b,o,oIcon)}}
Herzlich,
Tom
Tom