AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi TRichEdit - CFM_Link : nach SaveToFile ist alles futsch
Thema durchsuchen
Ansicht
Themen-Optionen

TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

Ein Thema von taaktaak · begonnen am 30. Okt 2007 · letzter Beitrag vom 2. Nov 2007
Antwort Antwort
Seite 1 von 2  1 2      
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#1

TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 30. Okt 2007, 22:39
Moin, Moin Zusammen!

Ich beschäftige mich seit einigen Tagen mit dem RichEditControl. Nachdem ich mich nun im MSN Informationsdickicht etwas besser zurechtfinde habe ich gute Informationen über CharFormat2 und ParaFormat2 gefunden. Damit lassen sich ja grundlegende Formatierungen durchführen, die Delphi so nicht zur Verfügung stellt. Leider hat die Link-Formatierung mir nun einige graue Haare mehr wachsen lassen:

Delphi-Quellcode:
procedure reSetLink(re:TRichEdit;Start,Length:Integer;SwitchOn:Boolean);
var CF2 : TCharFormat2;
    OldRange,
    NewRange : TCharRange;
begin
  FillChar(CF2,SizeOf(CF2),0);
  CF2.cbSize:=SizeOf(CF2);
  CF2.dwMask:=CFM_Link;
  if SwitchOn then CF2.dwEffects:=CFE_Link;

  NewRange.cpMin:=Start;
  NewRange.cpMax:=Start+Length;

  SendMessage(re.Handle,EM_ExGetSel,0,LParam(@OldRange));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
  SendMessage(re.Handle,EM_SetCharFormat,SCF_Selection,LParam(@CF2));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@OldRange));
end;
Obige Prozedur funktioniert prima - solange man den Text nicht in eine Datei speichert und anschließend wieder in den Speicher lädt: Dann ist der Link verschwunden! Habe einen kurzen Text mit 'nem Hex-Editor untersucht. Nun ist auch klar warum: Während für andere Formatierungen entsprechende Befehle (gibt's da einen Fachausdruck?) in der RTF-Datei stehen, unterbleibt dies beim "Link-Format".

Bevor ich nun eine Glatze bekomme , meine Frage: Ist dies so von Microsoft gewollt oder ist Delphi mit dem SaveToFile-Befehl daran schuld? Wenn das alles so sein soll - hat einer 'ne Idee, wie ich das Link-Format für den Anwender "unsichtbar" in eine Datei speichern kann. "Normale" Formatierungen wie FontColor, Unterstreichen o.ä. müssen ja für den Anwender verfügbar bleiben und dürfen nicht für die exklusive Link-Nutzung missbraucht werden.

Gruß Ralph
Ralph
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#2

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 31. Okt 2007, 11:36
Gibt es gar keinen RichEdit-Experten, der hierzu einen Hinweis geben könnte?

Im Augenblick sehe ich nur die Möglichkeit, vor dem Speichern die "Linkformatierung" durch eine andere Formatierung die auch gespeichert wird, dem Anwender aber nicht zur Verfügunge steht, zu ersetzen und beim Laden der Datei diese "behelfsmäßige Formatierung" wieder in einen Link umzuwandeln. Ist aber irgendwie blöd, oder
Gruß Ralph
Ralph
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#3

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 31. Okt 2007, 15:51
Gibt es denn GAR KEINEN Kommentar und GAR KEINE Anregung zu meinem Problem?
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 31. Okt 2007, 15:59
Zitat von taaktaak:
Ist dies so von Microsoft gewollt oder ist Delphi mit dem SaveToFile-Befehl daran schuld?
Es ist nicht von Microsoft vorgesehen, dass man diese Formatierung speichern und wieder laden kann.

Wenn du dir extrem viel Mühe machen willst, dann schaue dir an wie Word es macht (so weit ich mich erinnere über eine Feldfunktion) und implementiere das Einlesen bzw. Speichern in diesem Format selbst.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#5

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 31. Okt 2007, 16:04
Hallo Volker,
vielen Dank! Auf genau diesen Hinweis habe ich gewartet. Mache also nix falsch, weil's so von MS implementiert wurde. Dann will ich 'mal schauen, ob es mir gelingt eine Lösung zu finden ...
Gruß
Ralph
Ralph
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#6

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 31. Okt 2007, 22:51
Hallo Zusammen!
Habe jetzt eine Lösung gefunden, auch nach dem Speichern und Wiedereinlesen aus einer Datei einen mit CFM_Link formatierten Textteil wiederherzustellen. Nachdem Volker bestätigte, dass dies von MS nicht vorgesehen ist, habe ich mich also auf eine eigene Lösung konzentrieren können. Vorab: Sie erscheint mir nicht sonderlich elegant und noch optimierungsfähig - aber sie hat den Charme in nur etwas mehr als einer Stunde entstanden zu sein.

Grundidee ist, die CFM_Link-Formatierung vor dem Speichern in eine andere Formatierung zu konvertieren und dies nach dem Einlesen aus der Datei wieder rückgängig zu machen. Diese "temporäre Hilfsformatierung" muss nun eine sein, die a) auch gespeichert und b) vom Anwender nicht vermisst wird.

