![]() |
Dynamische Frames - Probleme
Hallo Gemeinde,
Intention: Ich versuche ein Programm zu schreiben, welches mir PlugIns (BPL-Packages) einbindet. Dadurch kann ich alle Funktionen in einzelne Packages auslagern und nur die gemeinsame Steuerung (TNA-Symbol, Mainform, Hotkeys usw. usf.) durch das Hauptform erledigen lassen. Dies stelle ich mir so vor: der User möchte das ein .bpl eingebunden wird (also ein entsprechender Eintrag in der Inidatei vorhanden ist). Dann wird aus der Package mit (z.B.) dem Namen 'PlugIn.bpl' automatisch der Frame 'TPlugInFrame' durch GetClass angefordert und in ein dynamisch erstellte TTabControl eingebettet. Hier nun soll der Bneutzer damit arbeiten können. Ich bin soweit, das ich ohne Probleme eine Form einbinden kann, darstellen und mit dieser Arbeiten kann. -> SplashScreen (mit Stringliste, welche den Fortschritt anzeigt) Auch das Frame klappt, aber nicht zu 100%: es wird geladen, eine TTabSheet erzeugt und das Frame dort hineinplatziert. Auch ein möglicher Button reagiert auf Benutzereingaben -> MessageBox 'OK' erscheint. Wenn ich aber versuche vom Frame zur Form.OnCreate auf den Owner zuzugreifen dann habe ich Probleme (hier mal ein Ausschnitt ausm Code) Source befindet sich in der EXE:
Delphi-Quellcode:
Source der Package:
procedure TfrmMain.FormCreate(Sender: TObject);
var Preferences: TAEJPrefSection; PlugInList: TStringList; i: Integer; aClass: TPersistentClass; aSheet: TTabSheet; aFrame: TFrame; p: procedure (Sender: TObject; Sheet: TTabSheet); function GenFrameClassName (Name: String): String; begin Result := 'T' + ChangeFileExt (ExtractFileName (Name), 'Frame'); end; begin // SIT: Identifikation // * Die Übernahme des gemeinsam benutzen ProgrammNamens erfolgt, damit beim // erneuten Starten des Programms das Prog./Formular gefunden werden kann! Application.Title := cProgrammName; // Erstellen der Zugriffsseite Preferences := CommonData.RegisterPrefSection ('General'); PlugInList := TStringList.Create; Preferences.ReadStringList ('PlugIn', PlugInList); // PlugIn (PI): Laden aller PlugIns // * die zu Ladenden PlugIns sind in der IniFile-Sektion 'General' gelistet // * jedes PlugIn hat einen Frame for i := 0 to PlugInList.Count - 1 do begin aClass := CommonData.GetClassOfModule (GenFrameClassName (PlugInList.Strings[i]), PlugInLIst.Strings[i]); if (aClass <> nil) then begin aSheet := TTabSheet.Create (tpcMain); aFrame := TComponentClass(aClass).create (aSheet) as TFrame; aSheet.InsertControl (aFrame); aSheet.PageControl := tpcMain; p := aFrame.MethodAddress ('InitPlugIn'); if Assigned (p) then p (self, aSheet); end; end; PlugInList.Free; end;
Delphi-Quellcode:
Ich habe schon vom Owner gewechselt auf Sheet durch Erweiterung der Prozedur:
unit uAbout;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls, uCommon; type TAboutFrame = class(TFrame) Button1: TButton; procedure InitPlugIn (Sender: TObject; Sheet: TTabSheet); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; implementation {$R *.dfm} procedure TAboutFrame.InitPlugIn (Sender: TObject; Sheet: TTabSheet); begin if (Sheet <> nil) then begin Sheet.Caption := 'About Dialog'; end; end; procedure TAboutFrame.Button1Click(Sender: TObject); begin if (Owner is TTabSheet) then (Owner as TTabSheet).Caption := 'About Dialog'; end; initialization RegisterClass (TAboutFrame); finalization UnregisterClass (TAboutFrame); end. p: procedure (Sender: TObject; Sheet: TTabSheet); aber auch hier bekomme ich Fehler wenn ich auf Sheet.Caption zugreife --> NICHTS PASSIERT, da Sheet = nil Wenn ich zur "interaktiven Laufzeit" (nach Form.OnCreate) auf Owner zugreife passiert das Erwartete... Ich hoffe ich konnte begreiflich machen, wo mein Problem liegt. Kann mir jemand damit helfen - oder gehe ich gar den falschen Weg, Alex |
Ich dachte ja ich verstehs ein wenig...
Ich habe die Prozedur abgeändert:
Delphi-Quellcode:
Nun funktioniert das Ganze so wie ich wollte, aber......
procedure TAboutFrame.InitPlugIn (Sender: TObject; Sheet: TTabSheet);
begin if (Sender <> nil) then begin if (Sender is TTAbSheet) then begin ShowMessage (Sender.ClassName); (Sender as tTabSheet).Caption := 'About Dialog'; end; end; end; Warum ist der Sender mein TTabSheet?!? Müsste das nicht die Form sein - Aufrufeder Code steht in der Form.OnCreate
Delphi-Quellcode:
Ich verstehs nimmer... Ich dachte bisher das ich wüsste was SELF bedeutet, aber dies ist der Gegenbeweis....
p := aFrame.MethodAddress ('InitPlugIn');
if Assigned (p) then p (self, aSheet); mfg, Alex |
Es geht noch weiter...
Liste der Anhänge anzeigen (Anzahl: 1)
So nun habe ich noch weitere Versuche gemacht - Ich habe zum Spass eine Function definiert:
Delphi-Quellcode:
Das klappt nun gar nicht -->
TAboutFrame = class(TFrame)
procedure PlugInInformation (Sender: TObject; var Info: TAEJPlugInInformation); procedure InitPlugIn (Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; [...] procedure TAboutFrame.PlugInInformation (Sender: TObject; var Info: TAEJPlugInInformation); begin Info.PIType := pitSingleTool; Info.PIName := 'About Frame'; end;
Delphi-Quellcode:
da bekomme ich immer einen Fehler...
if (aPlugInClass <> nil) then begin
// PlugIn Informationen lesen aPlugInFrame := TComponentClass(aPlugInClass).create (Application) as TFrame; aPlugInGetInfo := aPlugInFrame.MethodAddress ('PlugInInformation'); if Assigned (aPlugInGetInfo) then aPlugInGetInfo (self, aPlugInInformation) else begin aPlugInInformation.PIType := pitSingleTool; aPlugInInformation.PIName := lstPlugIns.Strings[iPlugInDex]; end; aPlugInSheet.Caption := aPlugInInformation.PIName; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:40 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz