Форум: "Основная";
Текущий архив: 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.011 c