Autor Beitrag
hRb
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 11.01.16 15:35 
Hallo,
Ich verbinde heute eine Frage mit einer Lösung - wenn es keine bessere gibt.
Bei Änderung der Schriftgröße in Richedit-Vorlagen beobachte ich (zumindest unter Delphi7) ein teilweises Fehlverhalten.

Programm-Konstruktion: In meinem Programm liegen auf den einzelnen Reitern eines TTabedNotebook-Objektes 13 Richedit-Vorlagen. Sichtbar ist immer nur die jeweils aktive Vorlage. Nun soll die Schriftgröße in allen Edit-Vorlagen verändert werden. Dabei stelle ich fest, dass sich die Änderung nur auf die jeweils sichtbare ODER auf noch nicht gespeicherte Textvorlagen auswirkt. Umgekehrt ausgedrückt: wenn (((leere Vorlagen) ODER (schon gespeicherte Textvorlagen)) UND (nicht Fokused)) dann verändert sich die Schriftgröße nicht.
Problem verständlich beschrieben?
Eine Lösung liefere ich gleich mit. Keine sehr elegante, aber es funktioniert.
1. Prüfe ob Text modified,
2. wenn leer/gespeichert Zwangsänderung,
3. Schriftgrößenänderung wirkt
Hat jemand eine Erklärung, warum dies so ist? Worin besteht der Unterschied zwischen sichtbar/nichtsichtbare bzw. gespeichert/ungespeicherte Edit-Vorlage?
Hinweis: Fi[i] ist array of Richedit, FiLinAct, FiColAct ist Cursorpos

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure SizeGroesse(big,hoehe:integer);
var i:integer;
    s:string;
begin
with Form1 do begin
  s:='=';
  for i:=1 to cAnzahlVorlagen do 
   begin with Fi[i] do begin    //array of Richedit
     if modified=false then begin
       Lines.Insert(FiLinAct,s);  //Vorlage zwangsweise ändern (modified=true)
       Font.Height:=hoehe;  // hoehe genügt {Fi[i].Font.Size:=big; }
       Lines.Delete(FiLinAct)
       modified:=false; end 
     else Font.Height:=hoehe; 
     if Focused then SelStart:=Perform(EM_LineIndex,FiLinAct,0)+ FiColAct; //Cursorpos beibehalten
   endend;
  Edit1Com.Font.Height:=hoehe;  //Kommandozeile {weitere anzupassende Vorlagen}
  FiFormat.Font.Height:=hoehe;  //Lineal
  LinePerPage:=ZeilenProSeite;  //REdit1.Height, neue Zeilenzahl berechnen
endend;
baumina
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 305
Erhaltene Danke: 61

Win 7
Delphi 10.2 Tokyo Enterprise
BeitragVerfasst: Mo 11.01.16 15:42 
Dein Quellcode ist für mich durch die Benutzung von "with" nahezu unlesbar. Kannst du diese with bitte rausnehmen?
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 11.01.16 16:02 
Habe deinen Quellcode auch nicht gelesen, möchte aber Folgendes dazu anmerken:

Es gibt in einer TRichEdit-Komponente natürlich das Property Font, das quasi die Start-Schrift beschreibt: Jene Schrift-Einstellung, die beim ersten Hineinschreiben in ein TRichEdit verwendet werden soll. Wenn du nun nachträglich die Schrift in einem TRichEdit ändern möchtest, mußt du zuerst den zu ändernden Text selektieren und dann über SelAttributes die Schrift ändern. In einem TRichEdit, das bereits Text enthält bzw. nach seiner Erzeugung enthalten hat, sind die Schrifteinstellungen an Absätze gebunden oder gar an einzelne Zeichen oder Strings. Ansonsten könnte man in einem RichEdit nicht unterschiedliche Schriftformatierungen verwenden.

Eine Idee, die mir gerade kam: Du könntest einmal versuchen, bevor du die Font-Eigenschaft eines TRichEdit änderst, PlainText auf True zu setzen und danach wieder auf False. Würde sich aber wohl nur auf ein TRichEdit auswirken, das nach seiner Erzeugung noch keinen Text enthalten hat, denn wenn du den Text aus einem TRichEdit löschst, bleiben (bei PlainText = False) Schriftformatierungen des letzten (oder ersten?) Absatzes bestehen.

