Announcement

Collapse
No announcement yet.

Aus einer Dynamisch geladenen DLL Form anzeigen?

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Aus einer Dynamisch geladenen DLL Form anzeigen?

    Hallo
    Wie zeige Ich eine Fenster das in sich in einer <b>dynamisch geladen Dll</b>, befindet?
    Die DLL wird mittels <br> <br>

    procedure TForm1.Button1Click(Sender: TObject);<br>
    var FuncPtr : TFarProc;<br>
    DLLHandle : THandle;<br>
    Pfad : String;<br> <br>
    begin<br>
    Pfad:='der Pfad'; <br>
    DLLHandle := LoadLibrary(PChar(Pfad));<br>
    FreeLibrary(DLLHandle);<br>
    end;<br> <br> <br> <br> <br>

    geladen. Aber wie zeige Ich nun die Form an?<br>
    In der Export-Klausel der DLL steht folgendes.<br>
    exports <br>
    <b>ShowForm;</b> <br>

    Danke für jede Antwort!

    mfg Saladin

  • #2
    Hallo,

    über die Win32-API-Funktion <b>GetProcAddress</b> muss nur noch die Adresse der exportierten Funktion aufgerufen werden. Das folgende Beispiel stammt aus meinem demnächst erscheinenden Buch <b>Delphi Win32-Lösungen</b>:
    <pre>
    type
    TFormMain = class(TForm)
    Bevel1: TBevel;
    StatBar: TStatusBar;
    Label1: TLabel;
    EditDLL: TEdit;
    BitBtnSet: TBitBtn;
    Bevel2: TBevel;
    PanelDLL: TPanel;
    Label2: TLabel;
    BitBtnGet: TBitBtn;
    BitBtnClose: TBitBtn;
    RGDLL: TRadioGroup;
    procedure BitBtnSetClick(Sender: TObject);
    procedure BitBtnGetClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure RGDLLClick(Sender: TObject);
    private
    { Private-Deklarationen }
    hDLL : THandle; // DLL-Handle
    bDLL : Boolean; // DLL geladen ?
    szText : array[0..99] of Char; // Text-Puffer
    public
    { Public-Deklarationen }
    end;

    var
    FormMain: TFormMain;

    implementation

    {$R *.DFM}

    (* Prozedurale Typen für die DLL-Funktionen deklarieren *)

    type
    TSetDLLText = procedure(aTxt: PChar);
    TGetDLLText = function: PChar;

    var
    FSetDLLText : TSetDLLText;
    FGetDLLText : TGetDLLText;

    (* Text aus dem Editierfeld in die DLL-Variable kopieren *)

    procedure TFormMain.BitBtnSetClick(Sender: TObject);
    begin
    StrCopy(szText, PChar(EditDLL.Text));
    FSetDLLText(szText);
    StatBar.SimpleText := 'DLL-Daten geschrieben'
    end;

    (* Text aus der DLL-Variablen auslesen *)

    procedure TFormMain.BitBtnGetClick(Sender: TObject);
    begin
    StrCopy(szText,FGetDLLText);
    PanelDLL.Caption := szText;
    StatBar.SimpleText := 'DLL-Daten gelesen'
    end;

    (* DLL laden und entladen *)

    procedure TFormMain.RGDLLClick(Sender: TObject);
    var
    dwError : DWord;
    begin
    if RGDLL.ItemIndex = 1 then begin
    // DLL laden
    if bDLL then Abort;
    hDLL := LoadLibrary('DLL_1.DLL');
    if hDLL <> 0 then begin
    @FSetDLLText := GetProcAddress(hDLL, 'SetDLLText');
    @FGetDLLText := GetProcAddress(hDLL, 'GetDLLText');
    if (Assigned(FSetDLLText) and
    Assigned(FGetDLLText)) then begin
    // Kein Fehler - also Button freigeben
    bDLL := True;
    BitBtnSet.Enabled := True;
    BitBtnGet.Enabled := True
    end
    else ShowMessage('DLL-Funktionen nicht gefunden !');
    end
    else begin
    // DLL-Ladefehler -> Fehlernummer anzeigen
    dwError := GetLastError;
    ShowMessage('Fehler: ' + IntToStr(dwError));
    end
    end
    else begin
    // DLL soll wieder freigegeben werden
    if bDLL then begin
    FreeLibrary(hDLL);
    FSetDLLText := nil;
    FGetDLLText := nil;
    bDLL := False;
    BitBtnSet.Enabled := False;
    BitBtnGet.Enabled := False
    end;
    end;
    end;

    procedure TFormMain.FormCreate(Sender: TObject);
    begin
    RGDLL.ItemIndex := 0;
    end;

    initialization
    FSetDLLText := nil;
    FGetDLLText := nil;
    </pre&gt

    Comment


    • #3
      <h4>Hallo</h4>
      <font face="MS Sans Serif">
      Danke für ihre Antwort Herr Kosch, aber ich habe das Problem damit leider noch nicht gelöst.<br>
      Ich habe die DLL dynamisch eingebunden.<br>
      Habe aber bisher vergebens versucht die Form aufzurufen, da<br>
      mir kein Befehl dazu bekannt ist. Können Sie mir erklären wie das zu bewerkstelligen<br>
      ist?<br>
      Bisher habe Ich folgendes stehen:<br> <br>

      type <br>
      TShowForm = procedure;<br>
      var ShowForm : TShowForm; <br>

      <br><br> ... <br> <br>

      <b>try</b> <br>
      <ul>
      DLLHandle := LoadLibrary('DllForm.dll');<br>
      if DLLHandle <> 0 then <br>
      <ul>begin <br>
      @ShowMail := GetProcAddress(DLLHandle, 'ShowForm');<br>
      <b>???</b>
      end; <br></ul>
      </ul>
      <b>finally</b> <br>
      FreeLibrary(DLLHandle); <br>
      end; <br><br> <br>
      Danke für ihre Hilfe

      </font&gt

      Comment


      • #4
        Hallo,

        der Aufruf der DLL-Funktion wurde auch in meinem o.g. Beispiel demonstriert:
        <pre>
        procedure TFormMain.BitBtnSetClick(Sender: TObject);
        begin
        StrCopy(szText, PChar(EditDLL.Text));
        FSetDLLText(szText);
        StatBar.SimpleText := 'DLL-Daten geschrieben'
        end;
        </pre>
        Dabei verbirgt sich hinter <b>FSetDLLText</b> die dynamisch importierte DLL-Funktion. Es reicht also aus, das unter Delphi die Variable für diese <b>Schnittstellenprozedur</b> aufgerufen wird (da diese Variable als <b>prozeduraler Typ</b> deklariert wurde, ist Delphi darüber informiert, das sich hinter dieser Variablen in Wirklichkeit eine aufrufbare Funktion verbirgt.

        Somit wird klar, das die Formular-Instanz direkt in der DLL erzeugt und freigegeben werden muss. Die DLL exportiert somit nur die Schnittstellenprozedur an den Client:
        <pre>
        procedure ShowAboutDLL;
        begin
        FormAbout := TFormAbout.Create(Application);
        try
        FormAbout.ShowModal
        finally
        FormAbout.Free
        end
        end;
        </pre>
        In diesem Fall reicht es aus, wenn der Client die DLL-Funktion ShowAboutDLL dynamisch importiert und einfach aufruft

        Comment


        • #5
          warum kann ich ein Form aus einer DLL nicht als nonmodalse Fenster aufrufen?
          Es flackert nur kurz auf und verschwindet gleich darauf wiede

          Comment


          • #6
            <b>Hallo Enrico</b><br>
            Man kann schon ein Formular nonmodular anzeigen. Das von dir <br>beschriebene Problem hatte ich auch. Wenn du folgenden Code <br>verwendest, dann tritt es nähmlich auf.<br>

            procedure create;<br>
            try<br>
            form1:=form1.create(NIL);<br>
            Form1.Show;<br>
            finally<br>
            Form1.release;<br>
            end;<br>
            end;<br><p>

            Aber wenn du den Try finally Block ausläst, dann funktionierts 'normal'. Ich habe den Form1.release Teil einfach in die OnClose-Procedure gesteckt!. ICh weiss nicht, ob das so geschickt ist, aber es funktioniert.

            Irfan Düzgü

            Comment


            • #7
              Hi Ifran

              besser wäre im OnClose Event

              Action := caFree;

              zu setzen.

              .Release erledigt aber das gleiche.

              Gruß Hage

              Comment

              Working...
              X