Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.06.18;
Скачать: CL | DM;

Вниз

Форма в DLL   Найти похожие ветки 

 
KBsoft ©   (2006-05-05 23:03) [0]

Здравствуйте.

Посмотрел форум, но конкретного ответа не нашел.
Дело в следующем.
1. Есть приложение основное вызывающее некоторую функцию
из DLL.
2. В DLL функция выполняет слудующее:

function Execute(POwner:TComponent):TModalResult;
begin
 Result:=mrNone;
 Form1.:=TForm1.Create(POwner);
 try
   Result:=Form1.ShowModal;
 finally
   Form1.Free;
 end;
end;


Вроде бы все нормально, но есть некоторые нюансы, решить которые не могу, как ни бьюсь.
1. В форме Form1 не работают Hint
(для их отображения использую StatusBar c AutoHint:=True).
2. Иконка в верхнем левом углу формы не та, которая присвоена
программе, а стандартная для exe-файлов без указанного ico(белый прямоугольник).
Может быть есть еще более важные несоответствия, но в глаза
бросаются именно эти.

Как с этим делом справится?

Пробовал слеждующее:
1. В качестве POwner передавал и форму-из которой осуществляется вызов, и Application и nil. Результат не
изменяется.
2. Пробовал Hint"ы обрабатывать самостоятельно (переопределял Application.OnHint), но тогда исчезает весь смысл использования StatusBar.
3. Поковырялся с Application. Получается, что у приложения
и у DLL у каждого свой Application. Попробовал в DLL подменять
Application на Application формы (передавал в качестве параметра). Иконка в левом верхнем углу формы стала такой,
какой надо, но работа стала нестабильной. То вроде бы все нормально отработает, то начинает выдавать ошибки
(что-то с доступом к памяти, не вникал особенно).
Так понимаю, что этот способ неверный, а всех деталей процесса загрузки и работы DLL возможно не знаю.

Вопрос: Что делать? :-)

Владислав


 
Leonid Troyanovsky ©   (2006-05-06 00:44) [1]


> KBsoft ©   (05.05.06 23:03)  

> Как с этим делом справится?
> Вопрос: Что делать? :-)


Перенести форму в приложение, на работу в котором
она и рассчитана.

Меня все время волновал вопрос, откуда люди упорно цепляют
эту замечательную идею: засунуть форму (объект) в dll?

Ладно уж, на заре дельфи были еще подметные книжонки, но,
вроде бы, с этим уже разобрались, виновные расстреляны.
Сейчас, IMHO, мало кто, находясь в трезвой памяти, будет
и шутить на эту тему.

Может в консерватории что-то неладно? Преподы помогают :)

--
Regards, LVT.


 
Германн ©   (2006-05-06 02:43) [2]


> Может в консерватории что-то неладно? Преподы помогают :
> )


Имхо! Или "преподы" или "плагины"!
К первым отношусь "выборочно". Ко вторым - отрицательно, до тех пор пока не "покажут суть"!


 
evvcom ©   (2006-05-06 08:47) [3]


> Получается, что у приложения
> и у DLL у каждого свой Application

И не только Application! Есть еще много разных глобальных объектов в недрах VCL. И не только объектов. Даже классы и те идентичные, но разные. И если ты не используешь run-time packages, то все они "свои" у приложения и у каждой из dll. Отсюда и несостыковочки.


 
KBsoft ©   (2006-05-06 16:34) [4]


> Меня все время волновал вопрос, откуда люди упорно цепляют
> эту замечательную идею: засунуть форму (объект) в dll?


Все дело в том, что форм много - программа просто пухнет на глазах :-).
Каждый раз при изменении чего-либо в одной форме приходится
перекомпилировать всю программу. Пересылать же по e-mail
полностью всю программу сложновато из-за размера, а
так отправил только новую DLL и все (400-500 Кб вместо ~10Мб).

Может есть другой способ, кроме использования DLL.
Буду признателен, если подскажите.

(До недавнего времени и не выделял в DLL формы, но вышеназванные
причины вынуждают, а что делать?)

Владислав
PS

> И не только Application! Есть еще много разных глобальных
> объектов в недрах VCL. И не только объектов. Даже классы
> и те идентичные, но разные. И если ты не используешь run-
> time packages, то все они "свои" у приложения и у каждой
> из dll. Отсюда и несостыковочки.

То-то я и думаю почему p:TComponent, которому присвоено
значение p:=Application(программы) в условии
if p is TApplication в DLL выдает False.


 
Сергей М. ©   (2006-05-06 16:48) [5]


