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 |
Re: Aus DLL Button erstellen
Zitat:
|
Re: Aus DLL Button erstellen
Zitat:
|
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? |
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:
Quellcode aus der DLL:
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;
Delphi-Quellcode:
Danke schon mal!
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; |
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
|
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:
Beim Start des Programms schaut es für jedes Plugin über die Funktion "GetButtonCount" nach,
// 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; 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 |
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! |
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 |
Re: Aus DLL Button erstellen
Hallo!
Ich habs fast genau so wie du gemacht, nur gehts bei mir nicht. :gruebel: DLL:
Delphi-Quellcode:
Aufruf:
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.
Delphi-Quellcode:
ShareMem ist sowhol in der DLL (siehe oben) wie auch in der DPR der Aufrufsawendung.
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. Was passt hier nicht?! Grüße Faux |
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.
|
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. :(
|
Re: Aus DLL Button erstellen
Hast du denn in den Projekteigenschaften des Hauptprogramms und der DLL eingestellt, dass mit Laufzeitpackages kompiliert werden soll?
|
Re: Aus DLL Button erstellen
Zitat:
Daran lags. Jetzt funktionierts. :) Was genau macht diese Funktion?! Die OH bringt das nicht so ganz rüber. Grüße Faux |
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.
|
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 |
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. |
Re: Aus DLL Button erstellen
*hust*
Du meinst, ich soll meinen gesamten Delphi-Ordner mit in die Installation packen?! :shock: |
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 00:20 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