Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Проблема с общей формой


Автор: bazzzman 18.9.2006, 05:26
Вот такая проблема. Есть exe и dll.
В dll есть функция:

Код

procedure Func(ParentForm: TWinControl);
begin
   Fr_Lang := TFr_Lang.Create(ParentForm);
   Fr_Lang.Parent := ParentForm;
   Fr_Lang.Align := alClient;
   Fr_Lang.Show;
end;


Fr_Lang - это обычная форма со своим набором контролов. Она хронится в dll.

Exe вызывает эту функцию с параметром - главная форма приложения:
Код

Func(Application.MainForm);


Т.е. мы просто создаем дочернюю форму из dll.

Если в главной форме Exe через Application.MainForm.Controls[0] попытаться
обратится к форме созданной в dll, то
(Application.MainForm.Controls[0] is TControl) = True
а вот
(Application.MainForm.Controls[0] is TWinControl) = False

Как в Exe обратиться к свойствам и методам формы созданной в Dll?

Автор: Alexeis 18.9.2006, 07:22
Подозрительно, что не определяет правельно, тип, но если это точно форма, то в наглую использовать преобразование типов (Application.MainForm.Controls[0] as TControl).caption := 'hdfhd';

Автор: Fedia 18.9.2006, 07:37
А если экспортировать не процедуру, а функцию:
Код

function Func(ParentForm: TWinControl): TFr_Lang;
begin
   Result := TFr_Lang.Create(ParentForm);
   Result .Parent := ParentForm;
   Result .Align := alClient;
   Result .Show;
end;

Ну а далее с результатом функции производить нужные действия.

Автор: bazzzman 18.9.2006, 08:32
Цитата

Подозрительно, что не определяет правельно, тип, но если это точно форма, то в наглую использовать преобразование типов (Application.MainForm.Controls[0] as TControl).caption := 'hdfhd';

(Application.MainForm.Controls[0] as TControl) дает ошибку.

Цитата

function Func(ParentForm: TWinControl): TFr_Lang;
begin
   Result := TFr_Lang.Create(ParentForm);
   Result .Parent := ParentForm;
   Result .Align := alClient;
   Result .Show;
end;

Этого вообще делать нельзя. Тоже ошибку получаем.

Добавлено @ 08:43 
Вот что я нашел:
Цитата
If you want to group MDI children into a DLL you have to build the host MDI application and the DLL with run-time packages. This ensures that all the modules and the main application use the same Application and Screen objects as well as the same instance of the RTL and VCL. To be 100% sure, you should use Packages instead of DLLs (why mess with DLLs when those MDI child forms make sense only in your Delphi application)! 
MDI child inside a Package - the only true solution!
A Delphi Package is a special type of DLL, designed only to be used by Delphi applications. If your modules are developed as packages and not as DLLs, all modules will share the same memory manager, the VCL globals like Application and Screen, the same copy of the RTL and VCL code in memory!


Похоже придется использовать .bpl вместо .dll

Автор: Fedia 18.9.2006, 09:18
Цитата(bazzzman @  18.9.2006,  08:32 Найти цитируемый пост)
Этого вообще делать нельзя. Тоже ошибку получаем.

C "не дочерними" работает. С дочерними не пробовал.

Автор: bazzzman 18.9.2006, 10:24
Цитата

C "не дочерними" работает. С дочерними не пробовал.

Можно source?

Автор: Fedia 18.9.2006, 10:54
Цитата(bazzzman @  18.9.2006,  10:24 Найти цитируемый пост)
Можно source?

Конечно !

Добавлено @ 10:56 
В папке "DLL" - библиотека, в папке "DLL\Form" - проект, вызывающий форму из библиотеки.

Автор: Alexeis 18.9.2006, 10:58
Цитата(bazzzman @  18.9.2006,  08:32 Найти цитируемый пост)

(Application.MainForm.Controls[0] as TControl) дает ошибку.


Код ошибки если не сложно.

Автор: bazzzman 18.9.2006, 11:50
Fedia, твой пример в самом деле работает. Но мне нужен маленько другой фунционал.

Как получить ошибку в примере Федора  smile :

1. В Lib.dpr после:
Код

Result:=TFormTest1.Create(ParentForm);

добавляем:
Код

Result.Parent := ParentForm;

т.е. делаем форму в форме.

2. В Project1.dpr после:
Код

FormTest.Close;

добавляем:
Код

FormTest.Destroy;


Вот теперь если после показа формы в Project1.dpr сделать:
Код

  if Controls[1] is TWinControl then
   ShowMessage('1. '+Controls[1].Name);
  if Controls[1] is TControl then
   ShowMessage('2. '+Controls[1].Name);

То мы увидим только второй ShowMessage. Т.е. мы не можем обратится к созданной форме через Controls[x]. Получаем всегда TControl вместо TForm.

А вот:
Код

  with Controls[1] as TWinControl do
   ShowMessage('2. '+Controls[1].Name);

Вернет:
user posted image

И is тоже не работает. Как проверить Controls[1] - это форма или нет?

Автор: bazzzman 19.9.2006, 02:28
Не работает:
Код

  with Controls[1] as TWinControl do
   ShowMessage('2. '+Controls[1].Name);


Работает отлично:
Код

   ShowMessage(TWinControl(Controls[1]).Name);


Как проверить что Controls[1] именно форма? Подскажите плз.  smile 

Автор: Akella 19.9.2006, 08:05
Цитата(bazzzman @  19.9.2006,  02:28 Найти цитируемый пост)
Как проверить что Controls[1] именно форма? Подскажите плз.


Код

  if (Controls[1] is TForm) then...

Автор: bazzzman 19.9.2006, 08:48
Akella, читай мой предыдущий пост.

Код

if Controls[1] is TWinControl then

Не работает.

Код

if (Controls[1] is TForm) then...

Тоже не работает.

Код

with Controls[1] as TWinControl do

Выдает ошибку.


Но!
Код

TForm(Controls[1])

Работает отлично.

Но использовать TForm(Controls[1]) не безопасно, т.к. это может быть и не форма.
Это какая-та особенность vcl? Как проверить Controls[1] - это форма или нет?

Автор: bazzzman 20.9.2006, 02:11
Я сам нашел решение. Если кому-то интересно:
Код

if (Controls[1].ClassParent.ClassName = 'TForm') then

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)