![]() |
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 ![]()
Delphi-Quellcode:
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:
function DoGUIActions(FormHWND: HWND): ShortString; stdcall;
Delphi-Quellcode:
Nur leider erscheint der Button wider Erwarten nicht auf dem Formular :(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; Mit einem normalen TForm als Argument habe ich es auch schon versucht, sprich so:
Delphi-Quellcode:
Geht leider genau so wenig :( Beim ersten bekomme ich keine Fehlermeldung, beim zweiten jedoch eine Zugriffsverletzung.
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; 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! |
Re: Dll soll Control wärend Laufzeit auf Form erstellen
Zitat:
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. |
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; |
Re: Dll soll Control wärend Laufzeit auf Form erstellen
Zitat:
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; |
Re: Dll soll Control wärend Laufzeit auf Form erstellen
Wo ist das Problem, wenn ich 'n 32bit Wert übergebe? :gruebel:
|
Re: Dll soll Control wärend Laufzeit auf Form erstellen
Zitat:
Aber: Es behebt das ursprüngliche Problem nicht. |
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. |
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. |
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). |
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:
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.
//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; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:54 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 by Thomas Breitkreuz