Ich habe mich für CFM_Revised entschieden - kann mir im Augenblick nicht vorstellen, dass diese Formatierung im Rahmen meiner Programme benötigt wird. Insgesamt sind folgende 4 Prozeduren/Funktionen notwendig (hier ist deutliches Optimierungspotential) :

Delphi-Quellcode:
procedure reSetLink(re:TRichEdit;Start,Length:Integer;SwitchOn:Boolean);
var CF2 : TCharFormat2;
    OldRange,NewRange : TCharRange;
begin
  FillChar(CF2,SizeOf(CF2),0);
  CF2.cbSize:=SizeOf(CF2);
  CF2.dwMask:=CFM_Link;
  if SwitchOn then CF2.dwEffects:=CFE_Link;

  NewRange.cpMin:=Start;
  NewRange.cpMax:=Start+Length;

  SendMessage(re.Handle,EM_ExGetSel,0,LParam(@OldRange));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
  SendMessage(re.Handle,EM_SetCharFormat,SCF_Selection,LParam(@CF2));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@OldRange));
end;
Delphi-Quellcode:
function reIsLink(re:TRichEdit;Position:Integer):Boolean;
var CF2 : TCharFormat2;
    OldRange,NewRange : TCharRange;
begin
  FillChar(CF2,SizeOf(CF2),0);
  CF2.cbSize:=SizeOf(CF2);
  CF2.dwMask:=CFM_Link;

  NewRange.cpMin:=Position;
  NewRange.cpMax:=Position+1;

  SendMessage(re.Handle,EM_ExGetSel,0,LParam(@OldRange));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
  SendMessage(re.Handle,EM_GetCharFormat,SCF_Selection,LParam(@CF2));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@OldRange));

  Result:=CF2.dwEffects and CFE_Link=CFE_Link;
end;
Delphi-Quellcode:
procedure reSetRevised(re:TRichEdit;Start,Length:Integer;SwitchOn:Boolean);
var CF2 : TCharFormat2;
    OldRange,NewRange : TCharRange;
begin
  FillChar(CF2,SizeOf(CF2),0);
  CF2.cbSize :=SizeOf(CF2);
  CF2.dwMask :=CFM_Revised;
  if SwitchOn then CF2.dwEffects:=CFE_Revised;

  NewRange.cpMin:=Start;
  NewRange.cpMax:=Start+Length;

  SendMessage(re.Handle,EM_ExGetSel,0,LParam(@OldRange));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
  SendMessage(re.Handle,EM_SetCharFormat,SCF_Selection,LParam(@CF2));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@OldRange));
end;
Delphi-Quellcode:
function reIsRevised(re:TRichEdit;Position:Integer):Boolean;
var CF2 : TCharFormat2;
    OldRange,NewRange : TCharRange;
begin
  FillChar(CF2,SizeOf(CF2),0);
  CF2.cbSize:=SizeOf(CF2);
  CF2.dwMask:=CFM_Revised;

  NewRange.cpMin:=Position;
  NewRange.cpMax:=Position+1;

  SendMessage(re.Handle,EM_ExGetSel,0,LParam(@OldRange));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
  SendMessage(re.Handle,EM_GetCharFormat,SCF_Selection,LParam(@CF2));
  SendMessage(re.Handle,EM_ExSetSel,0,LParam(@OldRange));

  Result:=CF2.dwEffects and CFE_Revised=CFE_Revised;
end;

Speichern und Laden erfolgen dann nach folgendem beispielhaften Schema:

Delphi-Quellcode:
procedure reSave(var RE:TRichEdit;FName:String);
var i : Integer;
begin
  for i:=0 to length(RE.Text)-1 do // konvertiere Link-Attribut
    if reIsLink(RE,i) then reSetRevised(RE,i,1,true); // in Revised-Attribut
  RE.SaveToFile(FName); // und nun Speichern
end;
Delphi-Quellcode:
procedure reLoad(var RE:TRichEdit;FName:String);
var i : Integer;
begin
  RE.LoadFromFile(FName); // aus der Datei einlesen und
  for i:=0 to length(RE.Text)-1 do // konvertiere Revised-Attribut
    if reIsRevised(RE,i) then reSetLink(RE,i,1,true); // zurück in Link-Attribut
end;
So, auch wenn die Resonanz auf meine Anfrage recht bescheiden war, vielleicht kann es ja doch der eine oder andere gebrauchen ...

