Einzelnen Beitrag anzeigen

sir-archimedes

Registriert seit: 2. Jan 2006
Ort: Münster
167 Beiträge
 
Delphi 2006 Professional
 
#5

Re: Objektablage zum Teil instabil?

  Alt 9. Feb 2006, 16:58
Okay, ich versorge euch dann mal mit Code:

Zunächst das Formular aus dem Package (pkgForms.bpl):
Delphi-Quellcode:
unit uAMSForm;

interface
uses Forms, Windows, SysUtils, Classes;

type
  EDialogExecuteAbort = Exception;
  TDialogExecuteEvent = procedure(Sender: TObject; var stop : boolean) of Object;

  TAMSForm = class(TForm)
  private
    { Private-Deklarationen }
    FOnPrepare : TDialogExecuteEvent;
    FOnReActivate : TNotifyEvent;
  public
    { Public-Deklarationen }
    function ExecuteModal : Integer; dynamic;
    procedure ShowPrepared; dynamic;
    procedure ReActivate; dynamic;
    constructor Create(AOwner : TComponent); override;
  published
    property OnPrepare : TDialogExecuteEvent read FOnPrepare write FOnPrepare;
    property OnReActivate : TNotifyEvent read FOnReActivate write FOnReActivate;
  end;

implementation

{ TAMSForm }

constructor TAMSForm.Create(AOwner: TComponent);
begin
  inherited;
  // Activate Hints for all descended forms
  ShowHint := true;
end;

function TAMSForm.ExecuteModal: Integer;
var
  Stop : Boolean;
begin
  Stop := false;
  if Assigned(onPrepare) then
    onPrepare(self, Stop);
  if Stop then
    raise EDialogExecuteAbort.Create(Format('Starten des Formulares "%s" abgebrochen',[ClassName]));
  Result := ShowModal;
end;

procedure TAMSForm.ReActivate;
begin
  if Assigned(OnReActivate) then
    OnReActivate(self);
  BringToFront;
end;

procedure TAMSForm.ShowPrepared;
var
  Stop : Boolean;
begin
  Stop := false;
  if Assigned(onPrepare) then
    onPrepare(self, Stop);
  if Stop then
    raise EDialogExecuteAbort.Create(Format('Starten des Formulares "%s" abgebrochen',[ClassName]));
  Show;
end;

end.
Registrieren tue ich es so (pkgFormsD.bpl):
Delphi-Quellcode:
unit uAMSFormReg;

interface
uses uAMSForm, Classes, DesignIntf, DesignEditors;

procedure Register;

implementation

procedure Register;
begin
  RegisterCustomModule(TAMSForm, TCustomModule);
end;

end.
Dann noch z.B. die AMSBaseForm, die in der Objektablage liegt: (Da ist noch nicht wirklich viel drin. Habe diese Klasse angelegt, um spätere Erweiterungen an einer Basisklasse, die im Hauptprojekt liegt durchführen zu können.
Delphi-Quellcode:
unit uAMSBaseForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, fMainForm, uAMSForm;

type
  TAMSBaseForm = class(TAMSForm)
  protected
    { Private-Deklarationen }
    MainForm : TAMSMainForm;
  public
    { Public-Deklarationen }
    constructor Create(AOwner : TComponent); override;
  end;

implementation

{$R *.dfm}

{ TAMSBaseForm }

constructor TAMSBaseForm.Create(AOwner: TComponent);
begin
  inherited;
  if AOwner IS TAMSMainForm then
    MainForm := AOwner AS TAMSMainForm;
end;

end.
Dann noch evtl. die MDI-Klasse (Diese soll dafür selbst sorgen, dass ihre Actions in eine Toolbar eingetragen werden. Den Mechanismus werde ich aber wahrscheinlich noch so austauschen, dass ich nicht direkt auf die Mainform zugreife, sondern eine Toolbar übergebe):
Delphi-Quellcode:
unit uMDIForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, uAMSBaseForm, ActnList, TBX;

type
  TMDIForm = class(TAMSBaseForm)
    FormActions: TActionList;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    Constructor Create(AOwner : TComponent); override;
  end;

  TMDIFormClass = class of TMDIForm;

implementation

{$R *.dfm}

procedure TMDIForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  inherited;
  Action := caFree;
  if Assigned(MainForm) AND (Assigned(MainForm.MDIToolbar)) then
    begin
      MainForm.MDIToolbar.BeginUpdate;
      MainForm.MDIToolbar.Items.Clear;
      MainForm.MDIToolbar.Visible := false;
      MainForm.MDIToolbar.EndUpdate;
    end;
end;

constructor TMDIForm.Create(AOwner : TComponent);
begin
  inherited;
  WindowState := wsMaximized;
end;

procedure TMDIForm.FormActivate(Sender: TObject);
var
  Item : TTBXItem;
  I : Integer;
begin
  inherited;
  if Assigned(MainForm) then
    begin
      MainForm.MDIToolbar.BeginUpdate;
      MainForm.MDIToolbar.Items.Clear;
      for I := 0 to FormActions.ActionCount - 1 do
        begin
          Item := TTBXItem.Create(MainForm.MDIToolbar);
          Item.Action := FormActions.Actions[I];
          MainForm.MDIToolbar.Items.Add(Item);
        end;
      MainForm.MDIToolbar.Visible := MainForm.MDIToolbar.Items.Count > 0;
      MainForm.MDIToolbar.EndUpdate;
    end;
end;

end.
Ich höre an dieser Stelle mal auf - die beiden letzten Formen sind auf jeden Fall in der Objektablage eingetragen. In den dfm-Dateien habe ich gar nichts geändert, da mir das die Objektablage eigentlich völlig richtig automatisch macht.

In den Formen die dadrunter abgeleitet liegen (z.B. PaneledMDIForm) kommen nur noch ein paar Panels hinzu, die steuern, wie die Fenster aufgebaut sind. Die angesprochene DialogForm hat noch einen OK und einen Abbrechen-Knopf und entsprechende Ereignisbehandlungsmechanismen, aber das ist wohl hier nicht weiter entscheidend.

Jetzt bin ich ja mal gespannt, ob jemand sagen kann, wodurch hier so gewisse Instabilitäten auftreten können...

Gruß,
  Mit Zitat antworten Zitat