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.