Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Tabulatorpositionen im RichEdit (https://www.delphipraxis.net/112912-tabulatorpositionen-im-richedit.html)

taaktaak 29. Apr 2008 15:00


Tabulatorpositionen im RichEdit
 
Moin, Moin,
um meinen kleinen Editor auf Basis des RichEdits etwas komfortabler zu gestalten, versuche ich eine Tabulator-Funktionalität bereitzustellen.

Zuerst habe ich versucht, mit SendMessage() und EM_SETTABSTOPS die Tabulatorpositionen zu setzen. Ohne jeden Erfolg. MSDN sagt, dass auf diesem Wege die Tabulatorpositionen in einem "MultiLineControl" gesetzt werden. Da das aber offenbar nicht funktioniert, gehe ich im Augenblick davon aus, dass TRichEdit (im Gegensatz zu TMemo) kein MultiLineControl ist, auf dass diese Aussage zutrifft. Ist das korrekt, oder habe ich etwas falsch gemacht?

Ein (erster) Blick in die Delphi-Hilfe brachte dann die Erkenntnis, dass Tabulatoren mit RichEdit.Paragraph.Tab[Idx]:=~~ gesetzt werden können. Ok, intern wird dann SendMessage() mit EM_SETPARAFORMAT verwendet, um die Tabulatorpositionen zu setzen.

Nun beobachte ich aber ein mir seltsam erscheinendes Verhalten, und das ist der eigentliche Grund meiner Nachfrage an dieser Stelle:

Ich erwarte, nun für jeden Absatz (Paragraph) individuelle Tabulatorpositionen setzen zu können, bevor im Absatz Text manuell erfasst wird und diese Tabulatorpositionen danach durch Einfügen von Tabs (TabTaste) während der Eingabe anspringen zu können. Also ganz so, wie man es z.B. in Word machen kann. Bei dieser Vorgehensweise haben die gesetzten Tabulatorpositionen aber keinerlei Auswirkung; es werden immer nur die Default-Positionen angesprungen?!
Nur in der entgegengesetzten Reihenfolge funktioniert es: Zuerst im Absatz den Text inklusive Tabs erfassen, dann die Tabulatorpositionen neu setzen - nun wird der Text wie erwartet ausgerichtet. Aber diese Reihenfolge ist leider total unkomfortabel!

Fragen:

Mache ich da etwas falsch, oder ist dieses absonderliche Verhalten eine Eigenart des RichEdits?

Ist das Verhalten im RTF-Format begründet, dass die Festlegung von Tabulatorpositionen nur bestehenden Text (d.h. bereits vorhandene TabStops) ausrichten kann?

Wie/Wo werden die Default-Tabstops definiert?

Jelen 29. Apr 2008 16:21

Re: Tabulatorpositionen im RichEdit
 
Hallo taaktaak,
hast Du mal versucht, die Eigenschaft TabCount ins Spiel zu bringen?
Wenn ich folgendes schreibe:
Delphi-Quellcode:
RichEdit1.Paragraph.TabCount := 4;
RichEdit1.Paragraph.Tab[0] := 90;
RichEdit1.Paragraph.Tab[1] := 120;
RichEdit1.Paragraph.Tab[2] := 240;
RichEdit1.Paragraph.Tab[3] := 480;
funktionierts bei mir, auch wenn der aktuelle Absatz noch leer ist und ich den Text samt Tabstopps erst danach eingebe.

So ganz durchdrungen hab' ich das RichEdit aber auch nicht, ich habe mich nur vor einiger Zeit auch mal abgemüht, ihm Tabulatorpositionen aufzuzwingen...

toms 29. Apr 2008 18:59

Re: Tabulatorpositionen im RichEdit
 
Hallo,

Vielleicht macht der Code von den Newsgroups das was du möchtest.

Zitat:

Zitat von P. Below
Tab positions are a paragraph property in this control, so you use the Paragraph.Tab property to set tabstop positions. At least that is the theory.
Unfortunately the Tab property has been plagued by a longstanding bug, so you are better off setting tabstops by using the EM_SETPARAFORMAT message. Here is an example, add the
Richedit unit to your uses clause for the message and TParaformat type.



Delphi-Quellcode:
{-- SetTabstops -------------------------------------------------------} 
{: Set tabstops at the indicated positions in the current paragraph
@Param re is the richedit control to modify
@Param TabPositions is an array of positions to set. The unit used
  are inches and the array needs to be sorted.
@Precondition re <> nil
@Desc Note: if the TabPositions array contains more than MAX_TAB_STOPS
  entries the extras will not be used.


}{ Created 2004-04-15 by P. Below


-----------------------------------------------------------------------} 
procedure SetTabstops( re: TRichedit; TabPositions: array of single );
Var
  pf: TParaFormat;
  i : Integer;
  charwidth : Integer;
begin
  Assert( Assigned( re ), 'SetTabstops: re cannot be nil' );
  FillChar( pf, sizeof(pf), 0);
  pf.cbSize := Sizeof( pf );
  pf.dwmask := PFM_TABSTOPS;
  if High(TabPositions) >= MAX_TAB_STOPS then
    pf.cTabCount := MAX_TAB_STOPS
  else
    pf.cTabCount := High(TabPositions)+1;
  For i:= 0 To pf.cTabCount-1 Do
    pf.rgxTabs[i] := Trunc(TabPositions[i] * 1440);

  re.perform( EM_SETPARAFORMAT, 0, Integer( @pf ));
end; { SetTabstops } 


procedure TForm1.Button1Click(Sender: TObject);
begin
  with RichEdit1 do
  begin
    Clear;
    SelStart := GetTextLen; // position caret at end
    SelAttributes.Style := [];
    SelAttributes.Color := clBlack;
    SetTabstops( richedit1, [0.5, 1.0, 1.5, 2.5] );
    SelText := 'STRING1'+#9+'STRING2'+#9+'STRING3'+#13#10+ 
      'A'#9'B'#9'C'#9'D'#9'E';
  end;
end;

taaktaak 29. Apr 2008 21:33

Re: Tabulatorpositionen im RichEdit
 
Moin, Moin!

Ja, da möchte ich mich zunächst einmal herzlich bedanken!
Beide Methoden funktionieren wie erläutert.

Mein Versuche waren erfolglos geblieben, da ich das TabCount nicht verwendet habe. Allerdings hat mir die Delphi-Hilfe mit folgender Aussage...

Zitat:

Wenn Index Werte kleiner als TabCount erhält, wird die Position vorhandener Tabstopps verändert. Alle Wert von Index, die größer oder gleich TabCount sind, vergrößern die Anzahl der Tabstopps im Absatz und ändern entsprechend den Wert von TabCount.
suggeriert, das dies nicht nötig sei!

Wenn ich mir nun allerdings in der Unit ComCtrls die Prozedur TParaAttributes.SetTab() anschaue, dann kann ich keinen relevanten Unterschied zur Prozedur SetTabStops von P.Below erkennen - und die funktioniert, ohne TabCount zu setzen. Hmmm, aber ist vielleicht akademisch und im Augenblick nicht so sehr wichtig zu ergründen.

Da bei Nutzung der Paraformat2-Struktur für RichEdits ab Version3.0 (laut MSDN) noch weitere TabAttribute wie z.B. Center tab, Right-aligned tab, ... und verschiedene Tab leader definierbar sind, werde ich jetzt besser mit EM_SetParaFormat experimentieren.

HPB 5. Mai 2009 09:12

Re: Tabulatorpositionen im RichEdit
 
Moin Moin,
hast Du schon herausgefunden wie man Rechte und Linke-Tabstopps setzen kann?
Wenn ja, kannst Du es evtl veröffenlichen??

Mit Gruß HBP

taaktaak 5. Mai 2009 11:30

Re: Tabulatorpositionen im RichEdit
 
Moin, Moin.
Nein, habe die "Tabulatoren" damals nicht weiter verfolgt. Ist aber ein zwingendes Thema in meinem aktuellen Projekt. Mit Blick auf die immer noch umfangreiche ToDo-Liste ist die Befassung damit etwa im nächsten Monat zu erwarten. Da offenbar von Interesse, werde ich mich dann wieder melden.

HPB 5. Mai 2009 11:43

Re: Tabulatorpositionen im RichEdit
 
Moin Ralph,
vielen Dank für Deine rasch Antwort.
Auch mein Terminplan ist doch ziemlich eng.
Ich wäre sehr einer Lösung des Problems interessiert.

Mit vielen Dank aus Nienburg und eine hoffentlich
erfolgreichen Tag.
Hans-Peter


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz