Forms i DLL

Tags:    delphi
Skrevet af Bruger #270 @ 20.08.2001
Tilføj en Form til en DLL

Introduktion

Spørgsmålet "Hvordan viser man en form der ligger i en DLL?" popper op med jævne mellemrum i diverse nyhedsgrupper. Derfor har jeg besluttet at skrive denne artikel. At vise en form der ligger i en DLL, er en relativ simpel opgave, hvor hovedforskellen er den måde man opretter og nedlægger formen på.


Opret en ny DLL

Det første skridt er at oprette en ny DLL, der indeholder formen. For at gøre dette skal du følge de nedenstående punkter:

Start et nyt projekt med File|New DLL
Du har nu en tom DLL skabelon
Du skal oprette en ny form med File|New Form, som skal tilføjes projektet.
Formen tilføjes til projektet og gem formen under en sigende navn (fx. DllForm).
Tilføj den til projektet med Project|Add To Project.... I den dialogboks, der fremkommer vælger du den form du gemte før (DllForm.pas).
Nu har vi en simpel DLL fil, der indeholder en form, men der er endnu ingen procedure/funktion til at kalde DLL'en eller til at vise formen. Koden vi skal bruge for at gøre dette skal skrives i "hånden", hvilket er nærmere forklaret i det næste afsnit.

Skrive koden til DLL'en

DLL'en vil tilbyde to metoder, en procedure og en funktion, til at vise formen med. Den ene bruger Show og den anden ShowModal metoden til at vise formen med.
Den første procedure, der bruger Show således ud:
procedure ShowDllForm; stdcall;
begin
  if frmDllForm = nil then 
     frmDllForm := TfrmDllForm.Create(nil);
  frmDllForm.Show;
end;
Alt denne procedure gør er at oprette formen, ved at give en nil pointer med som parameter, siden vi ikke ved hvad der ejer formen. Stdcall-direktivet bliver brugt til at bestemme hvordan parametrene bliver givet til proceduren, så når den bliver kaldt skal vi huske at overholde den samme konvention. Det kaldes også kaldekonvention (calling convension).
Kaldekonvention sikrer også kompatibilitet med andre sprog, som fx C++.

For yderligere information om dette emne kig i online hjælpen, eller måske skriver jeg en artikel om det en dag... Situationen, hvor vi skal vise formen i modal tilstand er lidt anderledes, idet vi skal returnere resultatet af ShowModal metoden på vores form. Det følgende kode løser problemet:
function ShowDllFormModal: integer; stdcall;
begin
  if frmDllForm = nil then 
    frmDllForm := TfrmDllForm.Create(nil);
  result := frmDllForm.ShowModal;
end;
Den eneste forskel på denne kode og det tidligere viste eksempel er at vi bruger en funktion i stedet for procedure, for at vi kan returnere resultatet af kaldet til formens ShowModal metode - samt selvfølgelig at vi kalder ShowModal i stedet for Show.

Hvad du måske har lagt mærke til så opretter disse to eksempler en form, men nedlægger den aldrig, hvilket resulterer i spild af hukommelsesresurser (memory leak på godt dansk). Den nemmeste metode til at nedlægge en form er at benytte sig af formens OnClose event, for deri at sætte TCloseAction til caFree, hvilket betyder at alt hukommelse tilknyttet/ejet af formen bliver frigivet, når formen lukker. Det bliver alt sammen klaret ved at skrive følgende kode i formens OnClose event:
procedure TfrmDllForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
  frmDllForm := nil;
end;
Sidst men ikke mindst skal vi have de to respektive funktioner eksporteret fra DLL filen således de senere kan kaldes fra vores applikation. Det gør du ved at tilføje følgende kode i DPR filen:
exports
  ShowDllForm,
  ShowDllFormModal;
Vi er nu færdige med at lave DLL filen, så alt hvad der er at gøre et at bygge (Project|Build...) DLL filen samt at skrive en applikation, der kan kalde den.

Oprette en ny applikation

Det næste skridt et at oprette en ny applikation, som kalder DLL'en. For at oprette en ny applikation skal du følge de nedenstående punkter:

Start et nyt projekt med File|New Application
Tilføj to knapper til formen, en til at vise formen med og en til at vise den i modal tilstand.
Skift teksten på knapperne til noget sigende, og tilpas størrelsen på formen, hvis det er nødvendigt.

Nu har vi en simpel applikation, der ingenting kan så nu skal vi skrive koden til knapperne således så at udfører de ønskede funktioner.

Skrive koden til knapperne

Første skridt i forbindelse med at skrive koden, er at lave deklarationerne (interface delen) for den procedure og funktion, der skal kalde DLL'en. Dette kan i dette simple eksempel gøres i Interface sektionen af din unit1.pas :
procedure ShowForm; stdcall; external 'Project1dll.dll' name 'ShowDllForm';
function ShowFormModal: integer; stdcall; external 'Project1dll.dll' name 'ShowDllFormModal';
Skal der kaldes flere metoder på formen, kan man med fordel benytte en wrapper klasse omkring DLL'en.
Det eneste vi gør her er at erklære proceduren/funktionen som normalt, dog med den forskel er de er erklæret external (eksternt i forhold til applikationen) og at de findes I Project1dll.dll samt de hedder hhv. 'ShowDllForm' og 'ShowDllFormModal'. Igen bliver StdCall brugt som kaldekonvention fordi det var sådan proceduren/funktionen var erklæret i DLL filen, og fordi denne kaldekonventionen sikere at DLL'en så kan bruges fra andre programmer.
Funktionen og proceduren har samme funktionalitet, blot med den forskel at funktionen returnerer en integer.
Næste skridt er at kalde to procedurer (funktioner), det bliver gjort i de to knappers OnClick event. Koden for knapperne skal de således ud:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShowFormModal;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  ShowForm;
End
Ingen magi, bare simpel kode, det er den slags jeg elsker Delphi for :) - Alt der sker her er at vi kalder metoderne i DLL filen afhængigt af hvilken knap, der er trykket på.

Konklusion

I denne artikel har jeg demonstreret en simpel måde til at bruge forms i en DLL fil. Det er yderst brugbart når du ønsker at dele en eller flere forme mellem flere applikationer, uden at replicere koden. Hvis man linker dynamisk til DLL filen, altså på runtime, er det en nem måde at skabe såkaldte plugins (igen et godt dansk ord) til sine applikationer (se artiklen Dynamisk læsning af DLL). Du kan hente fuld source kode her (2,5 kb). Koden har ingen praktisk anvendelse, men tjener udelukkende det formål at vise hvordan eksemplet ovenfor virker.


Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (0)

Du skal være logget ind for at skrive en kommentar.
t