Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Dynamische Frames - Probleme (https://www.delphipraxis.net/62791-dynamische-frames-probleme.html)

junale 9. Feb 2006 15:53


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:
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;
Source der Package:

Delphi-Quellcode:
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.
Ich habe schon vom Owner gewechselt auf Sheet durch Erweiterung der Prozedur:
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

junale 9. Feb 2006 16:50

Ich dachte ja ich verstehs ein wenig...
 
Ich habe die Prozedur abgeändert:

Delphi-Quellcode:
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;
Nun funktioniert das Ganze so wie ich wollte, aber......

Warum ist der Sender mein TTabSheet?!? Müsste das nicht die Form sein - Aufrufeder Code steht in der Form.OnCreate

Delphi-Quellcode:
      p := aFrame.MethodAddress ('InitPlugIn');
      if Assigned (p) then
        p (self, aSheet);
Ich verstehs nimmer... Ich dachte bisher das ich wüsste was SELF bedeutet, aber dies ist der Gegenbeweis....

mfg,
Alex

junale 10. Feb 2006 06:48

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:
  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;
Das klappt nun gar nicht -->

Delphi-Quellcode:
    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;
da bekomme ich immer einen Fehler...


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:34 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