delphi, передавая параметры выполнения другому экземпляру через wm_copydata, дает неверный результат в Delphi XE2
Этот код раньше работал с Delphi 5, но с delphi XE2 не работает должным образом. Строка, переданная с помощью wm_copydata, будет обрезана.
procedure SendAppParameters(aMsgStr: string);
var
hwnd: THandle;
cds: CopyDataStruct;
begin
hwnd := FindWindow('TMyAppFormMain', nil); //<-- Substitute window classname with your own
if hwnd <> 0 then
begin
// showmessage(aMsgStr);
// prepare the data to copy
cds.dwData := 0;
cds.cbData := length(AMsgStr);
cds.lpData := PChar(AMsgStr);
// activate the destination window
SetForegroundWindow(hwnd);
// send the data to the first instance using a wm_CopyData message
SendMessage(hwnd, wm_CopyData, Application.Handle, integer(@cds));
end
end;
И в основной форме у меня есть:
procedure TMyAppFormMain.GotMessage_CopyData(var Msg: TWmCopyData);
var
MsgString: string;
I: Integer;
begin
MsgString := PChar(Msg.CopyDataStruct.lpData);
showmessage(MsgString);
end;
1 ответ
На самом деле ваш код никогда не был правильным. Это сломано даже на ANSI-версиях Delphi.
Давайте взглянем. Вы готовите сообщение так:
cds.cbData := length(AMsgStr);
cds.lpData := PChar(AMsgStr);
На ANSI Delphi это означает, что текст распределяется до, но не включая нулевого терминатора.
Получатель делает это:
MsgString := PChar(Msg.CopyDataStruct.lpData);
Это зависит от наличия нулевого терминатора. Нет никаких оснований ожидать, что будет и даже пытаться читать дальше cds.cbData
байты это ошибка.
Получатель должен заботиться о ценности cds.cbData
который отправляется и не читается за пределами буфера.
Теперь другая проблема заключается в том, что вы перешли на Unicode Delphi, поэтому текст теперь в кодировке UTF-16.
Чтобы отправить текст я написал бы:
cds.cbData := length(AMsgStr)*SizeOf(Char);
cds.lpData := PChar(AMsgStr);
А на принимающей стороне это должно быть:
SetString(MsgString, PChar(Msg.CopyDataStruct.lpData),
Msg.CopyDataStruct.cbData div SizeOf(Char));
Актерский состав, который вы используете, integer(@cds)
, это неверно. Которые должны быть LPARAM(@cds)
,