apidelphisendmessagefindwindowwm-copydata

Why I cannot find window?


I use this example to send a string between two applications.

When I press the Send button for the first time, the string is sent to the Receiver, but only a part of the string is received.

When I press the Send button for the second time, I get "Window not found!". The window is right there on screen. Why it works when I press the button the first time, but not the second time?


This is the sender:

procedure TfrmSender.SendString;
var
 stringToSend : string;
 copyDataStruct : TCopyDataStruct;
begin
 Caption:= 'Sending';
 stringToSend := 'About - Delphi - Programming';

 copyDataStruct.dwData := 12821676; //use it to identify the message contents
 copyDataStruct.cbData := 1 + Length(stringToSend) ;
 copyDataStruct.lpData := PChar(stringToSend);

 SendData(copyDataStruct) ;
end;



procedure TfrmSender.SendData(CONST copyDataStruct: TCopyDataStruct);
VAR
   receiverHandle : THandle;
   res : integer;
begin
 receiverHandle := FindWindow(PChar('TfrmReceiver'), PChar('frmReceiver')) ;
 if receiverHandle = 0 then
  begin
   Caption:= 'Receiver window NOT found!';
   EXIT;
  end;

 res:= SendMessage(receiverHandle, WM_COPYDATA, Integer(Handle), Integer(@copyDataStruct));
 if res= 0 then Caption:= 'Receiver window found but msg not hand';
end;

And this is the receiver:

procedure TfrmReceiver.WMCopyData(var Msg: TWMCopyData);
VAR
   s : string;
begin
 if Msg.CopyDataStruct.dwData = 12821676 then
  begin
   s := PChar(Msg.CopyDataStruct.lpData);
   msg.Result := 2006;  //Send something back

   Winapi.Windows.Beep(800, 300);
   Caption:= s;
  end
end;

Solution

  • To summarize the comments there are two errors

    1) (See @Tom Brunberg) is that the length is set incorrectly which is why you only get part (about half? of the string)

    It should be

    copyDataStruct.cbData := sizeof( Char )*(Length(stringToSend) + 1 );
    

    2) The forms caption is being changed which invalidates the expression

    FindWindow(PChar('TfrmReceiver'), PChar('frmReceiver'))
    

    because the second parameter is the form's caption (in Delphi terminology)