I was recently asked how to display a form in an application that is contained in a dll. This is a fairly simple process with main difference being how the form is created and destroyed.
The first step in this project is to create the DLL that will contain the form. To do this follow these steps:
We now have a simple DLL which contains a form but at present there is no to call the DLL or display the form. The code needed to do this will have to be written manually, as will be explained in the next section.
In this example I will provide two methods (one procedure and one function) for displaying the form, one to display it using the Show method and one to display it using the ShowModal method.
The first procedure to just show the Form is written like this:
procedure ShowDllForm;stdcall; begin frmDllForm :=TfrmDllForm.Create(nil); frmDllForm.Show; end;
All we are doing in this procedure is creating the form, passing nil as a parameter as we do not know what owns the form. We then Show the form using its standard Show method. The stdcall directive is used to state how parameters are passed to the procedure, when called it must be called in the same way. For further information on calling conventions look in the online help ,or maybe wait for a later article ;-).
To show the form modally is slightly different as we need to return the modal result. The code to do this is as follows:
function ShowDllFormModal:integer;stdcall; begin frmDllForm :=TfrmDllForm.Create(nil); Result := frmDllForm.ShowModal; end;
The only difference between this code and the previous example is that we are using a function instead of a procedure so that we can return the modal result of the form, and we are calling the ShowModal method instead of Show.
One thing you have noticed in these examples is that we are creating the form but never destroying it, which would result in our application wasting resources (leaking memory). The easiest way to destroy the Form is to do this by using its OnClose event, and setting its TCloseAction to caFree (i.e. all memory associated with form is freed when the form is closed). This done using the following code in the OnClose event of the form:
procedure TfrmDllForm.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := caFree; end;
Finally in the DLL we need to export the functions so that they can be called by our application. This is done by adding the following code to the DPR file:
Exports ShowDllForm, ShowDllFormModal;
We have now finished writing the DLL so just need to build it and get on with writing the application that will call it.
To create the application we need to perform the following steps:
We now have a simple application that does nothing so all that needs doing now is to add the code for the buttons to perform their required functions.
The first stage in writing the code is to write the declarations for the procedure and function that we will be calling in the DLL. This is done before the implementation section of the pas file that the function will be called in, like this:
procedure ShowForm;stdcall; external 'Project1dll.dll' name 'ShowDllForm'; function ShowFormModal:integer;stdcall; external 'Project1dll.dll' name 'ShowDllFormModal';
For the first declaration all we are doing is declaring a procedure as we would normally and then saying that the function is external (to the application) and can be found in Project1dll.dll and in the DLL it is called ShowDllForm. Again StdCall is used as this is how the procedure was declared in the DLL. The function declaration works exactly the same way except it has a return type of integer.
Next we need to call the two procedures (functions) this is done in the OnClick events of the buttons that we created earlier. The code needed for the buttons is thus:
procedure TForm1.Button1Click(Sender: TObject); begin ShowFormModal; end; procedure TForm1.Button2Click(Sender: TObject); begin ShowForm; end;
All we are doing here is calling the procedures in the DLL depending on which button is pressed.
This is a very simple demonstration of how to use forms in a DLL. It is useful when you wish to share forms amongst applications without sharing the code beneath them. Also when DLL's are used dynamically (i.e. linked in at run time) this is a powerful way of adding new features to an application.
You can download the source code for this application from here, it contains only the source code (to save space) so you will have to build both projects to run the application.