Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Aus DLL Button erstellen (https://www.delphipraxis.net/75063-aus-dll-button-erstellen.html)

Thanatos81 13. Aug 2006 18:43


Aus DLL Button erstellen
 
Hallo zusammen!

Wir testen hier gerade ein wenig mit DLLs als PlugIns zur Programmerweiterung / modularen Programmaufbau. Das klappt soweit auch schon ganz gut, bis auf eine Kleinigkeit... Und zwar versuchen wir aus einer DLL heraus einen Button auf dem Mainform zu erzeugen.

Dabei bekommen wir allerdings die Fehlermeldung "TFont kann nicht TFont zugewiesen werden." Hat jemand eine Idee, woran das liegen könnte?

Schönen Gruß,
Thomas

Balu der Bär 13. Aug 2006 18:50

Re: Aus DLL Button erstellen
 
Zitat:

Zitat von Thanatos81
Dabei bekommen wir allerdings die Fehlermeldung "TFont kann nicht TFont zugewiesen werden." Hat jemand eine Idee, woran das liegen könnte?

Ohne entsprechende Quellcodezeilen wird das schwer. ;)

Bernhard Geyer 13. Aug 2006 18:56

Re: Aus DLL Button erstellen
 
Zitat:

Zitat von Balu der Bär
Ohne entsprechende Quellcodezeilen wird das schwer. ;)

Ist nicht schwer. Wenn Du VCL-Objekte in der DLL ereugst und in der Exe anzeigen lassen willst aber keine Laufzeitpackages verwendst kommt dieser Fehler ziemlich zu erst, da TObject in Exe <> TObject in DLL.

Thanatos81 14. Aug 2006 08:04

Re: Aus DLL Button erstellen
 
DAnke euch beiden erstmal.

@Bernhard
Laufzeitpackages wären nicht unbedingt unsere Wahl. Würde es denn mit PlugIns auf .bpl-Basis funktionieren?

Thanatos81 14. Aug 2006 09:53

Re: Aus DLL Button erstellen
 
Da für .bpl-PlugIns anscheinend die gleiche Beschränkung besteht, haben wir es jetzt doch mit Laufzeitpackages und ner DLL gemacht. Der Button ist da, allerdings bekommen wir noch eine ungültige Zeigeroperation.

Quellcode aus der EXE:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var DllPrg : procedure (Parent : TForm); stdcall;
    Handle : cardinal;
begin
  Handle := LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+'project2.dll'));
  if Handle <> 0 then
    begin
      @DllPrg := GetProcAddress(Handle, 'BtnErzeugen');
      if @DllPrg <> nil then
        begin
          DllPrg(Form1); //<--- hier kommt die ungültige Zeigeroperation
        end;
    end;
end;
Quellcode aus der DLL:
Delphi-Quellcode:
procedure BtnErzeugen(parent : Tform); stdcall;
var btn : TButton;
begin
  btn       := TButton.create(parent);
  btn.parent := parent;
  btn.name  := 'btn1';
  btn.left  := 100;
  btn.top   := 100;
end;
Danke schon mal!

Bernhard Geyer 14. Aug 2006 10:25

Re: Aus DLL Button erstellen
 
Ich tipp mal darauf das die Variable Form1 nil ist.
Ersetze es durch folgendes:

Delphi-Quellcode:
DllPrg(self); //<--- hier kommt die ungültige Zeigeroperation

pszopp 14. Aug 2006 12:34

Re: Aus DLL Button erstellen
 
Hallo Thanatos81,

ich habe in einem meiner Programme sowas schonmal realisiert.
Dabei hat jedes Plugin bestimmte Prozeduren/Funktionen:

Delphi-Quellcode:
  // Liefert die Anzahl der Buttons, die das Plugin braucht.
  Function GetButtonCount : Integer; STDCALL;
  // Liefert die Caption eines Buttons
  Function GetButtonCaption(aIndex : Integer) : PChar; STDCALL;
  // Informiert das Plugin über den Klick auf einen Button.
  Procedure ButtonClicked(aIndex : Integer); STDCALL;
Beim Start des Programms schaut es für jedes Plugin über die Funktion "GetButtonCount" nach,
wieviele Buttons das aktuelle Plugin brauchen.
Im Programm werden dann die Buttons erzeugt, und die Caption jedes Buttons wird im passenden Plugin
über die Methode "GetButtonCaption" erfragt. aIndex gibt dabei an, um welchen Button des Plugins es sich handelt.
Klickt der Benutzer auf einen Button, sucht sich das Programm anhand des Buttons das zutreffende Plugin aus,
und ruft dort die Methode "ButtonClicked" mit passendem Index auf.

Diese Lösung hat den Vorteil, dass die Buttons komplett vom Programm verwaltet werden und nicht von der Dll.
Sie ist dafür evtl etwas aufwendiger zu programmieren.


Viele Grüße,
pszopp

Thanatos81 14. Aug 2006 14:39

Re: Aus DLL Button erstellen
 
@pszopp
Mir würde die von dir vorgeschlagene Vorgehensweise auch besser gefallen. Aber mein Kollege möchte sich alle Möglichkeiten offen halten. Also z.B. auch einen Indy-TCP-Server oder ein StringGrid aus der DLL herauserzeugen können ohne jedesmal das Interface in der Hauptanwendung anzupassen...

@Bernhard
Knapp daneben ;-) Form1 war nicht nil, sondern es fehlte ein simples ShareMem in der .dpr der Hauptanwendung :wall:

Jetzt funktioniert das ganze aber :) Danke euch allen nochmal!

Thanatos81 15. Aug 2006 06:59

Re: Aus DLL Button erstellen
 
