Einzelnen Beitrag anzeigen

delphifan2004

Registriert seit: 26. Nov 2004
Ort: Dresden
272 Beiträge
 
Delphi 10.3 Rio
 
#1

WM_COPYDATA zwischen Delphi- und Freepascalprogramm

  Alt 12. Feb 2010, 23:32
Hallo,

ich habe einen Client und einen Server, die ich in Freepascal bzw. Delphi geschrieben habe. Zum Beispiel den Client in Delphi, den Server in Freepascal. Könnte aber auch genau andersrum sein.

Wichtig ist: Eines der Programme, die per WM_COPYDATA miteinander kommunizieren sollen ist in Freepascal geschrieben, während das Andere in Delphi vorliegt.

Vom Freepascal- zum Delphiprogramm funktioniert die Übertragung.

Jedoch vom Delphiprogramm zu dem in Freepascal geschriebenen kommt nix an.

Warum?

Wenn ich wie in Delphi als Name den Fenstertitel für das TARGET_WINDOW verwende, das den Namen des
Freepascal-Programmes/Programmfensters repräsentiert, erhalte ich im Delphiprogramm, das mit dem Freepascalprogramm kommunizieren und dazu Daten senden soll, die Meldung: 'No recipient found!'.
Wenn ich stattdessen den Namen der .exe Datei, ohne Erweiterung, verwende, kommt die Meldung nicht mehr, aber es kommen keine Daten an.

Die Konstante TARGET_WINDOW findet in der Methode SendData() Verwendung.

Senden vom Freepascal-Programm an das Delphi Programm funktioniert dagegen. Als Name für das entfernte Delphiprogramm funktioniert der Fenstertitel.

Warum klappt das im Freepascal Programm nicht?

Und: was muss ich stattdessen machen, damit das Delphi Programm auch Daten an das Freepascalprogramm senden kann?

Kann es sein, das die Typumwandlung "Result:=String(sText)" in der Methode ReceiveData zwar in Delphi, nicht jedoch in Freepascal klappt.

Allerdings wird lblStatus.Caption im Server nicht verändert, was ja wiederum der Fall sein müsste, wenn eine leerer String übergeben würde.

Delphi-Quellcode:
//Dieser Client sei das mit Delphi geschriebene Programm:

type
  TfrmClient = class(TForm)
    btnReceive: TButton;
    pClientShow: TMemo;
    btnSend: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btnReceiveClick(Sender: TObject);
    procedure btnSendClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    procedure SendData(AData: String); //gleiche Implementierung, wie auf Server
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
  public

  end;
  
//Dieser Server sei in Freepascal/Lazarus geschrieben:

type
  TServer = class(TForm)
    btnTestCmd: TButton;
    lblStatus: TLabel;
    procedure btnTestCmdClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { private declarations }
   
   
    function ReceiveData(var Msg: TWMCopyData): String;
    procedure SendData(AData: String);
  public
    procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;

implementation

uses Strings

function TServer.ReceiveData(var Msg: TWMCopyData): String;
var
  sText: array[0..163] of Char;
begin
  // generate text from parameter
  // anzuzeigenden Text aus den Parametern generieren
  {$ifdef FPC}
  StrLCopy(sText, Msg.CopyDataStruct^.lpData, Msg.CopyDataStruct^.cbData);
  {$else}
  StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
  {$endif}
  // write received text
  // Empfangenen Text ausgeben
  Result := String(sText);
  //pClientShow.Lines.Add(String(sText));
end;

procedure TServer.SendData(AData: String);
var
  aCopyData: TCopyDataStruct;
  aCopyPntr: Longint; //falls Typumwandlungen nötig
  hTargetWnd: HWND;
begin
  with aCopyData do
  begin
    dwData := 0;
    cbData := StrLen(PChar(AData)) + 1;
    lpData := PChar(AData)
  end;
  aCopyPntr:= Longint(@aCopyData); //falls Typumwandlungen nötig
  // Search window by the window title
  // Fenster anhand des Titelzeilentext suchen
  hTargetWnd := FindWindowEx(0, 0, nil, PChar(TARGET_WINDOW));
  if hTargetWnd <> 0 then
    SendMessage(hTargetWnd,
       WM_COPYDATA,
       Longint(Handle),
       Longint(@aCopyData)
    )
  else
    ShowMessage('No recipient found!');
end;

procedure TServer.WMCopyData(var Msg: TWMCopyData);
begin
  lblStatus.Caption := ReceiveData(Msg);
end;

end.
Habe nur die Freepascal Seite mit Implementationsteil angegeben. Vom FPC-Programm aus kann ich ja an das Delphi Programm senden, nur nicht von diesem Empfangen.


Wer kann mir weiter helfen?


P.S: Das Beispiel hab ich hier aus der DP, wenn auch geringfügig geändert.
  Mit Zitat antworten Zitat