Gruß Ralph
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 1. Nov 2007, 14:27
Und das ist immer noch eine gültige RTF-Datei, die auch ohne Probleme mit anderen RTF-Editoren geöffnet werden kann?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#8

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 1. Nov 2007, 15:22
Hallo Michael,
hab's eben noch mal getestet: JA, die erzeugte Datei lässt sich mit WORD und NotePad öffnen - das ersatzweise verwendete Attribut "Revised" wird in beiden Programmen nicht verwendet(?), zumindest aber optisch nicht dargestellt.
Die beiden Prozenduren SAVE... und LOAD... sind nur beispielhaft angeführt. In meiner Anwendung wird der Text vor dem Speichern noch komprimiert und in ein proprietäres Archiv geschrieben, sodaß nahezu unbegrenzt viele RTF-Texte in das Archiv (Indexdatei und Datendatei) aufgenommen werden können.
Gruß Ralph
Ralph
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#9

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 1. Nov 2007, 22:49
Hallo Zusammen!

Bevor es Klagen über mangelnde Geschwindigkeit gibt, oute ich es besser selbst: Wenn der Text mehrere Tausend Zeichen lang ist, dann dauert das alles für meinen Geschmack viel zu lange! Wie ich bereits vermutet habe, müssen die allgemeingültigen Proc/Funcs und insbesondere die Konvertierungs-Schleifen vor dem Speichern bzw. nach dem Laden optimiert werden. Wenn ich diesbezüglich etwas erreicht habe, werde ich das natürlich zur Verfügung stellen.

Gruß Ralph

/edit: Na, und noch ein großer Schnitzer: Es müssen natürlich RE.Lines.LoadFromFile() bzw. RE.Lines.SaveToFile() verwendet werden
Ralph
  Mit Zitat antworten Zitat
taaktaak

Registriert seit: 25. Okt 2007
Ort: Radbruch
1.990 Beiträge
 
Delphi 7 Professional
 
#10

Re: TRichEdit - CFM_Link : nach SaveToFile ist alles futsch

  Alt 2. Nov 2007, 09:15
Moin, Moin.

Hmmm, mit dem Optimieren ist das so eine Sache.

1. Das Speichern ist nicht so kritisch, da der Anwender hier keine so hohe Anforderung hat, sofort eine optische Rückmeldung zu erhalten.

2. Anders beim Laden aus der Datei, nach Auswahl des Textes in einer Auswahlliste sollte das RichEdit (im Optimalfall) praktisch sofort gefüllt sein - leider bremst die Prüfung auf vorhande Revised-Attribute im Text den Ladevorgang enorm aus (Ladezeit für etwa 13000 Zeichen langen Text auf einem Notebook: über 3 Sekunden).

Habe nun die für den Ladevorgang zuständigen Routinen verbessert:

Delphi-Quellcode:
  function IsRevised(re:TRichEdit;Position:Integer):Boolean;
  var NewRange : TCharRange;
  begin
    NewRange.cpMin:=Position;
    NewRange.cpMax:=Position+1;
    SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
    SendMessage(re.Handle,EM_GetCharFormat,SCF_Selection,LParam(@CF2Get));
    Result:=CF2Get.dwEffects and CFE_Revised=CFE_Revised;
  end;

  procedure SetLink(re:TRichEdit;Position:Integer);
  var NewRange : TCharRange;
  begin
    NewRange.cpMin:=Position;
    NewRange.cpMax:=Position+1;
    SendMessage(re.Handle,EM_ExSetSel,0,LParam(@NewRange));
    SendMessage(re.Handle,EM_SetCharFormat,SCF_Selection,LParam(@CF2Set));
  end;
Gegenüber der Ursprungsversion sind die Initialisierungen 'raus (muss ja nicht 13.000x initialisiert werden). Ebenso Save/Restore der SelPosition. Die eigentliche Ladeprozendur sieht dann beispielhaft folgendermassen aus (im Original abweichend, nur um das Schema zu demonstrieren):

Delphi-Quellcode:
procedure Load(var RE:TRichEdit;FName:String);
var i : Integer;
    CF2Get,
    CF2Set : TCharFormat2;
  
  FillChar(CF2Get,SizeOf(CF2Get),0);
  CF2Get.cbSize:=SizeOf(CF2Get);
  CF2Get.dwMask:=CFM_Revised;

  FillChar(CF2Set,SizeOf(CF2Set),0);
  CF2Set.cbSize :=SizeOf(CF2Set);
  CF2Set.dwMask :=CFM_Link;
  CF2Set.dwEffects:=CFE_Link;
  
  RE.Lines.BeginUpdate;
  RE.Lines.LoadFromFile(FName);

  for i:=0 to length(RE.Text)-1 do // konvertiere Revised-Attribut
    if IsRevised(RE,i) then SetLink(RE,i); // zurück in Link-Attribut

  RE.Lines.EndUpdate;

  // ...
end;
"Rumbasteln" an der FOR-Schleife, die den RichEdit-Text prüft und ggf. das Attribut konvertiert, brachten bisher leider NUR Geschwindigkeitsnachteile (z.B. wortweise weiter, wenn am Anfang des Textes kein Attribut gefunden).

Die Ladezeit konnte nun auf etwas über 2 Sekunden reduziert werden - ist aber immer noch zu lang. Hat jemand eine Idee?

Gruß Ralph

PS : Muss jetzt mal was für die Firma tun und bin erst mal nicht am PC
Ralph
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:23 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