Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi TComPort 3.1 und DLL (https://www.delphipraxis.net/112054-tcomport-3-1-und-dll.html)

Gloegg_FHBI 14. Apr 2008 14:16


TComPort 3.1 und DLL
 
Hallo,
Ich versuche momentan über die serielle Schnittstelle mit einem Gerät zu kommunizieren. Und das klappt auch alles super. Aber leider nur wenn ich das Formular, in welchem die TComPort-Komponente liegt, als Formular einer EXE laufen lasse. Sobald ich das gleiche Formular über eine DLL erzeuge, klappt zwar noch das Senden von Daten und es werden auch Daten empfangen, aber leider kein Event ausgelöst, das jetzt Daten anliegen. Zeige ich das Formular über die DLL Modal an, funktioniert es wieder.

Für mein Projekt ist es aber leider notwendig das Formular nicht Modal über eine DLL anzuzeigen. Das gleiche Verhalten hatte ich auch schon mit der TSerialPortNG-Komponente. Woran könnte es liegen, das das Event nicht ausgelöst wird?

Hier ein paar Ausschnitte aus dem Quellcode:

Der Quellcode des Formulars ist ziemlich trivial:
Delphi-Quellcode:
unit body;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, uBodyDLL, CPort, CPortCtl;

type
  TbodyFrm = class(TForm)
    startBtn: TButton;
    stopBtn: TButton;
    Memo1: TMemo;
    Panel1: TPanel;
    ComPort1: TComPort;
    Button1: TButton;
    ComDataPacket1: TComDataPacket;
    procedure ComDataPacket1Packet(Sender: TObject; const Str: string);
    procedure Button1Click(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure stopBtnClick(Sender: TObject);
    procedure startBtnClick(Sender: TObject);
  private
    { Private-Deklarationen }
    start : boolean;
    online : boolean;
  public
    { Public-Deklarationen }
    dir : string;
  end;

var
  bodyFrm: TbodyFrm;

implementation

{$R *.dfm}

procedure TbodyFrm.startBtnClick(Sender: TObject);
begin
  startOnlineMode(comPort1); //sendet den Start-string über die Schnittstelle - klappt einwandfrei
  online := true;
end;

procedure TbodyFrm.stopBtnClick(Sender: TObject);
begin
  stopOnlineMode(comPort1); //sendet #13 über die Schnittstelle - klappt einwandfrei
  online := false;
end;

procedure TbodyFrm.Button1Click(Sender: TObject);
begin
  comPort1.WriteStr('V'+#13); //Versionsinfos vom Gerät anfordern
end;

procedure TbodyFrm.ComDataPacket1Packet(Sender: TObject; const Str: string);
begin
  memo1.Lines.Add(str)
end;

procedure TbodyFrm.FormActivate(Sender: TObject);
begin
  if start then
  begin
    dir := ExtractFilePath(Application.ExeName);
    comPort1.Open;  
    start := false;
  end;
end;

procedure TbodyFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if online then
    stopBtn.Click;
  comPort1.Close;
  action := caFree;
end;

procedure TbodyFrm.FormCreate(Sender: TObject);
begin
  start := true;
end;

end.
Funktionen zum Anzeigen des Formulars in der DLL:
Delphi-Quellcode:
function ShowForm(aHandle : HWND) : longint;
var
  aForm : TBodyFrm;
begin
  // save Application.Handle
  oldHandle := Application.Handle;
  Application.Handle := aHandle;
  { create and show form }
  aForm := TBodyFrm.Create(Application);
  aForm.Show;
  Result := longint(aForm);
end;

function CloseForm(handle : longint) : integer;
var
  aForm : TBodyFrm;
begin
  aForm := TBodyFrm(handle);
  Result := 1;
  if aForm <> nil then
    if aForm.Showing then
      aForm.Close;
  // restore Application.Handle
//  Application.Handle := oldHandle;
end;

function ShowFormModal(aHandle : HWND) : integer;
begin
  try
    oldHandle := Application.Handle;
    Application.Handle := aHandle;
    bodyFrm := TBodyFrm.Create(Application);
//    Application.CreateForm(TbodyFrm, bodyFrm);
    result := bodyFrm.ShowModal;
    bodyFrm.Free;
  finally
    Application.Handle := oldHandle;
  end;
end;
Ausschnitt aus der aufrufenden EXE
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
//DLL - ShowForm - Normal - funktioniert nicht, gerät wird gestartet aber es wird kein NotifyEvent ausgelöst
  fHandle := showForm(Application.Handle);

//DLL - ShowForm - Modal - funktioniert
//  showFormModal(Application.Handle);

//App . ShowForm - Normal - funktioniert
//  bodyFrm.Show;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//DLL - CloseForm - Normal
  closeForm(fHandle);
end;

Reinhard Kern 14. Apr 2008 15:58

Re: TComPort 3.1 und DLL
 
Zitat:

Zitat von Gloegg_FHBI
Hallo,
Ich versuche momentan über die serielle Schnittstelle mit einem Gerät zu kommunizieren. Und das klappt auch alles super. Aber leider nur wenn ich das Formular, in welchem die TComPort-Komponente liegt, als Formular einer EXE laufen lasse. Sobald ich das gleiche Formular über eine DLL erzeuge, klappt zwar noch das Senden von Daten und es werden auch Daten empfangen, aber leider kein Event ausgelöst, das jetzt Daten anliegen. ...

Hallo,

eine DLL hat von sich aus keine Message Loop, kann also keine Events erhalten und bearbeiten. Man kann aber selbst eine Message Loop einrichten, am besten gleich in einem eigenen Thread.

Darüber gibts im Internet viel zu lesen, google am besten mal mit "dll message loop delphi".

Gruss Reinhard

Gloegg_FHBI 15. Apr 2008 10:33

Re: TComPort 3.1 und DLL
 
Nutzt das Formular nicht die Message-Loop der Application, die das Formular erzeugt hat? Immerhin biege ich ja den Application.Handle extra auf den Handle der aufrufenden Applikation um...


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz