Gegenteil von GraQueryTextBox

Grafische Primitive, XbaseParts und Darstellungsfragen allgemein.

Moderator: Moderatoren

Antworten
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
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

Beitrag von Koverhage »

Ü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 ?
Gruß
Klaus
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Gegenteil von GraQueryTextBox

Beitrag von georg »

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.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Gegenteil von GraQueryTextBox

Beitrag von Tom »

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.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Gegenteil von GraQueryTextBox

Beitrag von brandelh »

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.
Gruß
Hubert
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
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

Beitrag von Herbert »

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.
Da die Differenz der 2 Formulare derart gross ist, weisst du bestimmt aufgrund anderer Parameter, welches Formular zum Zug kommt.
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...
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Gegenteil von GraQueryTextBox

Beitrag von Tom »

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.

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
Der Keyboard-Slot ruft GetTextWidth mit dem EditBuffer des Eingabefelds auf.
Zuletzt geändert von Tom am Mi, 18. Jun 2014 13:31, insgesamt 1-mal geändert.
Herzlich,
Tom
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16508
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Gegenteil von GraQueryTextBox

Beitrag von Martin Altmann »

Eine super Idee :!: :thumbright:

Viele Grüße,
Martin
:grommit:
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.
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
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

Beitrag von Koverhage »

Hallo Tom,

die Idee gefällt mir auch.
Man reagiert ständig auf den EditBuffer
Ich weiß noch nicht wie aber in dem Fall wäre wohl DCGET cKurz GETEVAL ???
der richtige Weg ?
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Gegenteil von GraQueryTextBox

Beitrag von Tom »

Wenn Du mit DCGET arbeitest:

Code: Alles auswählen

@ 1,1 DCGET cKurzBezeichnung EVAL {|o|o:Keyboard := {|a,b,o|CheckText(a,b,o,oIcon)}}
Und mit DCSAY ... GET:

Code: Alles auswählen

@ 1,1 DCSAY "Kurzbezeichnung:" GET cKurzBezeichnung GETEVAL {|o|o:Keyboard := {|a,b,o|CheckText(a,b,o,oIcon)}}
"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.
Herzlich,
Tom
Antworten