![]() |
JVRichEdit parsen - Hilfe?!
Hi,
ich möchte in meinem Programm die JVRichEdit Komponente verwenden, da ich gerne Bitmaps in mein RichEdit einbauen möchte. Ich habe mit dem "Messenger-Beispiel" von den JV-Beispielen gearbeitet und die Bitmapanzeige geht auch schon soweit. Die Eingabe des Textes erfolgt auch über ein JVRichEdit. Dies sieht z.B. wiefolgt aus: Zitat:
Das Messenger Beispiel hat wohl schon vorgefertigte Smileys, aber irgendwie blicke ich nicht so wirklich durch den Code. Ich weiss nicht wie ich eigene Definitionen einbauen kann. Hier erstmal der komplette Code, unten drunter eine genauere Erklärung, was ich nicht verstehe:
Code:
Nehmen wir mal den Anfang des Parsers - hier fängt das erste Problem an:
procedure TfrmNachricht.ParseString(const S: string);
var P, Q: PChar; State: Integer; procedure AddImage(const SmileIndex, SmileLength: Integer); begin AddTextToRichEdit(Q, P - Q - SmileLength + 1, JVRichEdit2.Font); AddImageToRichEdit(SmileIndex); State := 0; Q := P + 1; end; begin P := PChar(S); Q := P; State := 0; // State = 1.. then looking at ":-A" with A = @x)( etc. // 10.. "LOL" // 20.. "O :-)" // 30.. "(blush)" // 40.. ":'-(" // 50.. "8-)" // 60.. ";-)" // 70.. "readonly" // 80.. "read-only on" or "read-only off" // // State = 1 -> ":" read // State = 2 -> ":-" read // State = 11 -> "LO" read // State = 22 -> "O :" read // State = 23 -> "O :-" read // // etc. while P^ <> #0 do begin case P^ of '$': if State in [2, 23] then AddImage(9, 3) // :-$ else State := 0; '&': if State in [2, 23] then AddImage(4, 3) // :-& else State := 0; '(': case State of 1, 22: AddImage(5, 2); // :( 2, 23: AddImage(5, 3); // :-( 40: AddImage(2, 3); // :,( 41: AddImage(2, 4); // :'-( else State := 30; end; ')': case State of 1, 22: AddImage(11, 2); // :) 2: AddImage(11, 3); // :-) 23: AddImage(6, 5); // O :-) 35: AddImage(3, 7); // (blush) 51: AddImage(1, 3); // 8-) 61: AddImage(15, 3); // ;-) else State := 0; end; '*': if State = 1 then AddImage(7, 2) // :* else State := 0; ',': if State in [1, 22] then State := 40 else State := 0; '-': case State of 1, 22, 40, 50, 60: Inc(State); 73: State := 80; else State := 0; end; '8': State := 50; '"': State := -1; // to prevent "read.." etc will be triggered by the program ':': if State = 21 then State := 22 else State := 1; ';': State := 60; '@': case State of 1, 22: AddImage(0, 2); // :@ 2, 23: AddImage(0, 3) // :-@ else State := 0; end; 'D': case State of 1, 22: AddImage(8, 2); // :D = LOL 2, 23: AddImage(8, 3) // :-D = LOL else State := 0; end; 'L': if State = 11 then AddImage(8, 3) // LOL else State := 10; 'O': if State = 10 then State := 11 else State := 20; '\', '/': if State in [2, 23] then AddImage(14, 3) // :-\ else State := 0; 'a': if State = 71 then State := 72 else State := 0; 'b': if State = 30 then State := 31 else State := 0; 'd': if State = 72 then State := 73 else State := 0; 'e': if State = 70 then State := 71 else State := 0; 'h': if State = 34 then State := 35 else State := 0; 'l': if State in [31, 75, 82] then Inc(State) else State := 0; 'o': case State of 2, 23: AddImage(12, 3); // :-o 73, 80, 85: Inc(State); else State := 0; end; 'p': if State in [2, 23] then AddImage(13, 3) // :-p else State := 0; 'r': if State <> -1 then State := 70 else State := 0; 's': if State = 33 then State := 34 else State := 0; 'u': if State = 32 then State := 33 else State := 0; 'x', 'X': if State in [2, 23] then AddImage(10, 3) // :-x else State := 0; ' ': case State of 20, 84: Inc(State); 11: State := 21; else State := 0; end; end; Inc(P); end; if Q < P then AddTextToRichEdit(Q, P - Q, JVRichEdit2.Font); end;
Code:
while P^ <> #0 - ist wohl die Abfrage, ob der String leer ist oder nicht, richtig?
while P^ <> #0 do
begin case P^ of '$': if State in [2, 23] then AddImage(9, 3) // :-$ else State := 0; case P^ of normale Case-Bedingung, prüft auf die kommenden Zeichen '$': Wenn das Zeichen $ im String vorkommt, dann... if State in [2, 23] then Hier nun ein Problem: Warum State in [2, 23]? Was hat die 2 und die 23 damit zu tun? Ich verstehe auch nicht die Kommentare in der Funktion oben. Gibt´s da keine extra Hilfe, in der die States erklärt werden? Außerdem wird doch der Integer-Wert State vor dem Aufruf des Zeigers 0 gesetzt... Wie ihr seht: Fragen über Fragen...vielleicht versteht ja einer von euch den Code und könnte ihn mir etwas erklären?! Wäre super nett! Danke! |
Re: JVRichEdit parsen - Hilfe?!
Hi Christian,
die Prozedur ParseString() implementiert einen Parser als Zustandsautomaten (Finite State Machine, FSM). Nach C-Manier wird der zu untersuchende String mit einem PChar-Zeiger (P) adressiert, der einfach per Zeigerarithmetik (Inc(P)) über den String geschoben werden kann. Da auf diese Weise immer nur ein Zeichen (P^) gesehen wird, die Grammatik aber die Zusammensetzung eines Smiley aus mehreren Zeichen erlaubt, muss sich der lexical analyser merken, welche Teil-Kombinationen er bisher erkannt hat (State). Auf diese Weise entfallen teure Stringvergleiche. Hoffentlich habe ich mich einigermaßen verständlich ausdrücken können. Grüße vom marabu |
Re: JVRichEdit parsen - Hilfe?!
Ja, bin inzwischen durchgestiegen...raffiniert diese Methode, aber richtig "sauber" ist sie doch nicht, oder?
|
Re: JVRichEdit parsen - Hilfe?!
An der Methode ist nichts auszusetzen. Schwachstellen in der Umsetzung vermute ich, bin aber zu faul sie aufzuspüren.
Grüße, marabu |
Re: JVRichEdit parsen - Hilfe?!
Das bezog sich nicht auf die oben stehende Variante.
Trotzdem danke! Problem solved! :-) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:24 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz