Как получить экземпляр TForm из дескриптора? - PullRequest
7 голосов
/ 19 ноября 2011

Я преобразую некоторые функции в DLL, которые относятся к функциональности Windows 7. Я не могу передать TForm через DLL, поэтому мне нужно вместо этого передать его дескриптор. кроме того, как только у меня есть этот дескриптор на другой стороне, как мне восстановить его обратно в экземпляр TForm? Кроме того, каков подходящий способ для передачи дескриптора (HWND) через DLL Delphi, чтобы быть совместимым, например, для вызова из C #?

Если это невозможно, то мне по крайней мере нужно знать, как изменить цвет окна, используя только Windows API, без ссылки на TForm. Цель состоит в том, чтобы из этой библиотеки DLL каким-то образом изменить цвет формы. Передача дескриптора в DLL не проблема, но как использовать этот дескриптор для работы с формой, которую представляет дескриптор?

Я специально собираю одну DLL-библиотеку, содержащую все необходимое для совместимости приложения Delphi7 с Windows7, например, рисование стекла, правильное отображение нескольких форм на панели задач (и сворачивание форм), отображение зеленого цвета. прогресс в значке панели задач, и все остальное может быть вовлечено. Этот тип работы, однако, требует изменения формы. Я должен быть в состоянии сделать эти изменения изнутри DLL.

Ответы [ 3 ]

8 голосов
/ 19 ноября 2011

Как правило, вы можете преобразовать HWND в указатель объекта, полученный из VCL TWinControl, используя функцию FindControl() VCL в блоке Controls.Затем вы можете проверить, действительно ли TWinControl является TForm, используя оператор is.

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

4 голосов
/ 19 ноября 2011

Вы не можете получить TForm из ручки.За пределами вашего Delphi-приложения такого нет, если только вы не используете пакеты (как сказал ответ Дэвида).

Вы можете использовать Handle (HWND) непосредственно в вызовах API, но только для вызовов API.

Вы можете передать это HWND напрямую вызовам API, таким как GetDC , чтобы получить контекст устройства (DC), а затем использовать это DC напрямую с DrawThemeтакие функции, как DrawThemeText или что-либо еще, требующее Windows DC.Вы также можете передать его другим вызовам API, которые требуют HWND.

3 голосов
/ 19 ноября 2011

Вы не можете передавать объекты Delphi через границы DLL. Это просто не работает. Нет механизма для экспорта класса Delphi из DLL.

Вам известно об этом, но передача указателя через границу не помогает. Вы хотите работать на TForm на другой стороне границы. Но единственный экземпляр TForm, который может иметь смысл, - это единственный, который создал дескриптор, и этот экземпляр захвачен границей модуля.

Есть некоторые объекты, которые можно воссоздать только с помощью ручки. Например, растровые изображения и значки имеют это свойство. Это потому, что у них нет состояния, кроме того, что хранится в дескрипторе GDI. Более сложные объекты VCL имеют такое состояние, и в этом заключается проблема.

Ваши варианты:

  1. Использовать пакеты. Это работает, но вы должны использовать одну и ту же версию компилятора для всех модулей.
  2. Использовать интерфейсы или COM. Это дает вам свободу смешивать версии компилятора и даже разные языки.
...