我正在尝试在 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;
接收申请
procedure TMF.WMCopyData(var Msg: TWMCopyData);
var
s : AnsiString;
begin
s := PAnsiChar(Msg.CopyDataStruct.lpData) ;
jobstatus.Panels[1].Text := s;
end;
工作测试应用程序和我添加代码的应用程序之间的主要区别是目标应用程序中正在进行很多额外的事件。尤其是在启动时。
关于为什么 WMCopyData 过程似乎根本没有触发有什么建议吗?
干杯
丹
最佳答案
您的代码存在一些问题。
第一,您没有为消息分配唯一的 ID。 VCL 和各种第三方组件也使用 WM_COPYDATA
,因此您必须确保您实际上正在处理您的消息,而不是其他人的消息。
第二,您可能没有等待足够长的时间来启动第二个应用程序。使用带有 SEE_MASK_WAITFORINPUTIDLE
标志的 ShellExecuteEx()
来代替 Sleep()
(或者使用 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');
接收申请
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');
关于delphi - WM_COPYDATA 字符串未出现在目标应用程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7257719/