> Может есть другой способ, кроме использования DLL.


Отправлять патчи.


 
Eraser ©   (2006-05-06 18:43) [6]


> KBsoft ©   (06.05.06 16:34) [4]


> Все дело в том, что форм много - программа просто пухнет
> на глазах :-).

используя ДЛЛ, учитывая то, что сказано в [3], общий размер дистрибутива увеличится в разы, если не на порядок, учитывая "Все дело в том, что форм много"!

> Каждый раз при изменении чего-либо в одной форме приходится
> перекомпилировать всю программу. Пересылать же по e-mail
>
> полностью всю программу сложновато из-за размера, а
> так отправил только новую DLL и все (400-500 Кб вместо ~10Мб).
>

это не довод, для того, чтобы использовать ущербную архитектуру.
Да и есть решение - winRAR + [5].


 
KBsoft ©   (2006-05-07 11:03) [7]


> это не довод, для того, чтобы использовать ущербную архитектуру.
>
> Да и есть решение - winRAR + [5].


> Отправлять патчи.

С этого места можно поподробнее. :-)
Как их стряпать (патчи-то)? :-)
Серьезно, ни разу такого не делал.


> используя ДЛЛ, учитывая то, что сказано в [3], общий размер
> дистрибутива увеличится в разы, если не на порядок, учитывая
> "Все дело в том, что форм много"!

Это-то понятно, только общий размер мало волнует (пока, во всяком случае). А вот изменения - очень.


 
KBsoft ©   (2006-05-11 17:10) [8]

Возвращаясь к началу...
Если в DLL предусмотреть следующую процедуру и вызывать ее из основной программы перед вызовом самой формы с параметром (Application.Icon), то у формы(DLL) будет отображаться иконка, соответствующая программе.

procedure ApplicationDefineIcon(PIcon: TIcon); stdcall;
var
 pStream:TMemoryStream;
begin
 pStream:=TMemoryStream.Create;
 try
   PIcon.SaveToStream(pStream);
   pStream.Position:=0;
   Application.Icon.LoadFromStream(pStream);
 finally
   pStream.Free;
 end;
end;


А вот на счет Hint"ов что-то непонятное. Такое ощущение, что не отображаются они именно в StatusBar. Если у формы поставить ShowHint:=True, то Hint"ы (те, которые появляются около курсора мыши) работают нормально, а в StatusBar не выводятся.
Если переназначить Application.OnHint, то можно добиться появления их в StatusBar.

var
 vOnHint:TNotifyEvent;
begin
 vOnHint:=Application.OnHint;
 try
   {
   if Assigned(Application.OnHint)
   then ShowMessage("Да")
   else ShowMessage("No");
   }
   Application.OnHint:=DoFormHint;
   Result:=inherited ShowModal;
 finally
   Application.OnHint:=vOnHint;
 end;
end;
//
procedure TForm1.DoFormHint(Sender: TObject);
begin
 StatusBar.SimpleText:=Application.Hint;
end;

if Assigned(Application.OnHint)
then ShowMessage("Да")
else ShowMessage("No");
использовал для того, чтобы узнать определено ли что-либо изначально (выдает "No")

Начал копаться в исходниках, StatusBar выводит Hint в функции
function ExecuteAction(Action: TBasicAction): Boolean;
Попробовал создать свой компонент с переопределенной функцией
(взял из исходников)

type
 TMyStatusBar = class(TStatusBar)
 public
   function ExecuteAction(Action: TBasicAction): Boolean; override;
 end;
//
//...
//
function TMyStatusBar.ExecuteAction(Action: TBasicAction): Boolean;
begin
 if AutoHint and (Action.ClassName="THintAction"{ is THintAction}) and not DoHint then
 begin
   if SimplePanel or (Panels.Count = 0) then
     SimpleText := THintAction(Action).Hint else
     Panels[0].Text := THintAction(Action).Hint;
   Form1.Memo1.Lines.Add(THintAction(Action).Hint);
   Result := True;
 end
 else Result := inherited ExecuteAction(Action);
end;

такое ощущение, что эта функция в DLL вообще не вызывается (BreakPoints безразличен), для обычной exe-формы все работает.

Может быть что-либо делал криво, но нужно только ради того, чтобы разобраться.


 
REA   (2006-05-11 17:17) [9]

Попробуй packages. Проблем с ними не намного меньше, но они другие :)


 
Пусик ©   (2006-05-11 20:56) [10]

Модуль с формой, которую нужно получить из DLL модально:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   Label1: TLabel;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

