(CodeLib-Manager)
Registriert seit: 9. Jul 2003
Ort: Ensdorf
6.723 Beiträge
Delphi XE Professional
|
TRichedit - Speichern inkl. Links
18. Mai 2008, 11:29
Hi!
Da seitens Microsoft das Abspeichern von mit CFM_Link markierten Wörtern in einem RichEdit nicht unterstützt wird, hat taaktaak hier eine alternative Lösung vorgestellt:
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.
Die Wahl fiel auf CFM_Revised. Insgesamt sind folgende 4 Prozeduren/Funktionen notwendig:
Delphi-Quellcode:
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;
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 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;
Beispielhaft könnte eine Prozedur zum Laden dann so aussehen:
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;
... und so zum Speichern:
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.Lines.SaveToFile(FName); // und nun Speichern
end;
Allerdings bleibt anzumerken, dass die Prozeduren / Funktionen nicht die schnellsten sind und durchaus noch Optimierungsbedarf besteht!
Frederic Kerber
|