Delphi-PRAXiS
Seite 1 von 2  1 2      

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


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:33 Uhr.
Seite 1 von 2  1 2      

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