procedure CreateForm(AppHandle: THandle);
function GetLabelText:ShortString;
procedure DestroyForm;

implementation

{$R *.dfm}

procedure CreateForm(AppHandle: THandle);
begin
   Application.Handle:=AppHandle;
   Form1:=TForm1.Create(Application);
   Form1.ShowModal;
end;

function GetLabelText:ShortString;
begin
   Result:=Form1.Label1.Caption;
end;

procedure DestroyForm;
begin
   Form1.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   Close;
end;

end.


Текст DLL:

library test;

uses
 SysUtils,
 Classes,
 Unit1 in "FormInDLL\Unit1.pas" {Form1};

exports
   CreateForm,
   GetLabelText,
   DestroyForm;
end.



Текст приложения, использующего DLL:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

procedure CreateForm(AppHandle: THandle); external "DLL\test.dll";
function GetLabelText:ShortString; external "DLL\test.dll";
procedure DestroyForm; external "DLL\test.dll";

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
   CreateForm(Application.Handle);
   ShowMessage(GetLabelText);
   DestroyForm;
end;

end.


 
Leonid Troyanovsky ©   (2006-05-11 21:20) [11]


> Пусик ©   (11.05.06 20:56) [10]

> Модуль с формой, которую нужно получить из DLL модально:


А как насчет хинтов и прочих, скажем, попапов.

--
Regards, LVT.


 
GanibalLector ©   (2006-05-11 21:34) [12]

У мя, например, хинты появляются(на форме,которая в DLL). Только я несколько иначе создаю формы(CreateParented).


 
Leonid Troyanovsky ©   (2006-05-11 21:38) [13]


> GanibalLector ©   (11.05.06 21:34) [12]

>  Только я несколько иначе создаю формы(CreateParented).


Для меню, IMHO, оно хужей, бо PopupMenu окно общее,
(т.е., и разное с приложением).
Да мало ли других (глобальных) переменных.

--
Regards, LVT.


 
Сергей М. ©   (2006-05-12 09:29) [14]


> С этого места можно поподробнее. :-)
> Как их стряпать (патчи-то)? :-)


http://www.computerra.ru/softerra/raznosoft/33984/


 
Пусик ©   (2006-05-12 09:35) [15]


> Leonid Troyanovsky ©   (11.05.06 21:20) [11]
>
> А как насчет хинтов и прочих, скажем, попапов.


Все делается. При желании, конечно.


 
Чапаев ©   (2006-05-12 09:55) [16]


> Пересылать же по e-mail
> полностью всю программу сложновато из-за размера, а
> так отправил только новую DLL и все (400-500 Кб вместо ~10Мб).

use runtime packages. Этим ты и проблемы с dll решишь (если будет на то воля Аллаха), и исполняемые файлы будут манинькими.


 
KBsoft ©   (2006-05-12 18:01) [17]


> use runtime packages. Этим ты и проблемы с dll решишь (если
> будет на то воля Аллаха), и исполняемые файлы будут манинькими.

Попробовал, действительно все работает.

Но тут уже дело принципа. Разобраться надо. :-)


> Пусик ©   (11.05.06 20:56) [10]

В принципе все так и делал, только передавал Application,
а не Application.Handle.
Попробовал передавать Application.Handle, Hint"ы в StatusBar
все равно не появляются. Зато при закрытии формы(DLL) виснет
основная программа. Тогда после ShowModal добавил восстановление
старого Application.Handle - зависания нет.

begin
 vH:=Application.Handle;
 Application.Handle:=PHandle; {Параметр}
 Form1:=TForm1.Create(Application);
 //...
   Form1.ShowModal;
   //Получение результата
 //
 Application.Handle:=vH;
end;

Но с Hint"ами-то в StatusBar проблема не решена.


> Только я несколько иначе создаю формы(CreateParented).

CreateParented - в чем его отличие от обычного Create?
Может быть действительно его лучше использовать?



Страницы: 1 вся ветка

Текущий архив: 2006.06.18;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.064 c
2-1148914109
0_o
2006-05-29 18:48
2006.06.18
Обращение к родительской ветке древа


4-1143037786
Arazel
2006-03-22 17:29
2006.06.18
ListBox под WinApi это не проблема! А вот со скинами это слабо!


2-1149026365
shart
2006-05-31 01:59
2006.06.18
Pointer as Class - в чем проблема


3-1145623574
arsin
2006-04-21 16:46
2006.06.18
не выпадает список знач. lookup поля, если данные на другой форме


2-1149134771
Atanas
2006-06-01 08:06
2006.06.18
Код выполняемый сразу после запуска