WM_COPYDATA字符串未出现在目标应用程序中

Dan*_*lly 4 delphi delphi-2010 wm-copydata

我正在尝试在Delphi 2010中的两个应用程序之间传递信息.

我正在使用我过去成功使用的简化版代码(简化因为我不需要发件人知道发送已成功)我已经将收到的发送简化为一对示例应用程序,实质上如下

发送

procedure TMF.SendString;
var
   copyDataStruct: TCopyDataStruct;
   s: AnsiString;
begin
   s := ebFirm.Text;
   copyDataStruct.cbData := 1 + length(s);
   copyDataStruct.lpData := PAnsiChar(s);
   SendData(copyDataStruct);
end;

procedure TMF.SendData(copyDataStruct: TCopyDataStruct);
var
   rh: THandle;
   res: integer;
begin
   rh := FindWindow(PChar('TMF'), PChar('Get Phone'));
   if rh = 0 then
   begin
      // Launch the target application
      ShellExecute(Handle, 'open', GetPhone, nil, nil, SW_SHOWNORMAL);
      // Give time for the application to launch  
      Sleep(3000);
      SendData(copyDataStruct); // RECURSION!
   end;
   SendMessage(rh, WM_COPYDATA, Integer(Handle), Integer(@copyDataStruct));
end;
Run Code Online (Sandbox Code Playgroud)

接收申请

procedure TMF.WMCopyData(var Msg: TWMCopyData);
var
   s : AnsiString;
begin
   s := PAnsiChar(Msg.CopyDataStruct.lpData) ;
   jobstatus.Panels[1].Text := s;
end;
Run Code Online (Sandbox Code Playgroud)

工作测试应用程序与我添加代码的应用程序之间的主要区别在于目标应用程序中正在进行大量额外活动.特别是在启动时.

有关为什么WMCopyData程序似乎根本没有解雇的任何建议?

干杯

Rem*_*eau 6

您的代码存在一些问题.

一,您没有为邮件分配唯一的ID.VCL和各种第三方组件也使用WM_COPYDATA,因此您必须确保实际处理您的消息而不是SOMEONE ELSE'S消息.

第二,你可能没有等到第二个应用程序启动的时间.相反的Sleep(),使用ShellExecuteEx()SEE_MASK_WAITFORINPUTIDLE标志(或使用CreateProcess()WaitForInputIdle()).

第三,当启动第二个应用程序时,您的递归逻辑正在尝试第二次发送消息.如果碰巧失败了,你会启动第三个应用程序,依此类推.你应该完全取出递归,你不需要它.

试试这个:

var
  GetPhoneMsg: DWORD = 0;

procedure TMF.SendString;
var
  copyDataStruct: TCopyDataStruct;
  s: AnsiString;
begin
  if GetPhoneMsg = 0 then Exit;
  s := ebFirm.Text;
  copyDataStruct.dwData := GetPhoneMsg;
  copyDataStruct.cbData := Length(s);
  copyDataStruct.lpData := PAnsiChar(s);
  SendData(copyDataStruct);
end;

procedure TMF.SendData(copyDataStruct: TCopyDataStruct);
var
  rh: HWND;
  si: TShellExecuteInfo;
  res: Integer;
begin
  rh := FindWindow(PChar('TMF'), PChar('Get Phone'));
  if rh = 0 then
  begin
    // Launch the target application and give time to start
    ZeroMemory(@si, SizeOf(si));
    si.cbSize := SizeOf(si);
    si.fMask := SEE_MASK_WAITFORINPUTIDLE;
    si.hwnd := Handle;
    si.lpVerb := 'open';
    si.lpFile := GetPhone;
    si.nShow := SW_SHOWNORMAL;
    if not ShellExecuteEx(@si) then Exit;
    rh := FindWindow(PChar('TMF'), PChar('Get Phone'));
    if rh = 0 then Exit;
  end;
  SendMessage(rh, WM_COPYDATA, WParam(Handle), LParam(@copyDataStruct));
end;

initialization
  GetPhoneMsg := RegisterWindowMessage('TMF_GetPhone');
Run Code Online (Sandbox Code Playgroud)

接收申请

var
  GetPhoneMsg: DWORD = 0;

procedure TMF.WMCopyData(var Msg: TWMCopyData);
var
  s : AnsiString;
begin
  if (GetPhoneMsg <> 0) and (Msg.CopyDataStruct.dwData = GetPhoneMsg) then
  begin
    SetString(s, PAnsiChar(Msg.CopyDataStruct.lpData), Msg.CopyDataStruct.cbData);
    jobstatus.Panels[1].Text := s;
  end else
    inherited;
end;

initialization
  GetPhoneMsg := RegisterWindowMessage('TMF_GetPhone');
Run Code Online (Sandbox Code Playgroud)