Noch ein Gedanke: Verwende doch einmal statt des Font-Property's Height die Eigenschaft Size: Wenn die Eigenschaft Size einen positiven Wert enthält, ergibt sich für die Eigenschaft Height eine negative Zahl. Wenn Height einen positiven Wert enthält, wird die Eigenschaft Size in eine negative Zahl umgewandelt.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mo 11.01.16 21:14 
Oh, das hatte ich vergessen:
1. Bei meinem Programm handelt es sich um einen speziellen Editor, der mittels Kommandosprache oder Buttonklicks Daten innerhalb oder auch zwischen den einzelnen Vorlagen austauschen kann. Das Attribut Plain ist daher überall true. Insoweit gibt es keine Schriftgrößenunterschiede innerhalb der Vorlage. Ich nutze daher auch keine proportionale Schrift sondern CourierNew.
2. Im Pascalcode sieht man, dass die Prozedurversorgung sowohl Big und Hoehe enthält, wobei Big = Font.Size und Hoehe = Font.Height entspricht. Im Test zeigte sich, dass das Ändern eines Parameters genügt (der jeweils andere wird automatisch angepasst). Dabei ergab sich keine Funktionsverbesserung ob ich beide oder nur einen der beiden geändert habe (gleichwertig).
2. Die with-Anweisung ist etwas für Schreibfaule, dient der Comliper-Optimierung und ist zwingend erforderlich, wenn es um Bearbeitung innerhalb einer Schleife geht. Die Definition von Fi (File) ist
var Fi = array [1..cAnzahlVorlagen] of TRichedit
und enthält die einzelnen Vorlagen. Mit der for-Anweisung und der nachgeschalteten "with Fi[i]" -Anweisung weiß der Compiler, um welche Vorlage es sich handelt. Ohne with wäre die volle schreibweise z.B.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
if Form1.Richedit1.modified then begin
   Form1.Richedit1.Lines.Insert(FiLinAct,s);
   Form1.Richedit1.Font.Height:=hoehe; 
   ..
   end

und dann alles mit Form1.Richedit2. modified, Richedit3, usw. bis Richedit13
Nochmals: meine Lösung funktioniert ja, mein Unverständnis beruht darin, dass in einer leeren oder gespeicherten Vorlage die Height- und Size-Parameter zwar geändert werden, wenn man dann jedoch auf die Vorlage den Focus setzt und schreibt, sich diese Änderung nicht ausgewirkt hat (im Gegensatz zu einer Vorlage mit modified=true)
Könnte ja sein, dass ein XE-Compiler sich anders verhält. Dies kann ich derzeit aber noch nicht testen. Zumindest gibt es für jemanden der gleiches feststellt einen Lösungsansatz.
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 11.01.16 21:42 
Wenn ich dich richtig verstehe, möchtest du die Schriftgröße nach dem Speichern ändern, um dem Anwender damit anzuzeigen, daß der Text bereits gespeichert wurde, ebenso, wenn der Text geändert oder entfernt und automatisch durch einen Standard-Text ersetzt wurde. Wäre es hier nicht sinnvoller, den Status eines TRichEdit in einer Statusbar oder, wie das manche Anwendungen machen, in der Caption des Hauptfensters anzuzeigen?

Wie ich in meinem letzten Post dargelegt habe, werden für Font.Height negative Werte verwendet. Wenn du stattdessen positive Werte übergibst, kann es gut sein, daß die gar nicht angenommen werden.

