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

Передача массива Variant через Windows API "SendMessage" с WM_COPYDATA: решение проблемы

Delphi , Синтаксис , Справочник по API-функциям

Вопрос передачи данных между DLL и приложением, где данные представлены в виде массива Variant, является актуальным для разработчиков, использующих Delphi и Pascal. В данной статье мы рассмотрим, как решить эту задачу, используя Windows API функцию "SendMessage" с WM_COPYDATA.

Проблема

Разработчик столкнулся с необходимостью передать массив Variant из DLL в приложение. Попытки использовать SendMessage с WM_COPYDATA не увенчались успехом. Это связано с тем, что WM_COPYDATA предназначен для передачи непрерывного блока данных, в то время как массив Variant в Delphi не обязательно будет структурирован таким образом.

Решение

Для решения проблемы необходимо сериализовать массив Variant перед его передачей. Однако, если приложение и DLL используют одинаковую версию RTL и передача происходит внутри одного процесса, можно передать Variant как указатель.

Пример кода для отправки данных

procedure SendData(AppHandle: HWND);
var
  V: Variant;
begin
  V := VarArrayOf([1, 'Some Text', 123.45, True]);
  // Размер данных Variant в байтах
  copyDataStruct.cbData := SizeOf(TVariantPtr) + VarArraySize(V) * SizeOf(Pointer);
  copyDataStruct.lpData := @V;
  copyDataStruct.dwData := copyDataStruct.cbData; // Чтобы получить правильный размер в принятой стороне
  SendMessage(AppHandle, WM_COPYDATA, WPARAM(AppHandle), LPARAM(@copyDataStruct));
end;

Пример кода для приема данных

procedure WMCopyData(var Msg: TWMCopyData);
var
  V: PVariant;
  i: Integer;
begin
  if (Msg.CopyDataStruct.dwData <> 0) then
  begin
    SetLength(V, (Msg.CopyDataStruct.cbData - SizeOf(Pointer)) div SizeOf(Pointer));
    Move(Msg.CopyDataStruct.lpData^, V[0], Msg.CopyDataStruct.cbData);
    // Работа с массивом Variant
    for i := Low(V) to High(V) do
      Case VType(V[i]) of
        varTypeBoolean: // Обработка булевых значений
        varTypeCurrency: // Обработка валютных значений
        varTypeDate: // Обработка дат
        varTypeDispatch: // Обработка диспетчеров
        varTypeError: // Обработка ошибок
        varTypeInteger: // Обработка целых чисел
        varTypeNull: // Обработка пустых значений
        varTypeSingle: // Обработка одиночных чисел
        varTypeString: // Обработка строк
        varTypeUserDefinedType: // Обработка пользовательских типов
        varTypeUnknown: // Обработка неизвестных типов
        varTypeVariant: // Обработка общих значений
        // Добавьте соответствующие обработчики для каждого типа данных
      end;
    // Освобождение памяти
    SetLength(V, 0);
  end;
end;

Альтернативное решение

В качестве альтернативы можно использовать кастомное сообщение вместо WM_COPYDATA:

const
  WM_MYCUSTOMMSG = WM_USER + 100;

procedure SendCustomData(AppHandle: HWND; const AData: PVariant);
begin
  SendMessage(AppHandle, WM_MYCUSTOMMSG, 0, LPARAM(AData));
end;

procedure WMCustomData(var Msg: TMessage);
var
  V: PVariant;
begin
  if (Msg.Msg = WM_MYCUSTOMMSG) then
  begin
    V := PVariant(Msg.LParam);
    // Работа с Variant
  end;
end;

Заключение

Передача массива Variant через SendMessage с WM_COPYDATA требует понимания структуры данных Variant и правильной сериализации массива перед передачей. Важно также корректно обработать данные на стороне получателя. Использование кастомного сообщения может упростить процесс и избежать необходимости в сериализации данных.

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

Вопрос связан с передачей массива данных Variant через Windows API функцию 'SendMessage' с WM_COPYDATA для обмена данными между DLL и приложением на Delphi.


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

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




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


:: Главная :: Справочник по API-функциям ::


реклама


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

Время компиляции файла: 2024-12-22 20:14:06
2025-05-09 12:08:32/0.0014820098876953/0