Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   wie kommt man von TApplication nach TForm1 ? (https://www.delphipraxis.net/213617-wie-kommt-man-von-tapplication-nach-tform1.html)

paule32.jk 27. Aug 2023 12:56

wie kommt man von TApplication nach TForm1 ?
 
Hallo,

in einer DLL kann ich die Host-Anwendung mittels TApplication ein paar Informationen
herauspicken.
Darunter gehört auch "MainForm: TForm"
Wie komme ich aber in einer DLL, die als Plugin dient auf die eigentliche MainForm,
wenn diese "TForm1" als Sub-Klasse hat, sprich die Host-Anwendung-ExE die Klasse TForm1
zur Verfügung stellt ?

Ich kann ja nicht davon ausgehen, das da nun unbedingt "Form1" als Parameter übergeben
werden kann ?

Anmerkung:
Ich sehe gerade... TApplication stellt auch eine "Controls" Eigenschaft zur Verfügung.
Damit könnte ich quasi nach einen Control-Element in der Host-Anwendung suchen, und wenn
das nicht gefunden wurde - Fehlermeldung.

Däs iss lustig: Delphi ruft DLL ruft Delphi.

Naja, einfacher gehts ja fast nett.

Delphi.Narium 27. Aug 2023 13:13

AW: wie kommt man von TApplication nach TForm1 ?
 
Kein Ahnung, was Du genau meinst.

TApplication.MainForm ist das Hauptformuler der Anwendung.

Gib dem Hauptformular Deiner Anwendung einen "vernünftigen" Namen, z. B. "fmMain", dann sollte TApplication.MainForm.Name = fmMain sein und Du kannst überall das Hauptformular mit dem Namen "fmMain" ansprechen.

Oder sowas (per Cast)?
Delphi-Quellcode:
TForm1(Application.MainForm).Caption := 'Ich bin das Hauptformular';


Oder sowas?
Delphi-Quellcode:
var
  fm : TForm1;
begin
  if Application.MainForm is TForm1 then begin
    fm := TForm1(Application.MainForm);
  end else begin
    // Sinnvolle Fehlerbehandlung statt der Meldung einbauen:
    ShowMessage('Das Hauptformular der Anwendung ist vom falschen Typ.');
  end;
end;

jaenicke 27. Aug 2023 13:14

AW: wie kommt man von TApplication nach TForm1 ?
 
Du musst alles in Interfaces und einfache Typen verpacken, was die DLL machen könne
soll, z.B. ein Interface IFrontendGui oder so. Direkte Zugriffe auf Objekte sind nicht erlaubt.

Hintergrund ist, dass die DLL einen eigenen Speichermanager hat. Das macht sonst Probleme.

Außerdem funktioniert es zwar mit genau der gleichen Delphiversion unter Umständen, aber mit anderen Sprachen oder anderen Delphiversionen dann gar nicht mehr.

paule32.jk 27. Aug 2023 13:28

AW: wie kommt man von TApplication nach TForm1 ?
 
Hallo @Delphi.Narium

Dein Lösungsansatz ist dadurch limitiert, da die DLL doch die Struktur der TForm1
nicht kennen kann.
Es ist gefühlsmäßig bei mir so, dass das Delphi von Haus aus macht, also COM+, weil:
es wird in TApplication Object die Eigenschaft "Components" angeboten.

Darüber könnte man doch iterrieren, und prüfen, ob ein bestimmtes Control/Component
vorhanden ist: Delphi calls DLL calls Delphi.

Ich habe das jetzt erfolgreich umsetzen können (entweder mal auf mein git Account schauen)
oder hier ein kleines Snippet:
Delphi-Quellcode:
unit code;

interface

uses
  Forms, Dialogs, Controls, Classes, SysUtils;

type
  TPluginItemObject = class(TObject)
  private
    FValueA: Integer;
  public
    property ValueA: Integer read FValueA write FValueA;
  end;

  TPluginCollection = class(TCollection)
  private
    FItemCount: Integer;

    function GetItemObject(AIndex: Integer): TPluginItemObject;
    function GetItemString(AName: String): TPluginItemObject;

    function GetItemCount: Integer;
  public
    function Add(AName: String): TPluginItemObject;

    constructor Create;
    destructor Destroy; override;

    property Objects[AIndex: Integer]: TPluginItemObject read GetItemObject;
    property Strings[AName: String]:  TPluginItemObject read GetItemString;

    property Count: Integer read GetItemCount;
  end;

  TPluginInterface = class(TObject)
  private
    FFileVersion   : String;
    FFileAuthor    : String;
    FFileDescription: String;

    function GetVersion: String;
    function GetAuthor: String;
    function GetDescription: String;

  public
    constructor Create;
    destructor Destroy; override;

  public
    property Description: String read FFileDescription;
    property Author: String read FFileAuthor;
    property Version: String read FFileVersion;
  end;


function RegisterPlugin(app: TApplication): Boolean; stdcall; export;
exports
  RegisterPlugin;

implementation

constructor TPluginCollection.Create;
begin
  FItemCount := -1;
end;
destructor TPluginCollection.Destroy;
begin
  inherited Destroy;
end;

function TPluginCollection.Add(AName: String): TPluginItemObject;
var
  plugin: TPluginItemObject;
begin
  plugin := TPluginItemObject(inherited Add);
  result := plugin;
end;

function TPluginCollection.GetItemObject(AIndex: Integer): TPluginItemObject;
begin
  result := TPluginItemObject(inherited Add);
end;

function TPluginCollection.GetItemString(AName: String): TPluginItemObject;
begin
  result := TPluginItemObject(inherited Add);
end;

function TPluginCollection.GetItemCount: Integer;
begin
  result := FItemCount;
end;

constructor TPluginInterface.Create;
begin
  inherited Create;
  FFileVersion := '1.0.0';
  FFileDescription := 'Standard Controls';
  FFileAuthor := 'Jens Kallup - paule32';
end;
destructor TPluginInterface.Destroy;
begin
  inherited Destroy;
end;

function TPluginInterface.GetVersion: String;
begin
  result := FFileVersion;
end;

function TPluginInterface.GetAuthor: String;
begin
  result := FFileAuthor;
end;

function TPluginInterface.GetDescription: String;
begin
  result := FFileDescription;
end;

function RegisterPlugin(app: TApplication): Boolean; stdcall; export;
var
  C: TPluginInterface;
  T: TControl;
begin
  try
    try
      if LowerCase(ExtractFileName(app.ExeName)) <> 'editor.exe' then
      raise Exception.Create('Host-Application does not match file name');

      if app.ComponentCount < 0 then
      raise Exception.Create('Host-Application is empty.');

      ShowMessage(app.Title);
      C := TPluginInterface.Create;
      ShowMessage(C.GetVersion);
      FreeAndNil(C);
    except
      on E: Exception do
      begin
        ShowMessage('Error:' +
        #10 + 'ClassName: ' + E.ClassName +
        #10 + 'Message : ' + E.Message);
        result := false;
        exit;
      end;
    end;
  finally
  end;
  result := true;
end;
selbst EH ist in der DLL möglich - hätte ich nicht gedacht...
aber schau mal RegisterPlugin genauer an, das kommt fast ohne Cast zu TForm1 aus.

jaenicke 27. Aug 2023 13:37

AW: wie kommt man von TApplication nach TForm1 ?
 
Zitat:

Zitat von paule32.jk (Beitrag 1526154)
aber schau mal RegisterPlugin genauer an, das kommt fast ohne Cast zu TForm1 aus.

Enthält aber fälschlicherweise eine Objektreferenz auf TApplication. Das klappt nur, wenn du den gleichen Compiler verwendest und mit ein paar Einschränkungen. Deshalb ist es für ein Pluginsystem absolut ungeeignet.

Erstelle doch z.B. einfach ein Interface IHostApplication und ein IPlugin. Das Hostinterface gibst du dann der DLL und diese gibt dir das Plugin-Interface.

paule32.jk 27. Aug 2023 13:51

AW: wie kommt man von TApplication nach TForm1 ?
 
dann ist die richtigerweise Strategie mit folgenden Code:

DLL
EXE

???

jaenicke 27. Aug 2023 14:15

AW: wie kommt man von TApplication nach TForm1 ?
 
Delphi-Quellcode:
function RegisterPlugin(AHostApp: IHostApplication): IPlugin; stdcall; export;
begin
  Result := TPlugin.Create;
  ...
end;

himitsu 27. Aug 2023 17:48

AW: wie kommt man von TApplication nach TForm1 ?
 
Wenn es eine getrennte DLL ist, dann hat die DLL ihr eigenes Application Delphi-Referenz durchsuchenScreen, bzw. ihre eigene RTL/VCL/... und die EXE und andere DLLs haben auch ihr Eigenes und du kommst mit deinem Application Delphi-Referenz durchsuchenScreen nirgendwo drauf.

Außer man arbeitet z.B. mit Laufzeitpackages, wo DLL und EXE eine gemeinsame RTL/VCL/... nutzen.

QuickAndDirty 28. Aug 2023 11:10

AW: wie kommt man von TApplication nach TForm1 ?
 
Man kann ein Interface das RTTI-zugriffs-methoden exposed an die DLL schicken... Dann ist die fast Anwendung für das Plugin zugreifbar oder ?

jaenicke 28. Aug 2023 11:31

AW: wie kommt man von TApplication nach TForm1 ?
 
Wenn man die Anwendung selbst auf Interfaces aufbaut, kann man diese auch direkt in DLLs usw. nutzen. Das wäre der von mir präferierte Weg.


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