Von welchem Typ ist die Variable Fi? Ist das eine Record of TObject oder Record of TRichEdit oder eine TObjectList? Normalerweise verwendet man den Namen (Property Name) eines TObjects, um auf seine Instanz zuzugreifen. Das kann man eigentlich nur mit einer TObjectList.
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Mi 13.01.16 22:02 
Tut mit leid, wenn ich das "Problem" nicht gut genug beschrieben habe. Der Beweggrund zur Veränderung der Schriftgröße ist viel einfacherer Art.
Ich habe einen Bildschirm 1280x960 Pixel. Ein Bekannter der mein Programm nutzt hat einen Bildschirm 1920x1200. Ergebnis: die Schrift ist sehr klein bzw. schwer lesbar. Daher habe ich die Möglichkeit vorgesehen die Schriftgröße in Grenzen variabel anzupassen über Menü (wie nachstehend gezeigt) bzw. in einer config-Datei schon bei Programmstart voreinstellbar.
Den Hinweis auf negative Zahlen beim Parameter Height habe ich natürlich bedacht.
Wie beschrieben, liegen alle Richedit-Objekte quasi verdeckt gestapelt auf einem TabbedNotebook-Objekt. Über diesem läuft ein "Lineal" das mit dem vertikalen Scrollbar des jeweils aktiven Richedit (sprich Fi[i]) synchronisiert ist. In soweit muss sichergestellt werden, dass in allen Vorlagen immer gleiche Schriftgröße angezeigt wird (ansonsten passt Lineal nicht zur Edit-Vorlage. Dabei habe ich festgestellt, dass es unter den oben genannten Kriterien nicht in allen Vorlagen funktioniert.
Gerne würde ich einen Ausschnitt der Screenoberfläche zeigen, dann wäre einiges leichter zu verstehen. Das geht aber wohl im Forum nicht.
Das Fi-array ist vom Typ TRichedit. Vielleicht in Ermangelung besserer Programmiermethoden, weise ich in der INI-Routine die 13 Richedit-Objekte dem Fi-array zu. Für mich habe ich damit einen Weg gefunden die vielen Richedit-Objekte über einen Index anzusprechen, was die Programmierung stark vereinfacht. Aber all die zuletzt genannten Hinweise führen vom Problem weg. Frage mich halt immer noch, warum eine Schriftänderung sich überall nur auswirkt wenn ich obigen "Trick" anwende.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Size9MenuClick(Sender: TObject);
{ Schriftgrösse anpassen }
begin
 SizeGroesse(9,-12);
end;
procedure TForm1.Size10MenuClick(Sender: TObject);
begin
 SizeGroesse(10,-13);
end;
procedure TForm1.Size11MenuClick(Sender: TObject);
begin
 SizeGroesse(11,-15);
end;
procedure TForm1.Size12MenuClick(Sender: TObject);
begin
 SizeGroesse(12,-16);
end;
hRb Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 267
Erhaltene Danke: 12



BeitragVerfasst: Sa 17.06.17 00:04 
Manchmal dauert es lange, bis ein altes Thema plötzlich eine Lösung findet. Hatte wie oben beschrieben den Effekt, dass die Anpassung der Schriftgröße manchmal funktionierte, manchmal nicht.
Bisher hatte ich folgenden Befehlscode
ausblenden Delphi-Quelltext
1:
 Richedit.Size:= Schriftgroesse.Value;					

Inzwischen wird mir klar, dass eine gesicherte Änderung eines kompletten Textes nur gelingt, wenn der gesamte Text auch markiert ist. Da ich immer wieder sehr konkrete Hilfe erhalte, hier ein funktionsfähiger Code:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TForm1.SchriftgroesseChange(Sender: TObject);
{Schriftgroesse ist ein TSpinedit-Object}
var Start:longint;
begin  
 with Richedit do begin
  Lines.Beginupdate;  //flackern unterdrücken
   Start:=SelStart;   //Schreibmarke merken
   SelStart:=0;       
   SelLength:=length(text);  //gesamten Text markieren
   SelAttributes.Size:=Schriftgroesse.Value; //ändert gesamten Text in Richedit
   SelLength := 0;
   SelStart:=Start;  //Schreibmarke wieder herstellen
  Lines.EndUpdate;
 end;
end;

Sollte jemand - wie in der zuvor geführten Diskussion - mehrere Richedit in einer Form haben, die alle die gleiche Schriftgröße haben sollten, dann einfach eine for-Schleife:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var 
 Fi: array[1..3of TRichedit;
begin
 for i:=1 to 3 do 
  with Fi[i] do begin
  Lines.Beginupdate;  //flackern unterdrücken
  ..
  ..
  Lines.EndUpdate;
 end;
end;