Title: How to really add a form to a DLL
Question: Adding a form to a DLL is actually quite simple. Depending on the type of form (modal or mode-less) you have to proceed differently. This article explains how it is done.
Update: the return value from the ShowTestFrom function was incorrect, so I've changed it here
Answer:
{ To add a form to a DLL you have to remember these things:
1. assign the calling programs Application.Handle to the DLL's Application.Handle
2. Write one or two exported functions that handles the interaction with the calling program
3. include sharemem as the first unit in the DLL's uses clause if the exported functions uses strings
4. if you are going to show a mode-less form, you should return a handle to your form in the "Show" function and require it as a parameter in the "Close" function
5. always create the form with the Application object as the Owner
6. restore the DLL's Application.Handle after closing the form
You don't have to do anything special to add a form to a DLL: just add the forms filename to the uses clause and Delphi will compile it right into the DLL.
Here's an example with both modal and mode-less invocation. The examples just return an integer value, but you could of course return just about anything:
}
library testDLL;
uses
myTestFrom, SysUtils, Controls;
var
OldApphandle:longint = 0;
{ these functions are used with the mode-less form: }
{ AppHandle is the *calling* applications Handle }
function ShowTestForm(AppHandle:integer):longint;
var F:TmyTestForm;
begin
{ save current handle unless it's already done }
if Application.Handle AppHandle then
OldAppHandle := Application.Handle;
{ assign new }
Application.Handle := AppHandle;
{ create and show form }
F := TmyTestForm.Create(Application);
F.Show;
Result := longint(F);
end;
{ the input value, Handle, must be the same value as returned by ShowTestForm }
function CloseTestForm(Handle:longint):integer;
var F:TmyTestForm;
begin
{ typecast back to TForm (some sanity checks here would not be bad...}
F := TmyTestForm(Handle);
Result := F.SomeIntValue;
F.Close;
F.Free;
{ restore previous handle }
Application.Handle := OldAppHandle;
end;
{ this function is used to show the form modally }
function ShowTestFormModal(AppHandle:integer):longint;
var F:TmyTestForm;
begin
OldAppHandle := Application.Handle;
try
Application.Handle := AppHandle;
F := TmyTestForm.Create(Application);
try
if F.ShowModal = mrOK then
Result := F.SomeIntValue
else
Result := -1;
finally
F.Free;
end;
finally
Application.Handle := OldAppHandle;
end;
end;
{ finally export the functions: }
exports ShowTestForm name 'ShowTestForm', CloseTestForm name 'CloseTestForm',
ShowTestFormModal name 'ShowTestFormModal';
begin
end.