Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Dll soll Control wärend Laufzeit auf Form erstellen (https://www.delphipraxis.net/103025-dll-soll-control-waerend-laufzeit-auf-form-erstellen.html)

MEDV 8. Nov 2007 15:42


Dll soll Control wärend Laufzeit auf Form erstellen
 
Hallo,
hier wieder das oft durchgekaute Thema "dynamische Controls". Doch diesmal ist es ein bisschen anders: Ich habe eine Hauptanwendung mit einem Formular & eine DLL, die erst wärend der Laufzeit eingelesen wird (siehe dieses Tutorial hier). Diese DLL beinhaltet eine Funktion
Delphi-Quellcode:
function DoGUIActions(FormHWND: HWND): ShortString; stdcall;
Wie man sicherlich erkennt wird von der "Hauptanwendung" das HWND vom Fenster an die DLL übergeben. Diese sollte nun einen einfachen Button auf eben diesem Formular erzeugen:
Delphi-Quellcode:
   
function DoGUIActions(FormHWND: HWND): ShortString; stdcall;
   var  Button: TButton;
   begin
      Button := TButton.CreateParented(FormHWND);
      With Button do begin
         Caption := 'Hallo';
         Name := 'cmdTest';
         Left := 10; Top := 10;
         Visible := True;

      end;
      Result := Button.Caption; // Wird als Kontrolle durch eine ShowMessage ausgegeben
   end;
Nur leider erscheint der Button wider Erwarten nicht auf dem Formular :(
Mit einem normalen TForm als Argument habe ich es auch schon versucht, sprich so:
Delphi-Quellcode:
   function DoGUIActions(Form: TForm): ShortString; stdcall;
   var  Button: TButton;
   begin
      Button := TButton.Create(Form);
      With Button do begin
         Caption := 'Hallo';
         Name := 'cmdTest';
         Left := 10; Top := 10;
         Visible := True;

      end;
      Result := Button.Caption;  
   end;
Geht leider genau so wenig :( Beim ersten bekomme ich keine Fehlermeldung, beim zweiten jedoch eine Zugriffsverletzung.
Kann mir jemand auf Anhieb sagen was ich falsch mache?
Ich habe auch schon nach API-Befehlen (da diese ja eigentlich ausschließlich mit HWND-Argumenten funktionieren) gegoogelt, mit denen man eben solche Controls erstellen kann, doch leider ohne Erfolg :(
Ich bin für jede Hilfe dankbar!

sirius 8. Nov 2007 15:54

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Zitat:

Geht leider genau so wenig Beim ersten bekomme ich keine Fehlermeldung, beim zweiten jedoch eine Zugriffsverletzung.
Das zweite geht nicht, da du hier kreuz und quer Objekte über DLL grenzen schiebst (siehe Sharemem).

Beim ersten weis ich nicht. Die WinAPIfunktion um einen Button zu erstellen ist
CreateWindowEx (oder CreateWindow)
Edit: Die Frage ist dann nur, wie du messages abfangen willst. Da müsstest du entweder deinen Button "subclassen" oder die NotifyMessages in deiner Form-WndProc mitlesen.

Nuclear-Ping 8. Nov 2007 23:39

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
1.) Keine Strings in DLL verwenden *schauder* ... Lieber PChar und schön mit GetMem Speicher dafür reservern ... wie im guten alten C. ^^ Zu ShareMem sag ich jetzt nix. Bin ich kein Fan von.

2.) Wie rufst du die Funktion auf? Ich würde das so machen (ungetestet):
Delphi-Quellcode:
Hauptprojekt:
var
  MyPChar: PChar;
begin
  MyPChar := DoGUIActions (Integer (Self));
  // ...
  FreeMem (MyPChar);
end;

DLL:
function DoGUIActions(ParentForm: Integer): PChar; stdcall;
var
  Button: TButton;
begin
  Button := TButton.Create(TForm (ParentForm));
  with Button do
    begin
      Parent := TForm (ParentForm); // << -- !!
      Caption := 'Hallo';
      Name := 'cmdTest';
      Left := 10;
      Top := 10;
      Visible := True;
    end;
  GetMem (Result, Length (Button.Caption));
  StrCopy (Result, PChar (Button.Caption));
end;

sirius 9. Nov 2007 07:43

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Zitat:

Zitat von Nuclear-Ping
1.) Keine Strings in DLL verwenden *schauder*

Er hat Shortstrings benutzt. Und solange ihm das reicht, ist dies bequemer.

Ich würde nur keine Objektzeiger an die DLL übergeben. Auch wenn du sie vorher in Integer castest, es sind immer noch die 32bit. Da ändert sich nix.


Edit: So gehts auch
Delphi-Quellcode:
procedure Do_xyz(handle:hwnd);
var wnd:hwnd;
begin
  wnd:=createwindow('BUTTON','Hallo',ws_visible or ws_child,10,10,100,60,
                      handle,0,hinstance,nil);
  setwindowlong(wnd,gwl_id,1); //1 oder irgendeine andere möglichst eindeutige Ziffer
end;

Nuclear-Ping 9. Nov 2007 13:57

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Wo ist das Problem, wenn ich 'n 32bit Wert übergebe? :gruebel:

sirius 9. Nov 2007 14:12

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Zitat:

Zitat von Nuclear-Ping
Wo ist das Problem, wenn ich 'n 32bit Wert übergebe? :gruebel:

Das ist kein Problem und völlig in Ordnung. Nur da kannst du auch den Zeiger (self) direkt übergeben. Ist ja letztlich dieselbe Zahl.
Aber: Es behebt das ursprüngliche Problem nicht.

Nuclear-Ping 9. Nov 2007 14:16

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Hm, speziell das hab ich noch nicht probiert.
Aber in einem Projekt hab ich MDI-Formulare in DLLs (BPL) ausgelagert und fast ähnlich erzeugt (nur Application statt Form) und das läuft super.

Muetze1 9. Nov 2007 15:55

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
BPL <-> DLL!

Eine BPL ist eine Sonderform der DLL und kümmert sich u.a. um die Typeninformationen etc und sind somit überhaupt nicht vergleichbar. Wenn die gleiches leisten/bieten würde, warum sollte dann Borland eine BPL einführen? Nur weil es bei deiner BPL ging, bedeutet dies noch lange nicht, dass es bei einer DLL genauso funktioniert.

MEDV 10. Nov 2007 10:17

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Danke für alle Vorschläge doch leider hat dies bisher alles nichts genützt :(
Meine Absicht war es auf diese Weise ein Pluginsystem zu Programmieren, doch der per CreateWindowEx erzeugte Button liegt zwar optisch auf dem Form, ist aber kein Element von Form1.Controls. Gibt es noch Möglichkeiten auf Aktionen des Buttons zu reagieren (OnClick..)?

//edit
Und wenn dieser Ansatz nicht funktionieren sollte werd ich das eben über XML klären, wo die DLL alle Änderungen an meinem Hauptformular einträgt und das dann geparst wird (ist eben leider nicht so schön frei).

sirius 10. Nov 2007 10:47

Re: Dll soll Control wärend Laufzeit auf Form erstellen
 
Also in Form1.controls registrieren geht definitiv nicht, denn dann knallt die VCL dir Exceptions um die Ohren. Wie gesagt, wenn du Sharemem benutzt dürfte es gehen, aber schön ist es nicht. Allerdings für ein Pluginsystem, was nur unter deinem Delphi geschrieben wird, wäre es vielleicht sogar mal praktisch.
(Du musst dazu irgendwie in DLL und Programm als erstes die Unit Sharmem einbinden und irgendeine DLL der finalen Exe mitgeben)
Dann kannst du IMHO so programmieren, als wäre die DLL eine Unit im Programm. (Und du kannst auch AnsiStrings verwenden ;-)


Wenn dir Sharemem (wie den meisten) auch nicht gefällt:
Mit createwindow bekommst du den Buttonclick als Message an das ParentWindow mit, das geht etwa so:
Delphi-Quellcode:
//alles im Hauptprogramm
type TForm1=class(TForm)
      ...
      procedure WMCommand(var msg:TMessage);message WM_COMMAND;
...

procedure WMCommand(var msg:TMessage);message WM_COMMAND;
begin
  inherited;
  if (msg.wparamhi=BN_clicked) then
  begin
    //in msg.wparamlo steht der identifier (also in dem Fall die 1, die wir oben angegeben haben)
    //in msg.lparam sollte das WindowHandle des Buttons sein (result aus createwindow)

  end;    
end;
Am besten ist du fertigst dir für diese PluginButtons eine eigene Liste der Windowhandles. Denen kannst du auch eine CloseMessage schicken, wenn sich dein Formular schließt.


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