Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.06.18;
Скачать: [xml.tar.bz2];

Вниз

Форма в 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.627 c
2-1148909221
ksenia
2006-05-29 17:27
2006.06.18
перестановка символов


1-1147103040
Андрей Молчанов
2006-05-08 19:44
2006.06.18
Управление тултипами TTreeView


1-1146814280
pargo
2006-05-05 11:31
2006.06.18
Корректная работа с памятью.


6-1139760370
Shamansky
2006-02-12 19:06
2006.06.18
TUdpSocket


3-1145216539
DevilDevil
2006-04-16 23:42
2006.06.18
Не видит параметров SQL запроса





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский