Font-Einstellung wirkt nicht /Wie prüft man besser ob in einem Stück markierten Text ein Feld enthalten ist, ohne den Cursor zu verschieben?

  • Hallo,

    ich erzeuge WPRichtText's per Code und setze dort nach der Erzeugung

    Code
    WPRichtext := TWPRichText.create(FormMain);
    WPRichtext.CurrAttr.FontName := 'Courier New';
    WPRichtext..CurrAttr.Size := 16;
    WPRichtext.WPToolBar := WPToolBar1;

    Wenn ich nun ins RTF klicke steht in der Toolbar wie erwartet Courier New mit 16er Größe.

    Nur wenn ich tippe kommt Schrift in Arial, wenn ich davon Textteile markiere und in der Toolbar die Größe ändere, ändert sich zwar die Schriftgröße aber bleibt bei Arial.

    Was habe ich bei der Erzeugung an Einstellungen übersehen?

    Ciao

    Stefan

    Einmal editiert, zuletzt von wpsupport (3. Juni 2019 um 07:52) aus folgendem Grund: Titel angepasst

    • Offizieller Beitrag

    CurrAttr ändert den aktuellen Schreibmodus. Der kann sich aber jederzeit wieder ändern, je nach geladenem text.

    Wenn man text markiert zeigt die toolbar den font(attribute di im markierten text gleich gesetzt sind.

    Evtl. wollen Sie ja den Default font setzen?

    // Default - for text which does not use any attributes

    WPRichText1.DefaultAttr.SetFontName('Courier New');

    WPRichText1.DefaultAttr.SetFontSize(16);

    // Writing mode - the current mode

    WPRichText1.WritingAttr.SetFontName('Courier New');

    WPRichText1.WritingAttr.SetFontSize(16);

  • Danke, der Default-Font passt jetzt.

    Ich tippe "12345" was in Courier New 16 erscheint.

    Jetzt ändere ich die Schriftgröße auf 28 und klicke ich zwischen 3 und 4.

    wenn ich nun "abcde" tippe, hätte ich erwartet, dass dies nun in 28 erscheint, es bleibt aber bei 16?

    Ciao

    Stefan

    Einmal editiert, zuletzt von skoschke (29. Mai 2019 um 15:25)

  • Ich meine alles per "Bedienung", wenn ich zwischen 3 und 4 klicke zeigt die Toolbar 16 an.

    Jetzt ändere ich in der Toolbar auf 28 springt der Cursor ans Textende, klicke ich dann wieder zwischen 3 und 4 ist wieder 16 eingestellt.

    Bei Word verhält sich das so wie ich erwartet hatte...

    Ciao

    Stefan

  • Ja, da war ein Event am Werk...

    Der ist jetzt deaktiviert, der Cursor bleibt wo er ist.

    Ich klicke nun in einen 12pt Text, stelle in der Toolbar auf 20pt und tippe weiter, aber es entsteht weiter 12er Text.

    Ist das so gewollt?

    Ciao

    Stefan

    • Offizieller Beitrag

    Das ist so nicht gewollt und passiert in meinen Tests auch nicht.

    Evtl. wird ein SetFocusValues ausgeführt in einem anderen event oder der Cursor platziert.

    Beim Verstellen in der Toolbar darf dieser code in WPRTEDefs nicht ausgeführt werden:

    procedure TWPRTFDataCursor.GetCharAttr(Lock : TThreeState = tsIgnore);

    Ich würde zum Finden des Problems dort einen breakpoint platzieren (erfordert compiler symbol WPDEBUG) und dann in der Toolbar etwas verstellen.

    Wenn dann der Break kommt, weiss man durch den Aufrufstack, wieso das passiert.

  • Hallo,

    der Event, welcher das Problem verursacht, ist gefunden!

    Im OnKeypress rufe ich eine Funktion

    auf, die falls true key := #0 setzt.

    Damit möchte ich verhindern, dass bei Textmarkierung die ein Feld enthält, dieses durch Tippen gelöscht wird.

    Da in der oben gezeigten Funktion aber die Cursorposition verändert wird, geht die Toolbar-Einstellung verloren.

    Wie prüft man besser ob in einem Stück markierten Text ein Feld enthalten ist, ohne den Cursor zu verschieben?

    Ciao

    Stefan

    • Offizieller Beitrag

    Den cursor in KeyPress o.ä. zu verändern ist immer problematisch. Wenn man es aber doch tun muss, dann nicht SelStart oder CPPosition verwenden, da diese properties an das user interface gebunden sind. Man kann direkt TextCursor.postion verändern, das ist eine low level funktion.

    Man kann aber auch auf ActiveParagraph zugreifen um dort den Text zu prüfen. All die LowLevel routinen sind immer ok.

    Grundsätzlich kann man Felder ja schützen:

    ProtectedProp := [ppIsInsertpoint,ppProtectSelectedTextToo]

    oder

    [ppIsInsertpoint,ppIsMergedText,ppProtectSelectedTextToo]

    was dann auch den Feldinhalt, nicht nur die Marken schützt.

    Wenn Sie aber die Objekte in einer Selektion prüfen wollen geht das so:

    WPRichText1.TextCursor.CallForSelectedText(nil, [], nil, nil, TextObjCallback);

    mit den folgenden event handler

    procedure TForm1.TextObjectCallback(Sender: TObject; txtobj: TWPTextObj;

    Par: TParagraph; posinpar: Integer; var Abort: Boolean);

    begin

    ...

    end;

    • Offizieller Beitrag

    Übrigens - FieldAtCP ist eine sehr komplexe funktion, die auch prüft ob sich der Cursor innerhalb eines Feldes befindet. Da dafür auch in vorangegangen Absätzen gesucht wird, kann dies sehr lange dauern, vor allem wenn kein Feld gefunden wird.

    In einer Schleife könnte man ObjAtCP verwenden, das schaut wirklich nur an einer Position nach.

    Statt SelStart und SelLength ist es effektiver gleich GetSelPosLen zu verwenden, oder noch besser, gleich mit absatz zeigern arbeiten:

    TextCursor.GetBlockStart, TextCursor.GetBlockEnd.

    Beispiel:

  • Danke für die Tips.

    ProtectedProp hatte ich schon, was aber das Löschen oder Überschreiben von Feldern nicht verhindert hat.

    Jetzt weiß ich auch den Grund, ppProtectSelectedTextToo hatte ich nicht gesetzt, nur ppIsInsertpoint und ppIsMergedText.

    Jetzt verhält sich alles wie gewünscht :-)

    Den obigen Codeschnipsel habe ich in meine Sammlung übernommen, vielen Dank dafür.

    Ciao

    Stefan