Forms i DLLer

Tags:    delphi
Skrevet af Bruger #123 @ 17.06.2001
Indledning

I denne artikel vil jeg beskrive hvordan man laver en DLL som indeholder en open file dialog. Denne dialog kan selvfølgelig erstattes af en hvilken som helst slags form, og tjener kun til formål at vise fordan man bruger en form der er placeret i en DLL uden at denne form får sin egen bjælke i processlinien.

Det efterfølgende er kun testet under Windows NT 4.0 og Windows 98, men det burde virker under alle 32-bit udgaver af Windows.

Starten

Når man laver en DLL foregår det nogenlunde som når man laver et almindeligt program, dog med enkelte forskelle. Når man vil lave en DLL går man i Delphi ind på File|New ...
Dette bringer New Items dialogen frem og her vælger man så DLL. I modsætning til et program får man kun .DPR filen af se i DLL'en til at starte med. Denne anvendes nemlig anderledes i en DLL. For det første vil man bemærke at det første keyword er Library istedet for det sædvanelige Program.

Man kan så begynde at kode direkte i .DPR filen, eller man kan tilføje f.eks. en form. Det vil vi gøre. Projektet består nu af tre filer :
  • Project1.dll
    • Unit1.pas
    • Form1.dfm
Vi kan så fylde nogle komponenter på vores form. Lad os sætte følgende på :
  • En TDriveComboBox
  • En TDirectoryListBox
  • En TFilterComboBox
  • En TFileListBox
  • To TButtons
Så ser vores form sådan her ud :
Eksempel form

Egenskaber eller properties

Der er lige nogle properties som skal sættes på de forskellige komponenter. Ligeledes skal vi også lige givet dem nogen sigende navne, så det er nemmere at finde rundt.

Tbutton1 :
  • Name : btnOk
  • Caption : &Ok
  • ModalResult : mrOk
TButton2 :
  • Name : btnCancel
  • Caption : &Afbryd
  • ModalResult : mrCancel
TFilesListBox :
  • Name : lbxFiles
TFilterComboBox :
  • Name : cmbFilter
  • FileList : lbxFiles
  • Vi kan også vælge at tilføje flere filter typer end *.*, men det vil vi ikke gøre nu.
TDirectoryListBox :
  • Name : lbxDirectories
  • FileList : lbxFiles
TDriveComboBox :
  • Name : cmbDrives
  • DirList : lbxDirectories
Så er vi klar til at kode.

Koden

Vi skal have tilføjet en variabel til Private delen af vores form definition.
FFilNavn : String;
Desuden skal vi have tilføjet en property til Public delen af vores form definition.
Property FilNavn : String read FFilNavn;
Vi skal have tilføjet en OnClick event på vores Ok knap. Denne ser sådan ud :
procedure Tform1.btnOkClick(Sender: TObject);
begin
  if lbxFiles.ItemIndex <> -1 then
    FFilNavn := lbxFiles.FileName;
end;
Vi skal have tilføjet en global variabel, efterfølgende skal placeres lige over implementation :
Var
  DllApp : TApplication
Endelig skal vi have lavet den operation som tillade programmer at kalde vores fil dialog.
Function ShowFiles(MainApp : TApplication) : String; stdcall; 
Begin
  if Assigned(Application) then  // er Application oprettet
  begin
    DllApp := Application;       // lav en kopi af Application og
    Application := MainApp;      // Tildel MainApp til Application
  end;                           // Dette er for at sikre at det er
                                 // programmet (.EXE) som er ejer af
                                 // vores fil dialog.

  form1 := TForm1.Create(Application.MainForm); // Opret fil dialogen
  if form1.ShowModal = mrOk then         // Hvis der trykkes på Ok
    Result := form1.FilNavn              // Returneres det valgte filnavn
  else                                   // Ellers
    Result := '';                        // Returneres ingenting
  form1.Release;                         // dialogen nedlægges.
  
  if assigned(DllApp) then                      // Vi sætter application pointerne
    Application := DllApp;                      // Tilbage så de passer.
end;
Det som sker i ShowFiles er at DLL'ens egen Application pointer bliver gemt i en midlertidig variabel. Derefter kopieres den overførte application pointer over i DLL'ens Application pointer.

Her skal jo nok siges at Application er en slags intern variabel som Delphi sætter for hver enkelt program, og da DLL'er også er programmer, har de selvfølgelig også sådan en.
Man kan dog overskrive den, og det er det som vi lige har gjort.

Derefter opretter vi fil dialogen. Med ShowModal viser vi formen og venter til der kommer et modal result. Dvs. at en af de to knapper bliver trykket på. Hvis modal resultatet er mrOk (Ok knappen blev trykket på), returnerer vi FilNavn egenskaben og lukker fil dialogen, ellers returnerer vi en tom streng.
Til sidst flytter vi Application pointeren tilbage.

Nu mangler vi kun en ting, og det er at "offentliggøre" operationen ShowFiles. Det gør vi ved at kopierer hovedet
Function ShowFiles(MainApp : TApplication) : String; stdcall; exports ShowFiles;
op til lige over implementation delen af unit1.pas. Læg mærke til at der blev lige koblet lidt ekstra på, nemlig exports ShowFiles. Disse to ord gør at alle programmer som kender vores DLL kan kalde operationen ShowFiles.

Et eksempel

Forestil jer at i har et program med en memoboks og en knap. OnClick hændelsen for knappen ser sådanne ud :
procedure TMainForm.Button1Click(Sender: TObject);
var txt : String;
begin
  txt := VisFiler(application);
  if FileExists(txt) then
    memo1.lines.LoadFromFile(txt);
end;
Dette er dog ikke nok, fordi programmet skal lige kende DLL'en. Der er forskellige måder at gøre det på, her er den nemmeste :

Lige over implementation i MainForm filen tilføjes følgende :
Function ShowFiles(MainApp : TApplication) : String; stdcall; External 'FilDialog.dll';
Denne linie ligner umiddelbart erklæringen fra vores DLL og det skal den også. Det er meget vigtigt at erklæringen er magen til hinanden, dog er exports delen blevet erstattet af External 'FilDialog.dll'. Denne del gør at programmet ved at i FilDialog.dll filen er der en operation som hedder ShowFiles, og hvordan den ser ud.

Det var det

Det er faktisk alt hvad der skal til for at man kan bruge en form som er placeret i en DLL uden at denne får sin egen bjælke på processlinien.

Som en sidste detalje kan både den dll som bliver lavet her, samt et eksempel program downloades herfra : Zip-fil

Der er tale om et Delphi 4 projekt, men det burde uden problemer kunne bruges under både Delphi 3 og Delphi 5. Ingen af dem er dog testet, så det er muligt der er forhold er anderledes.


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