Announcement

Collapse
No announcement yet.

Wer ist die Schnecke: Source oder RichEdit

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Wer ist die Schnecke: Source oder RichEdit

    Hi,

    ich raufe mir die wenigen verblieben Haare: es soll ein parser geschrieben werden, der wie z.B. der Delphi-Editor bestimmte Worte oder Zeichen fett oder farbig darstellt. der folgende source ist ein ergebnis, welches bei kleinen texten auch prima funktioniert

    <PRE>
    TWordPos = record
    aWord : string;
    StartPos : LongInt;
    EndPos : LongInt;
    WordLen : integer;
    end;

    const
    cLIMITS = ';:=.()<>[],-' + #39 + '+*!?"§$%&/\?{}';

    // die reswords habe ich zum test der delphi-hilfe entnommen und lese als .txt ein

    procedure SetLangAttr2Text(aRichEdit: TRichEdit; StartPos,TextLen: integer; ResWords: TStringList; Limeters: string);
    var pointer;
    WordPos : TWordPos;
    i,j,FoundInt,EndPos : LongInt;
    s: string;
    begin
    WordPos.StartPos := 0; WordPos.EndPos := 0; WordPos.WordLen := -1; s := '';

    p := pChar(aRichedit.Text); j:= StartPos; aRichEdit.SelStart := StartPos;
    inc(pChar(p),StartPos);
    if TextLen < 0 then EndPos := Length(aRichEdit.Text) else EndPos := j + TextLen;

    while pChar(p)^ <> #0 do
    begin

    //Wir durchlaufen den Text vorwärts, also ist Start immer bekannt
    //nämlich zum ersten Zeitpunkt, wenn kein Limeter auftritt

    if IsLimeter(char(p^),cLIMITS) then
    begin
    WordPos.aWord := s; // das Wort ist fertig
    // Limeter einfärben ?
    if Form1.Checkbox1.checked = true then
    begin
    if ord(char(p^))> 32 then
    begin
    aRichEdit.SelStart:= j;
    aRichEdit.SelLength := 1;
    aRichEdit.SelAttributes.Color := clRed;
    aRichEdit.SelAttributes.Style := [];
    end;
    end;

    if length(s) > 0 then
    begin
    WordPos.EndPos := j;
    WordPos.WordLen := length(s);
    end;
    s:= '';
    end
    else
    begin
    if s = '' then
    begin
    WordPos.StartPos := j;
    WordPos.EndPos := 0;
    WordPos.WordLen := -1;
    end;
    s:= s + pChar(p)^;
    end;

    i := 1;
    if WordPos.WordLen > 0 then
    begin
    FoundInt := 0;
    try
    if trim(WordPos.aWord) <> '' then ResWords.find(trim(WordPos.aWord),FoundInt);
    except
    ShowMessage(WordPos.aWord);
    end;
    if (FoundInt > -1) and (FoundInt <= ResWords.Count-1) then
    begin
    if lowercase(ResWords[FoundInt]) = lowercase(WordPos.aWord) then
    begin
    aRichEdit.SelStart:= WordPos.StartPos;
    aRichEdit.SelLength := WordPos.WordLen;
    aRichEdit.SelAttributes.Color := clBlack;
    aRichEdit.SelAttributes.Style := [fsBold];
    i := WordPos.WordLen;
    end;
    end;
    end;
    inc(pChar(p),i); inc(j,i);
    if j > EndPos then break;
    end;
    end;
    </PRE>

    werden alle teile ausgeklammert, die das richedit manipulieren (aRichEdit. ..), dann rennt der Code auch bei der ComCtrls mit > 700 kb, ansonsten kann man Kaffee trinken gehen.

    gibt es einen weg, das richedit direkter zu manipulieren, mache ich was falsch oder wo ist der haken? delphi kann's doch auch

    für "den" tipp wäre ich wirklich dankbar

    gruss, bernhard

    ps: die function IsLimeter testet den Const cLIMITS durch und hält nachweislich den code nicht auf

  • #2
    Hallo,<BR>
    Vielleicht hilft das:<BR>
    http://www.delphisource.com/download.asp?type=comp&all=true&id=565<BR>
    Sigber

    Comment


    • #3
      @Sigbert

      auch weniger wäre nett! und es geht nicht um sourcen, sondern um begriffe aus den "Namensräumen" diagnosen, labor etc. ich hatte mir vorher schon das sdk angesehen und geahnt, dass hier wieder mal steine rumliegen.

      und das zugrundeliegende wörterbuch soll außerdem noch mit jedem txt-editor zu warten sein - somit fällt zumindest auf den ersten blick der mozilla-ansatz mit den festverdrahtungen aus.

      trotzdem erstmal danke,gruß bernhar

      Comment


      • #4
        Hast du dir schon mal die RTF Syntax angeschaut ?<br>
        Um eine simple Textdatei in RTF zu konvertieren und dabei gleichzeitig die Schrift auf Fett zu setzen benötigst du wirklich nicht viel. Du speicherts den Text in ein TMemoryStream, fügst den Standard RTF Header hinzu scannt auf deine Wörter und fügst die Formatierung für Bold ein. Danach lädst du deine RTF in's RichEdit.

        Gruß Hage

        Comment


        • #5
          Probier mal SynEdit: klatsche einfach ein SynEdit und ein SynAnySyn auf die Form, verdrahte beide miteinander (SynEdit1.Highlighter) und lade das Wöterbuch in SynAnySyn1.KeyWords - voila.
          <br>Ciao, Uli

          Comment


          • #6
            Ich vermute das Bernhard mit TrueTypes, Non-Fixed Fonts und Zeilenumbrüchen arbeiten will. Dann wäre SynEdit nicht die richtige Wahl.

            Gruß Hage

            Comment


            • #7
              Stimmt, die paar Einschränkungen hab ich ganz vergessen. :-/
              <br>Uli

              Comment


              • #8
                @Ulrich: Danke für den Tip, aber ich war aufgrund anderer Beiträge über SynEdit bereits gefallen und hatte es aus den von Hagen genannten Gründen verworfen.

                @Hagen: Ja, kann man wohl so machen. Dann gehen auch die Pointer "wech", die unter D7 bereits als unsicherer Code unter .net (grmh!) angemängelt werden.

                by the way: arichedit.lines.beginupdate /endupdate am Anfang und Ende dazu beschleunigt den Code noch mal rasant um den faktor 2-3, womit man bis zu etwa 2000 Textzeilen schon ganz gut leben kann.

                ich werde das mal am wochenende auf den memorystream umsetzen und dann sehen wir mal.

                gruß, und danke an euch beide

                Bernhar

                Comment


                • #9
                  .BeginUpdate/.EndUpdate verhindert nur das man auf den DeviceContext zum RichtEdit zeichnen kann. Das heisst aber noch lange nicht das auch nicht versucht wird zu zeichnen. Es verhindert als ein Flickern beschleunigt aber nicht auf das mögliche Maximum. Wie gesagt, ich bin bei meiner RTF Formatierung mit Hilfe eines TMemoryStreams und TMemoryStream.Memory = PChar vorgegangen. Dabei wird von hinten nach vorne gescannt und ein Buffer von ca. 1024 Bytes benutzt. D.h. von hinten nach vorne wird gescannt und 1024 Bytes hinter das Ende des Stream gespeichert. Wird eine Formatierung eingefügt so reduzieren sich diese 1024 Bytes jeweils um die Länge der hinzugefügten Zeichen. Sollte der Buffer zu klein werden wird er durch Verschiebung des gesammten nachfolgenden Speichers expandiert. Allerdings kann man auch einfach den Text von einem Stream ind einen anderen Stream mit hinzugefügten Formatierungen kopieren. Für kleine Texte < 1Mb ist das ziemlich effizient.

                  Gruß Hage

                  Comment

                  Working...
                  X