Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Отправка данных между процессами с помощью SendMessage и WM_MyMessage в Delphi

Delphi , ОС и Железо , Справочник по сообщениям

При работе с несколькими процессами в Delphi иногда возникает потребность передавать данные между ними. Одним из способов достижения этой цели является использование функции SendMessage, которая отправляет сообщение в оконный сообщённый порт (window message) другого процесса. Тем не менее, при передаче данных между процессами с помощью SendMessage и пользовательского сообщения WM_MyMessage могут возникнуть трудности.

Проблема:

При попытке отправить данные между двумя процессами с помощью SendMessage и WM_MyMessage может возникнуть проблема, когда передача данных работает только в пределах одного процесса. Это происходит потому, что адреса только имеют смысл в рамках одного процесса, и адрес, созданный в одном процессе, является мусором в целевом процессе.

Пример:

Ниже представлен пример, иллюстрирующий описанную проблему:

MainApps.pas:

Type
  PMyrec = ^TMyrec;
  TMyrec = Record
    name : string;
    add : string;
    age : integer;
  end;

procedure TForm1.ButtonSendClick(Sender: TObject);
var
  aData: PMyrec;
begin
  new(aData);
  aData^.Name := 'MyName';
  aData^.Add := 'My Address';
  aData^.Age := 18;
  SendMessage(FindWindow('SubApps'), WM_MyMessage, 0, Integer(@aData));
end;

SubApps.pas:

Type
  PMyrec = ^TMyrec;
  TMyrec = Record
    name : string;
    add : string;
    age : integer;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.OnMessage := OnCaptureMessage;
end;

function TForm1.OnCaptureMessage(var Msg: TMessage; var Handled: Boolean): Boolean;
var
  aData: PMyrec;
begin
  aData := PMyrec(Msg.LParam);
  ShowMessage(aData^.Name);
  Handled := True;
  Result := Handled;
end;

При нажатии кнопки в приложении MainApps, отправляется сообщение с данными в приложение SubApps, но в SubApps данные не удается получить корректно, так как адрес, созданный в MainApps, является мусором в SubApps.

Решение:

Чтобы передавать данные между процессами с помощью SendMessage, следует использовать сообщение WM_CopyData. Это сообщение копирует данные из одного процесса в другой, гарантируя, что данные будут корректно получены в целевом процессе.

Ниже представлен пример, иллюстрирующий использование WM_CopyData для передачи данных между процессами:

MainApps.pas:

procedure TForm1.ButtonSendClick(Sender: TObject);
var
  Buffer: TMemoryStream;
  Len: Integer;
  CopyData: TCopyDataStruct;
  Rec: TMyRec;
begin
  Rec.Name := 'MyName';
  Rec.Add := 'My Address';
  Rec.Age := 18;

  Buffer := TMemoryStream.Create;
  try
    Len := Length(Rec.Name);
    Buffer.Write(Len, SizeOf(Len));
    if Len > 0 then
      Buffer.Write(Rec.Name[1], Len * SizeOf(Char));
    Len := Length(Rec.Add);
    Buffer.Write(Len, SizeOf(Len));
    if Len > 0 then
      Buffer.Write(Rec.Add[1], Len * SizeOf(Char));
    Buffer.Write(Rec.Age, SizeOf(Rec.Age));

    CopyData.dwData := 0;
    CopyData.cbData := Buffer.Size;
    CopyData.lpData := Buffer.Memory;
    SendMessage(FindWindow('SubApps'), WM_CopyData, Handle, LParam(@CopyData));
  finally
    Buffer.Free;
  end;
end;

SubApps.pas:

procedure TForm1.WMCopyData(var Message: TWMCopyData);
var
  Rec: TMyRec;
  Len: Integer;
  Buffer: TStream;
begin
  Buffer := TReadOnlyMemoryStream.Create(
    Message.CopyDataStruct.lpData, Message.CopyDataStruct.cbData);
  try
    if Message.CopyDataStruct.dwData = 0 then begin
      Buffer.Read(Len, SizeOf(Len));
      SetLength(Rec.Name, Len);
      if Len > 0 then
        Buffer.Read(Rec.Name[1], Len * SizeOf(Char));

      Buffer.Read(Len, SizeOf(Len));
      SetLength(Rec.Add, Len);
      if Len > 0 then
        Buffer.Read(Rec.Add[1], Len * SizeOf(Char));

      Buffer.Read(Rec.Age, SizeOf(Rec.Age));

      // TODO: Do stuff with Rec here.

      Message.Result := 1;
    end else
      inherited;
  finally
    Buffer.Free;
  end;
end;

В этом примере, перед отправкой данных в MainApps, они записываются в поток памяти TMemoryStream. Затем создается структура TCopyDataStruct, в которую помещаются данные из потока памяти. После этого данные отправляются в SubApps с помощью SendMessage и WM_CopyData. В SubApps данные извлекаются из потока памяти TReadOnlyMemoryStream и помещаются в переменную Rec.

При использовании WM_CopyData для передачи данных между процессами важно учитывать, что данные, содержащие строки, представляются внутренне как указатели. Поэтому при передаче данных с помощью WM_CopyData необходимо выделить дополнительную память для хранения записи и данных строк в одном блоке памяти, чтобы целевой процесс мог прочитать их.

Вывод:

При передаче данных между процессами с помощью SendMessage и WM_MyMessage в Delphi могут возникнуть трудности, связанные с тем, что адреса имеют смысл только в пределах одного процесса. Для решения этой проблемы следует использовать сообщение WM_CopyData, которое гарантирует корректную передачу данных между процессами. При работе с данными, содержащими строки, важно учитывать, что строки представляются внутренне как указатели, и выделять дополнительную память для хранения записей и данных строк в одном блоке памяти.

Создано по материалам из источника по ссылке.

В этом контексте рассматривается проблема передачи данных между двумя процессами в Delphi с использованием функции `SendMessage` и пользовательского сообщения `WM_MyMessage`. При этом возникает трудность, связанная с тем, что адреса, созданные в одном про


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Справочник по сообщениям ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-16 00:49:47/0.0051150321960449/1