Liste der Anhänge anzeigen (Anzahl: 1)
So, damit andere die so etwas brauchen nicht lange suchen und fragen müssen, mal ein kleines Demoprojekt im Anhang. Zu beachten ist, das beide Projekte wie von Bernhard erwähnt mit Laufzeit-Packages compiliert werden müssen.

Schönen Gruß,
Thomas

faux 15. Aug 2006 10:28

Re: Aus DLL Button erstellen
 
Hallo!

Ich habs fast genau so wie du gemacht, nur gehts bei mir nicht. :gruebel:
DLL:
Delphi-Quellcode:
library Project1;

uses
  ShareMem, SysUtils, Controls, Classes, ExtCtrls;

{$R *.res}

var
  Panel: TPanel;

procedure CreatePlugin(Owner:TComponent; Parent: TWinControl); stdcall; export;
begin
  Panel := TPanel.Create(Owner);
  Panel.Parent := Parent;
  Panel.Align := alClient;
end;

procedure DestroyPlugin; stdcall;
begin
  Panel.Free;
end;

exports
  CreatePlugin, DestroyPlugin;

begin

end.
Aufruf:
Delphi-Quellcode:
unit Unit3;

interface

uses
  Classes, Controls, Windows;

procedure CreatePlugin(FileName: string; Owner:TComponent; Parent: TWinControl);

implementation

procedure CreatePlugin(FileName: string; Owner:TComponent; Parent: TWinControl);
var
  CreatePluginProc: procedure(Owner:TComponent; Parent: TWinControl); stdcall;
  Handle: THandle;
begin
  Handle := LoadLibrary(PChar(FileName));
  if Handle <> 0 then
  begin
    @CreatePluginProc := GetProcAddress(Handle, 'CreatePlugin');
    if @CreatePluginProc <> nil then
    begin
      CreatePluginProc(Owner, Parent);
    end;
    FreeLibrary(Handle);
  end;
end;

end.
ShareMem ist sowhol in der DLL (siehe oben) wie auch in der DPR der Aufrufsawendung.

Was passt hier nicht?!

Grüße
Faux

Thanatos81 15. Aug 2006 10:43

Re: Aus DLL Button erstellen
 
Versuch mal das FreeLibrary weg zu lassen. Bzw. ordentlicher wäre es wohl, das Handle global zu deklarieren und FreeLibrary nach DestroyPlugin aufzurufen.

faux 15. Aug 2006 10:44

Re: Aus DLL Button erstellen
 
Naja, jetzt ists noch immer der selbe Fehler (TFont nicht auf TFont...), aber nicht in der FreeLibrary-Zeile, sondern im Prozeduraufruf. :(

Thanatos81 15. Aug 2006 10:49

Re: Aus DLL Button erstellen
 
Hast du denn in den Projekteigenschaften des Hauptprogramms und der DLL eingestellt, dass mit Laufzeitpackages kompiliert werden soll?

faux 15. Aug 2006 10:55

Re: Aus DLL Button erstellen
 
Zitat:

Zitat von Thanatos81
Hast du denn in den Projekteigenschaften des Hauptprogramms und der DLL eingestellt, dass mit Laufzeitpackages kompiliert werden soll?

Nein hab ich nicht. :oops:
Daran lags. Jetzt funktionierts. :)

Was genau macht diese Funktion?! Die OH bringt das nicht so ganz rüber.

Grüße
Faux

Thanatos81 15. Aug 2006 11:03

Re: Aus DLL Button erstellen
 
Normalerweise werden die benötigten Komponenten statisch mit in die Echse kompiliert (z.B. TButton). Mit Laufzeitpackages werden die Komponenten dynamisch geladen. Vorteil des dynamischen Ladens: Die Echse wird wesentlich kleiner und man ist LGPL konform wie mir hier vor kurzem jemand erklärt hat ;-) Der große Nachteil ist, dass beim Zielrechner auch die bpl-Dateien vorhanden sein müssen und im Suchpfad liegen müssen.

faux 15. Aug 2006 11:22

Re: Aus DLL Button erstellen
 
Ja, das hab ichauch gemerkt, dass die EXE um EINIGES kleiner wird. ;)
Um Welche BPL-Dateien handelt es sich hier? Wie bekommt die der Zielrechner?
Da gibts ja auch noch ein Edit-Feld wo mein Eintragen kann, welche Laufzeitpackages exportiert werden sollen, welche sind denn notwenig, dass das Vorhaben funktioniert?

Grüße
Faux

Thanatos81 15. Aug 2006 12:10

Re: Aus DLL Button erstellen
 
Das kommt auf deine Komponenten an, welche du benutzt. Aber pauschal kann man die mitgeben, die im Edit-Feld aufgelistet sind.

Die findest du normalerweise unter C:\Programme\Boralnd\Delphi7\Bin. Bzw. statt Delphi7 deine Delphi-Version. Ich würde die mit in einen Installer packen. TuneUp zB speichert die im eigenen Porgrammverzeichniss.

Welche exportiert werden müssen, kann ich dir auch nicht sagen. Haben ja selber gestern erst diese Kombi (dll + Hauptanwendung + Laufzeitpackages) in Angriff genommen.

faux 15. Aug 2006 12:28

Re: Aus DLL Button erstellen
 
*hust*
Du meinst, ich soll meinen gesamten Delphi-Ordner mit in die Installation packen?! :shock:

Thanatos81 15. Aug 2006 12:46

Re: Aus DLL Button erstellen
 
Nee, nur die .bpl-Dateien. Und davon auch nur die, die in dem Edit-Feld aufgeführt sind. Und da kannst du auch testen, ob du alle davon benötigst. Für solche Versuche kann ich nur ne VM wie VMWare oder VirtualPC empfehlen ;-) Da kann man sich schön immer ein "suaberes" System behalten.


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