Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Формы из DLL и проблемы после парковки, точнее от размещения их в окне программы 
:(
    Опции темы
Gwire
Дата 6.2.2014, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 216
Регистрация: 7.8.2007
Где: Николаев

Репутация: 1
Всего: 4



Архитектура
1) Программа подключает DLL в которой есть форма;
2) Получает на эту форму указатель (как указатель на экземпляр класса TForm);
3) Программа в ходе работы скрывает у формы заголовок и "плюхает" её на "свою" панель.

Проблема. Эта форма не работает адекватно
1) Не сменяется фокус при нажатии [Tab];
2) Не переключаются закладки на TPageControl;
3) Клавиатурой не выделяется текст для TCustomEdit;
4) Команды Show и Hide ни к чему не приводят, ровно как и Visible.
5) Команды SetFocus приводит к ошибке "Control 'Edit1' has no parent window".

Изыскания
По началу пытался решить проблему тем, что знаю сам. Не вышло.
Потом решил почитать, что говорят сети по этому поводу. В основном только "Помогите" без нормальных советов.

Есть и рабочий вариант решения - это в настройках и программы, и библиотеки установить галку "Build with runtime packages"
и указать "vcl". "Хм, работает" - подумалось мне. Причем все эти 5 проблем исчезают.
Но предупреждения, что нудно таскать за собой bpl-файлы не очень мне правилось.
Проверил, и таки да: "Приложению не удалось запуститься, поскольку rtl70.bpl не был найден. Повторная установка ..." бла-бла-бла.
Ну и также требует "vcl70.bpl". Плохо. 

Дилемма
Почему с vcl все работает? Почему если просто форму без указания кто у нее Parent - не все но работает?
После прохода в отладке через GetParentForm в юните Forms
Код
function GetParentForm(Control: TControl): TCustomForm;
begin
  while Control.Parent <> nil do Control := Control.Parent;
  if Control is TCustomForm then           // Точка останова (в DLL).  Control.ClassName = "TForm1"
    Result := TCustomForm(Control) else
    Result := nil;                         // Ветка по которой идет выполнение.
end;

Как же так, ведь TForm1 это наследник TCustomForm, должен "Control is TCustomForm" возвращать "True".
И тут меня осенило: операнд "is" вызывает метод класса (напомню, что проверял я из DLL)
TForm1 наследник TCustomForm из программы, а строка это вызывает метод класса TCustomForm из DLL и сравнивает TForm1

Это как сравнивать двух однояйцевых близнецов. Разница только в "локации"
Вот откуда ноги растут. И включение vcl убирает клоны классов. Так все описатели классов они находятся в одном месте.

А теперь вопрос
Можно ли "объяснить" DLL, что описатели некоторых классов (TCustomForm, TCustomEdit, ... или всех) лежат в программе?
PM MAIL   Вверх
Alexeis
Дата 7.2.2014, 10:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(Gwire @  6.2.2014,  19:20 Найти цитируемый пост)
Как же так, ведь TForm1 это наследник TCustomForm, должен "Control is TCustomForm" возвращать "True".
И тут меня осенило: операнд "is" вызывает метод класса (напомню, что проверял я из DLL)
TForm1 наследник TCustomForm из программы, а строка это вызывает метод класса TCustomForm из DLL и сравнивает TForm1

Это как сравнивать двух однояйцевых близнецов. Разница только в "локации"
Вот откуда ноги растут. И включение vcl убирает клоны классов. Так все описатели классов они находятся в одном месте.

  Я бы сказал больше. Передача объектов через границу модуля запрещена религией VCL. Когда нарушен один из основных законов, то последствия могут быть любые. У VCL окон помимо свойства Parent, есть свойство ParentWindow, кроме того родителя можно назначать апи функцией SetParent. Правда проблему с Tab-ом это не исправит. Если приложение не признает окно родным VCL вским, то табы работают криво. Если же используются пакеты + ShareMem, то можно передавать объекты через границу модуля, но только объекты тех классов, которые реализованы в подключенных пакетах.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
gesper
Дата 7.2.2014, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


"Shарфик"
*


Профиль
Группа: Участник
Сообщений: 183
Регистрация: 23.2.2005

Репутация: 1
Всего: 2



Цитата(Alexeis @  7.2.2014,  10:39 Найти цитируемый пост)
 Я бы сказал больше. Передача объектов через границу модуля запрещена религией VCL. Когда нарушен один из основных законов, то последствия могут быть любые. У VCL окон помимо свойства Parent, есть свойство ParentWindow, кроме того родителя можно назначать апи функцией SetParent. Правда проблему с Tab-ом это не исправит. Если приложение не признает окно родным VCL вским, то табы работают криво. Если же используются пакеты + ShareMem, то можно передавать объекты через границу модуля, но только объекты тех классов, которые реализованы в подключенных пакетах. 

Где написано что запрещена?
У него ничего не работает, и программа сама ему говоритт по какой причине
Код

5) Команды SetFocus приводит к ошибке "Control 'Edit1' has no parent window"

В это случае выдается ошибка, во всех остальных ошибка обрабатывается и "забивается" в отстуствие какой либо реакции.

Это всего лишь оласти памяти, которые работают по программе описанной в классах. Каждая переменная, и связь оконо, это адреса классов. Они должны работать, без проблем, если правильно дать каждому окну нужные адреса.

Это сообщение отредактировал(а) gesper - 7.2.2014, 12:00
--------------------
...И приколется обломившийся и oбломится приколовшийся...
PM MAIL   Вверх
Alexeis
Дата 7.2.2014, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(gesper @  7.2.2014,  12:59 Найти цитируемый пост)
Где написано что запрещена?
У него ничего не работает, и программа сама ему говоритт по какой причине

  Первоисточник сходу не найду, но давно известный факт. Одна из главнейших причин состоит в том, что Delphi не поддерживает экспорт классов из Dll и Exe. Если мы хотим использовать объект некоторого класса, то мы обязаны его (класс не объект!) экспортировать. Иначе в другом модуле получаем лишь указатель неизвестного объекта. Попытка приведения этого указателя к такому же классу но другого модуля является undefined behavior чистой воды. Известно также что VCL объекты внутри часто используют обращения к RTTI . На этот счет есть статья в документации. http://docwiki.embarcadero.com/RADStudio/X...ckages_and_DLLs .
  Даже для C++ Builder a в котором поддерживается экспорт классов есть такой запрет.
http://docwiki.embarcadero.com/RADStudio/X...nents_(C%2B%2B) .
  Во всех случаях передача указателя на объект гарантируется производителем среды только если оба модуля имеют общую (разделенную shared) реализацию объекта в bpl . Все остальные варианты на свой страх и риск. 




--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0653 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.