Delphi-PRAXiS
Seite 1 von 2  1 2      

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 [Erledigt] RichEdit zur Laufzeit durch SynEdit ersetzen (https://www.delphipraxis.net/125739-%5Berledigt%5D-richedit-zur-laufzeit-durch-synedit-ersetzen.html)

-=IOI=- 10. Dez 2008 21:30


[Erledigt] RichEdit zur Laufzeit durch SynEdit ersetzen
 
Ich hab mal wieder ein Problem.
ich hab ein TabSheet, auf dem ein RichEdit ist. Über ein Popup Menu möchte ich nun zur Laufzeit, dieses RichEdit durch ein Synedit ersetzen und auch wieder umgekehrt.
Hier mal mein Quellcode für die beiden Fälle:
Delphi-Quellcode:
procedure TForm1.Quellcodemodus1Click(Sender: TObject);
var
  NewSyn: TSynEdit;
begin
  memo := FindMemo(ActiveControl); //aktives Tabsheet finden
  Quellcodemodus1.Visible := false;
  Editormodus1.Visible := true;
  NewSyn := TSynEdit.Create(memo);
  NewSyn.Options := NewSyn.Options + [eoHideShowScrollbars];
  NewSyn.OnMouseDown := TRichEdit(memo.Controls[0]).OnMouseDown;
  NewSyn.OnChange := TRichEdit(memo.Controls[0]).OnSelectionChange;
  NewSyn.OnKeyDown := TRichEdit(memo.Controls[0]).OnKeyDown;
  TRichEdit(memo.Controls[0]).Destroy;
  NewSyn.Parent := memo;
  NewSyn.Align := alClient;
  NewSyn.Show;
  NewSyn.SetFocus;
  NewSyn.ParentFont := true;
  NewSyn.Gutter.DigitCount := 5;
  NewSyn.Gutter.LeftOffset := 1;
  NewSyn.Gutter.RightOffset := 1;
  NewSyn.Gutter.ShowLineNumbers := true;
  NewSyn.Gutter.Width := 15;
  NewSyn.WordWrap := true;
  NewSyn.ScrollBars := ssVertical;
  //Text übernehmen
end;
Delphi-Quellcode:
procedure TForm1.Editormodus1Click(Sender: TObject);
var
  NewMemo: TRichEdit;
begin
  memo := FindMemo(ActiveControl); //aktives TabSheet finden
  Quellcodemodus1.Visible := true;
  Editormodus1.Visible := false;
  NewMemo := TRichEdit.Create(memo);
  NewMemo.OnMouseDown := TSynEdit(memo.Controls[0]).OnMouseDown;
  NewMemo.OnSelectionChange := TSynEdit(memo.Controls[0]).OnChange;
  NewMemo.OnKeyDown := TSynEdit(memo.Controls[0]).OnKeyDown;
  TSynEdit(memo.Controls[0]).Destroy;
  NewMemo.Parent := memo;
  NewMemo.Align := alClient;
  NewMemo.Show;
  NewMemo.SetFocus;
  NewMemo.ScrollBars := ssVertical;
  //Text übernehmen
end;
Das erste Wechseln von RichEdit zu SynEdit funktioniert tadellos.
Wenn ich nun aber wieder zurückwechsle, bekomme ich eine Access Violation.
Was mache ich da falsch?

SirThornberry 10. Dez 2008 21:33

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
kannst du bitte die vollständige Fehlermeldung der Accessviolation posten? Gerade die Adressen und deren Aktionen sind interessant.

thkerkmann 10. Dez 2008 21:39

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Hi,

warum setzt Du nicht beide RichEdit und SynEdit auf das Tabsheet, und machst sie nur abwechselnd visible.
Hab ich mal ähnlich für einen Editor gemacht und läuft prima.

Gruss

-=IOI=- 10. Dez 2008 21:48

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Fehlermeldung:
Zugriffsverletzung bei Adresse 0044654C in Modul 'DeskEdit.exe'. Lesen von Adresse 000001A0.

Ich hätte nur ungern Komponenten am Laufen, die ich garnicht benötige, aber im Notfall werde ich es wohl mit visible lösen.

jfheins 10. Dez 2008 22:04

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Ne AV tritt öfters auf, wenn du auf ein nicht-initialsierte sOBjekt zugreifst ...

Was passiert, ,wenn du startt den harten Casts ein as benutzt und statt .Destroy Freeandnil() :?:

(Könnte es sein, dass du beim zurückwechseln mit dem Index 0 auf das eigentlich schon freigegebene Objekt zugreifst ?)

Btw.: Wenn du Zeile für Zeile durchsteppst, in welche Zeile tritt die AV auf?

-=IOI=- 10. Dez 2008 22:17

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
FreeAndNil() gibt es für ein RichEdit garnicht.
Aber das mit dem Index hatte ich mir auch schon gedacht un daran liegt es wohl auch. Denn der Fehler tritt genau in der ersten Zeile auf, in der ich auf dieses Element versuch zuzugreifen.

Könnte ich also irgendwie sicherstellen, dass mein SynEdit in der Komponentenliste bei 0 steht?

jfheins 10. Dez 2008 22:26

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Ich meinte das so:
Delphi-Quellcode:
procedure TForm1.Editormodus1Click(Sender: TObject);
var
  NewMemo: TRichEdit;
begin
  memo := FindMemo(ActiveControl); //aktives TabSheet finden
  Quellcodemodus1.Visible := true;
  Editormodus1.Visible := false;
  NewMemo := TRichEdit.Create(memo);
  NewMemo.OnMouseDown := (memo.Controls[0] as TSynEdit).OnMouseDown;
  NewMemo.OnSelectionChange := (memo.Controls[0] as TSynEdit).OnChange;
  NewMemo.OnKeyDown := (memo.Controls[0] as TSynEdit).OnKeyDown; // Soft-Casten
  FreeAndNil(memo.Controls[0]); // Freeandnil
  NewMemo.Parent := memo;
  NewMemo.Align := alClient;
  NewMemo.Show;
  NewMemo.SetFocus;
  NewMemo.ScrollBars := ssVertical;
  //Text übernehmen
end;
Da sowohl der Parent als auch der Owner "memo" ist, gibt es da evtl. sowas wie RemoveControl, RemoveComponent oder so ähnlich?

-=IOI=- 10. Dez 2008 22:33

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Ok, also bei FreeAndNil meckert er wegen dem Parameter ([Fehler] main.pas(984): E2197 Konstantenobjekt kann nicht als Var-Parameter weitergegeben werden)
Es gibt die Methode RemoveControl(), aber der Effekt ist derselbe wie bei .Destroy.

BUG 10. Dez 2008 22:34

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Hast du außer dem RichEdit oder SynEdit noch etwas auf dem Tabsheet? Ansonsten könntest du es doch so probieren:
Delphi-Quellcode:
var
  NewMemo: TRichEdit;
  OldMemo: TSynEdit;
begin
  memo := FindMemo(ActiveControl); //aktives TabSheet finden
  Quellcodemodus1.Visible := true;
  Editormodus1.Visible := false;
  OldMemo := TSynEdit(memo.Controls[0]); //<=
  NewMemo := TRichEdit.Create(memo);
  NewMemo.OnMouseDown := OldMemo .OnMouseDown;
  NewMemo.OnSelectionChange := OldMemo .OnChange;
  NewMemo.OnKeyDown := OldMemo.OnKeyDown;
  OldMemo.free;
  NewMemo.Parent := memo; // ist das eigentlich notwendig?
  NewMemo.Align := alClient;
  NewMemo.Show;
  NewMemo.SetFocus;
  NewMemo.ScrollBars := ssVertical;
  //Text übernehmen
end;
Somit würdest du auf jeden Fall nicht das neue Memo freigeben.

Eigentlich könnte man doch auch eindeutige Namen und FindComponent benutzen, oder?


MfG,
Bug

-=IOI=- 10. Dez 2008 22:46

Re: RichEdit zur Laufzeit durch SynEdit ersetzen
 
Das kann genausowenig funktionieren, da ich ja trotzdem auch .Controls[0] zugreifen müsste, mein SynEdit dort aber garnicht drin ist.
In .Controls[1] ist es jedoch auch nocht. Das hab ich schon probiert.
Eindeutige Namen vergeben wird schwierig, da ich eine variable Anzahl an TabSheets habe, von denen man auch jedes Löschen kann.
Weitere Komponenten sind nicht auf dem TabSheet.

Es muss doch irgendeine Routine geben, wie die Komponenten in die Controls Liste gespeichert werden. Das erste wird ja immer in .Controls[0] gespeichert. Aber was passiert, wenn man das löscht un ein neues einfügt?


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:19 Uhr.
Seite 1 von 2  1 2      

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