Form in DLL: Application.Handle - Delphi

This is a discussion on Form in DLL: Application.Handle - Delphi ; Hi all, From D2007 help file (ms-help://borland.bds5/delphivclwin32/Forms_TApplication_Handle.html) it says: "Note: When writing a DLL that uses VCL forms, assign the window handle of the host EXE's main window to the DLL's Application.HandleApplication->Handle property. This makes the DLL's form part of ...

+ Reply to Thread
Results 1 to 4 of 4

Form in DLL: Application.Handle

  1. Default Form in DLL: Application.Handle

    Hi all,
    From D2007 help file
    (ms-help://borland.bds5/delphivclwin32/Forms_TApplication_Handle.html)
    it says:
    "Note: When writing a DLL that uses VCL forms, assign the window handle
    of the host EXE's main window to the DLL's
    Application.HandleApplication->Handle property. This makes the DLL's
    form part of the host application. Never assign to the Handle property
    in an EXE."

    How relevant is this information?
    I have a form in a DLL and it works OK without ever changing the DLL's
    Application.Handle. I mean I can show the form both modally and
    modal-less, the form and controls on it responding to user inputs, etc.


    My second question is: How to embed controls from DLL into an EXE's
    controls? Let's say my DLL looks like:

    library DLLProject;

    uses SimpleShareMem, SysUtils, Controls, Forms, StdCtrls;

    procedure AddButton(f: TForm); stdcall;
    var
    b: TButton;
    begin
    b:=TButton.Create(f);
    b.ParentFont:=false;
    b.Parent:=f;
    b.SetBounds(15, 15, 100, 25);
    b.Caption:='DLL Button';
    b.Show();
    end;

    exports AddButton;

    begin
    end.


    I use the same memory manager for both the DLL and EXE. And in my EXE's
    Form1 I have something like:

    unit Unit1;

    interface

    uses
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
    Forms, Dialogs, StdCtrls;

    type
    TForm1 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    private
    DLLHandle: HMODULE;
    public
    { Public declarations }
    end;

    var
    Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    DLLHandle:=LoadLibrary(PChar('DLLProject.dll'));
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
    FreeLibrary(DLLHandle);
    end;

    procedure TForm1.Button1Click(Sender: TObject);
    var
    p: procedure(f: TForm); stdcall;
    begin
    p:=GetProcAddress(DLLHandle, PChar('AddButton'));
    p(Self);

    // Create another botton to trick DLL button to show
    with TButton.Create(Self) do begin
    Parent:=Self;
    SetBounds(100, 100, 100, 25);
    Caption:='EXE Button';
    Show();
    end;
    end;

    end.



    In Button1Click, if I commented out the lines after "// Create another
    botton to trick DLL button to show" then the button from DLL won't show
    at all.

    But even after I can show the button from DLL, however the button from
    DLL is not responding to user's interaction etc (I've tried more
    complicated things: putting event-handler for DLL button's OnClick,
    setting the DLL's Application.Handle from the DLL, etc.)


    Regards,
    Edy

  2. Default Re: Form in DLL: Application.Handle


    "Edy" <edy.jordan@gmail.com> wrote in message
    news:483e4ca8$1@newsgroups.borland.com...

    > How relevant is this information?


    It is still relevant.

    > How to embed controls from DLL into an EXE's controls?


    I would not recommend doing that from a raw DLL. In order to use the VCL
    across the DLL boundary like you are attempting, you need to make a Package
    instead of a DLL. Then, in your EXE code, use Load/UnloadPackage() instead
    of Load/FreeLibrary().


    Gambit



  3. Default Re: Form in DLL: Application.Handle

    Edy wrote:

    > Hi all,
    > From D2007 help file
    > (ms-help://borland.bds5/delphivclwin32/Forms_TApplication_Handle.html)
    > it says: "Note: When writing a DLL that uses VCL forms, assign the
    > window handle of the host EXE's main window to the DLL's
    > Application.HandleApplication->Handle property. This makes the DLL's
    > form part of the host application. Never assign to the Handle
    > property in an EXE."
    >
    > How relevant is this information?


    What the manipulation described achieves is to make sure the DLL forms
    stay above the host applications main window in Z order.
    If you don't do it the host apps main form can cover the DLL forms
    (which may be what you want). A side effect of not doing the described
    manipulation is that the DLL forms will get their own taskbar button
    since the have no API owner in a DLL by default (since
    Application.Handle is 0 in a DLL).

    > My second question is: How to embed controls from DLL into an EXE's
    > controls? Let's say my DLL looks like:


    You can only achieve this reliably by building host application and DLL
    with run-time packages (better use a package instead of a DLL, unless
    you need to use it from a non-Delphi host as well). Without that VCl
    controls from the DLL will not be recognized as VCL controls by the
    host application and its message loop. You need the standard packages
    anyway if you want to transfer Delphi objects to the DLL, like in your
    example. Without them TForm would be a different class in host exe and
    DLL. If you use packages you don't need Sharemem, by the way, since you
    share the memory manager via the rtl package.


    --
    Peter Below (TeamB)
    Don't be a vampire (http://slash7.com/pages/vampires),
    use the newsgroup archives :
    http://www.tamaracka.com/search.htm
    http://groups.google.com

  4. Default Re: Form in DLL: Application.Handle

    Peter Below (TeamB) wrote:
    > What the manipulation described achieves is to make sure the DLL forms
    > stay above the host applications main window in Z order.
    > If you don't do it the host apps main form can cover the DLL forms
    > (which may be what you want). A side effect of not doing the described
    > manipulation is that the DLL forms will get their own taskbar button
    > since the have no API owner in a DLL by default (since
    > Application.Handle is 0 in a DLL).


    Ahh... I see. Thanks a lot, Peter


    > You can only achieve this reliably by building host application and DLL
    > with run-time packages (better use a package instead of a DLL, unless
    > you need to use it from a non-Delphi host as well). Without that VCl
    > controls from the DLL will not be recognized as VCL controls by the
    > host application and its message loop. You need the standard packages
    > anyway if you want to transfer Delphi objects to the DLL, like in your
    > example. Without them TForm would be a different class in host exe and
    > DLL. If you use packages you don't need Sharemem, by the way, since you
    > share the memory manager via the rtl package.


    I know ideally I should use Delphi Package instead of DLL. I was
    pursuing this avenue before; however the projects I inherited here so
    "spaghetti" and even the spaghetti is getting dry and very crackling
    now... very hard to untie them (time, cost & resources constraints, etc).
    There are way too many circular units referencing, etc. After trying to
    develop a package-based framework for the projects, finally I think it's
    just to risky that there could be more problems waiting ahead with
    package based libraries.


    Kind Regards,
    Edy

+ Reply to Thread