Текущий архив: 2006.12.03;
Скачать: CL | DM;
Вниз
Запутался с показом немодальной формы из DLL Найти похожие ветки
← →
DmiSb (2006-10-23 11:28) [0]Никак не пойму, почему при закрытии немодальной формы из динамически загруженной DLL вылетает AV
Код DLL :
library MyLIB;
uses
SysUtils,
Classes,
Windows,
Forms,
ibase,
LIBFormU in "LIBFormU.pas" {LibF};
procedure LibFormShow(HApp, HForm: THandle); stdcall;
begin
Application.Handle := HApp;
if Assigned(LibF) then
LibF.Show
else begin
LibF:=TLibF.Create(Application);
LibF.CallForm:=HForm;
LibF.Show;
end;
end;
procedure LibFormFree; stdcall;
begin
LibF.Free;
end;
exports LibFormShow;
exports LibFormFree;
begin
end.
Кусок кода основной программы:
TLibFormShow = procedure(HApp, HForm: THandle); stdcall;
TLibFormFree = procedure; stdcall;
var HLib: THandle;
procedure TMainF.WMUser(var Msg: TMessage);
var LF: TLibFormFree;
begin
if HLib > HInstance_Error then begin
LF := GetProcAddress(HLib, "LibFormFree");
if Assigned(LF) then LF;
FreeLibrary(HLib);
end;
end;
procedure TMainF.SpeedButton1Click(Sender: TObject);
var LS: TLibFormShow;
begin
if HLib <= HInstance_Error then
HLib := LoadLibrary("MyLib.dll");
if HlLib > HInstance_Error then begin
LS := GetProcAddress(HLib, "LibFormShow");
if Assigned(LS) then LS(Application.Handle, Self.Handle);
end;
end;
← →
Сергей М. © (2006-10-23 11:40) [1]для начала:
procedure LibFormFree; stdcall;
begin
FreeAndNil(LibF);
end;
← →
DmiSb (2006-10-23 11:49) [2]FreeAndNil(LibF) не помогает, при закрытии формы AV
← →
Сергей М. © (2006-10-23 11:52) [3]Закрытие выполняется юзером илии программно ?
На какой строчке возникает AV ?
← →
DmiSb (2006-10-23 11:58) [4]Закрытие окна производится бы пользователем,
а ошибка возникает на сктроке FreeLibrary(HLib);
в procedure TMainF.WMUser(var Msg: TMessage);
← →
MetalFan © (2006-10-23 12:22) [5]а откуда посылается это сообщение?!
← →
MetalFan © (2006-10-23 12:23) [6]и вообще, что-то мне не нравиться использование VCL в dll...
← →
iva © (2006-10-23 12:25) [7]в dll-овской форме по OnDestroy кидаешь сообщение главной форме и уже оттуда FreeLibrary
← →
DmiSb (2006-10-23 12:31) [8]Да, прошу прощения, не указал в начале
procedure TLibF.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if CallForm<>0 then
SendMessage(CallForm, wm_User, 0, 0);
end;
Возможно есть другой путь, но ни один попавший мне пример не работает
← →
iva © (2006-10-23 12:35) [9]попробуй добавить Action:=caFree;
← →
DmiSb (2006-10-23 12:45) [10]Пробовал, до и после еды :-)
← →
iva © (2006-10-23 12:48) [11]тогда посмотри http://www.realcoding.net/article/view/680
← →
DmiSb (2006-10-23 13:19) [12]Я этот пимер видел, но....
Либо опять же неверно определил WM_DLLUNLOAD, но процедура
procedure TMainF.WMDLLUnload(var Message:TMessage); у меня не срабатывает почему-то
← →
iva © (2006-10-23 13:26) [13]пользовался этой статьей, вроде работает.
← →
DmiSb (2006-10-23 13:29) [14]ДА вроде работает, не вызывается метод FreeLibrary, то есть программа не попадает в процедуру WMDLLUnload(
Скинь свой пример на DmiSb(собака)inbox.ru
← →
iva © (2006-10-23 13:30) [15]у меня нет примера, все в готовом проекте
← →
DmiSb (2006-10-23 13:31) [16]Как определил WM_DLLUNLOAD и где ?
← →
DmiSb (2006-10-23 13:36) [17]При данном способе, форма не разрушается при закрытии, а просто прячется, а мне надо чтобы она разрушалась и выгружалась Dll
← →
iva © (2006-10-23 13:37) [18]в главной форме
public
{ Public declarations }
procedure WMDLLUnload(var Msg:TMessage); message WM_DLLUNLOAD;
← →
DmiSb (2006-10-23 13:38) [19]Нет, я про константу WM_DLLUNLOAD хотел уточнить
← →
iva © (2006-10-23 13:41) [20]в файле описаний всякой всячины, который используется и в dll и в mainForm
const
...
WM_DLLUNLOAD = WM_USER+200+108;
← →
DmiSb (2006-10-23 13:49) [21]Ага, вот оно :-)
Так работает.
Я определил его меньше WM_USER, хотя.....как это повлияло, непонятно
Спасибо за помошь
← →
iva © (2006-10-23 13:53) [22]а как было у тебя?
← →
medved_68 © (2006-10-23 14:01) [23]
> При данном способе, форма не разрушается при закрытии, а
> просто прячется, а мне надо чтобы она разрушалась и выгружалась
> Dll
А кто мешает добавить в ДЛЛ функцию разрушения формы которая возвращает True в случае успеха и только после вызова этой функции выгружать ДЛЛ??? :)))
← →
DmiSb (2006-10-23 16:02) [24]Интересно, а как делается вызов какой либо функции из основной программы при нажатии кнопки, расположенной на ДЛЛ-форме ? Это очень сложно ?
← →
MetalFan © (2006-10-23 17:55) [25]
> procedure TLibF.FormClose(Sender: TObject; var Action: TCloseAction);
>
> begin
> if CallForm<>0 then
> SendMessage(CallForm, wm_User, 0, 0);
> end;
и что мы видим? из метода мы шлем SendMessage"ом сообщение, ждем его обработки, в котором осовобождается форма и длл... а потом соотв AV, ибо память то уже очищена...
замени SendMessage на PostMessage...
← →
MetalFan © (2006-10-23 17:58) [26]кстати, читаем MSDN
0 through WM_USER–1 Messages reserved for use by the system.
WM_USER through 0x7FFF Integer messages for use by private window classes.
WM_APP through 0xBFFF Messages available for use by applications.
0xC000 through 0xFFFF String messages for use by applications.
Greater than 0xFFFF Reserved by the system for future use
надо пользовать WM_APP + SomeInt...
← →
Ketmar © (2006-10-23 18:15) [27]>[26] MetalFan(c) 23-Oct-2006, 17:58
>надо пользовать WM_APP + SomeInt...
не обязательно. это желательно делать, если обмениваются сообщениями приложения. а в нашем случае мы имеем как раз "private window class".
и вообще, для обмена сообщениями между приложениями есть RegisterWindowMessage(). %-)
← →
MetalFan © (2006-10-23 18:20) [28]
> Ketmar © (23.10.06 18:15) [27]
ага, я не прав)
← →
MetalFan © (2006-10-23 18:22) [29]а по поводу
MetalFan © (23.10.06 17:55) [25]
что скажете?
← →
Ketmar © (2006-10-23 18:34) [30]>[29] MetalFan(c) 23-Oct-2006, 18:22
всё верно у тебя там указано. %-)
← →
Leonid Troyanovsky © (2006-10-23 19:18) [31]
> Ketmar © (23.10.06 18:34) [30]
> всё верно у тебя там указано. %-)
+ от меня бонус:
не пользовать формы из длл, тогда и будет всем джа.
--
Regards, LVT.
← →
Ketmar © (2006-10-23 19:25) [32]>[31] Leonid Troyanovsky(c) 23-Oct-2006, 19:18
>+ от меня бонус:
>не пользовать формы из длл, тогда и будет всем джа.
или, всё же, сначала разобраться, как это делать правильно. но лучше не использовать вообще -- ты прав. %-)
← →
MetalFan © (2006-10-23 21:06) [33]а если ср-вами winapi?
← →
Ketmar © (2006-10-23 21:08) [34]>[33] MetalFan(c) 23-Oct-2006, 21:06
>а если ср-вами winapi?
в WinAPI нет форм.
← →
MetalFan © (2006-10-23 21:17) [35]
> Ketmar © (23.10.06 21:08) [34]
но окна то есть)
← →
Ketmar © (2006-10-23 21:29) [36]>[35] MetalFan(c) 23-Oct-2006, 21:17
>но окна то есть)
окна -- есть. а форм -- нет. в [31] и [32] речь шла только о формах. %-)
← →
DmiSb (2006-10-24 07:47) [37]> не пользовать формы из длл, тогда и будет всем джа
А если есть необходимость разбить программу на модули, которые подгружались бы только в случае необходимости (также динамически как ДЛЛ) ?
← →
Loginov Dmitry © (2006-10-24 07:57) [38]DmiSb (24.10.06 7:47) [37]
А если есть необходимость разбить программу на модули, которые подгружались бы только в случае необходимости (также динамически как ДЛЛ
Скомпилируй все с пакетами (одного VCL вполне достаточно) и наслаждайся жизнью.
← →
DmiSb (2006-10-24 08:03) [39]Дык, а хочется еще меньше. У меня итак и основная программа и ДЛЛ компиляться с пакетами.
Это не выход.
Задача разбить программу на модули
← →
Ketmar © (2006-10-24 08:14) [40]>[39] DmiSb 24-Oct-2006, 08:03
>программа и ДЛЛ компиляться с пакетами.
>Это не выход.
отчего?
>Задача разбить программу на модули
и всенепременно динамически подгружаемые? может, тогда проще Оберон взять? %-)
← →
DmiSb (2006-10-24 08:35) [41]Ну хорошо, сдаюсь.
Может быть это была не самая лучшая мысль сделать программу с ДЛЛ,
но задача стояла следующая :
Программа должна уметь обновлять сама себя через Инет (VPN сеть). Используя ДЛЛ, её можно выгрузить, скачать новую, и загрузить.
Может кто подскажет, как это сделать красивее ?
← →
Ketmar © (2006-10-24 08:36) [42]пакетами?
← →
DmiSb (2006-10-24 08:42) [43]> пакетами?
В смысле ?
← →
Ketmar © (2006-10-24 08:44) [44]>[43] DmiSb 24-Oct-2006, 08:42
>> пакетами?
>В смысле ?
Borland сделали пакеты. Borland позволили пользователям делать пакеты. Borland дали для этого инструмент, которым пользовались сами.
← →
Slym © (2006-10-24 08:54) [45]модули компиль в пакеты :)
← →
DmiSb (2006-10-24 09:06) [46]Но тогда пакеты будут грузиться сразу ?
← →
metalfan © (2006-10-24 09:11) [47]
> DmiSb (24.10.06 09:06) [46]
с чего бы это?
http://delphiworld.narod.ru/base/little_about_plugins.html
← →
DmiSb (2006-10-24 09:46) [48]Да действительно.
И как я на эту статью раньше не наткнулся.
Интересно пообщаться с тем, кто реально использовал эту методику.
← →
DmiSb (2006-10-25 07:49) [49]>с чего бы это?
>http://delphiworld.narod.ru/base/little_about_plugins.html
Зы.....
У меня кстати не удалось повторить подвиг автора :-(
Если не делать Register(какой-либо класс),
функция GetClass(какой-либо класс) выдает nil
← →
Сергей М. © (2006-10-25 08:55) [50]
> DmiSb (25.10.06 07:49) [49]
> Если не делать Register(какой-либо класс),
> функция GetClass(какой-либо класс) выдает nil
Что в этом удивительного ?
← →
DmiSb (2006-10-25 09:18) [51]> Что в этом удивительного ?
Получается что ссылка на модуль с формой, которую я хочу хранить в пакете, должна быть в моем приложениии. И я так понимаю форма попадет в приложение, только в виде пакета ? Где же тогда, модульность ?
Или я не правильно понял ?
Сейчас пробую еще один путь, показанный в
http://www.codingclub.net/index.php?go=Articles&in=view&id=183
О форме, которая лежит в .bpl, основное приложение ничего не знает.
Методом TFormLoader FindClassByName(".....") класс формы определяется достаточно легко, я его только вынес в puplic секцию.
← →
metalfan © (2006-10-25 09:25) [52]
> Методом TFormLoader FindClassByName(".....") класс формы
> определяется достаточно легко, я его только вынес в puplic
> секцию.
кого куда вы вынесли?!
← →
Юрий Зотов © (2006-10-25 09:58) [53]> DmiSb (25.10.06 07:49) [49]
unit MyInterfaces; // Используется EXE и всеми DLL.
type
IMyInterface = interface
procedure Method1(...);
function Method2(...): ...;
...
еnd;
unit MyPluginForm; // Используется какой-то DLL
uses
MyInterfaces;
TPluginForm = class(TForm, IMyInterface)
...
end;
procedure GetMyInterface: IMyInterface; stdcall; // Экспортируется из DLL
begin
Result := TPluginForm.Create(...) as IMyInterface
end;
И это все. Модуль EXE знает, где лежат плагины (DLL или BPL). Он знает, что каждый из них экспортирует функцию GetMyInterface, а та возвращает ссылку на интерфейс IMyInterface. Еще он знает, какие методы этот интерфейс имеет, для чкго они нужны и как их вызывать.
А больше ему и знать ничего не нужно. Его не интересует ни класс, который реализует этот интерфейс (поэтому не требуется никаких RegisterClass), ни способ реализации, ни даже язык, на котором эта DLL написана.
Exe грузит плагин (LoadLibrary), вызывает его функцию GetMyInterface (GetProcAddress), получает ссылку на интерфейс IMyInterface - а далее просто вызывает методы этого интерфейса. Тогда и такие, когда и какие ему нужны. Остальное делает плагин, а КАК он это делает - для Exe неважно.
← →
Ketmar © (2006-10-25 10:24) [54]>[53] Юрий Зотов(c) 25-Oct-2006, 09:58
offtopic: Юрий, вы решили учить нас личным примером? (это я намекаю на "ламеров второго рода") нам-то вряд ли поможет, но вопрошающим крупно повезло. многие даже не понимают, как им повезло... (без иронии)
← →
Юрий Зотов © (2006-10-25 11:51) [55]> Ketmar © (25.10.06 10:24) [54]
Ага-а, значит, прочитал все-таки... и задумался-таки?
Это есть гуд.
:о)
А насчет "не понимают" - потом поймут. Не скоро. А тогда, когда станут готовы к такому пониманию.
Это и есть главное. Понимаешь?
:о)
← →
DmiSb (2006-10-25 11:54) [56]>[54]
Да я собственно даже на "второго рода" не претендую.
У меня такая задача первая.
>[53]
> procedure GetMyInterface: IMyInterface; stdcall; // Экспортируется из DLL
> begin
> Result := TPluginForm.Create(...) as IMyInterface
> end;
Я так понял, этот подход работает в DLL, потому как в BPL "as IMyInterface" не компилиться. И еще мне тут [31], [32] сильно советовали отказаться от форм из DLL. Как тогда этот подход можно использовать из BPL ? Может быть есть какая-нибудь литература по интерфейсам ?
← →
Сергей М. © (2006-10-25 11:59) [57]
> не компилиться
Значит у тебя ошибка в тексте программы.
← →
Amoeba © (2006-10-25 12:17) [58]Статьи по рассматриваемому вопросу:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=274
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=468
← →
DmiSb (2006-10-25 12:31) [59]С этой статьи
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=468
я и начал изучение использования пкетов в качестве плагинов, но ......[49],
а ссылка на исходники в статье битая.
Ладно, буду пробовать дальше....
Всем огромное спасибо
← →
Ketmar © (2006-10-25 13:13) [60]>[55] Юрий Зотов(c) 25-Oct-2006, 11:51
>Ага-а, значит, прочитал все-таки... и задумался-таки?
конечно, прочитал. даже осмыслил немного -- в применении к себе. %-)
>Это и есть главное. Понимаешь?
так я ж не к тому, что "бросайте это всё, ведь не оценят и не поймут". вовсе даже наоборот.
← →
Наиль © (2006-10-25 13:52) [61]> Ага-а, значит, прочитал все-таки... и задумался-таки?
А можно ссылку на то, от чего Ketmar задумался?
Хочется тоже преобщится к великому.
← →
Германн © (2006-10-25 16:10) [62]
> А можно ссылку на то, от чего Ketmar задумался?
Ищи в"Потрепаться" про "ламеров второго рода" :-)
← →
Ketmar © (2006-10-25 16:13) [63]>[62] Германн(c) 25-Oct-2006, 16:10
>Ищи в"Потрепаться" про "ламеров второго рода" :-)
угу. а то у меня ещё нет полнотекстового поиска в CDM. %-)
← →
MetalFan © (2006-10-25 18:23) [64]а что такое CDM?
← →
Ketmar © (2006-10-25 18:40) [65]>[64] MetalFan(c) 25-Oct-2006, 18:23
>а что такое CDM?
http://delphimaster.net/view/15-1158621901/
Страницы: 1 2 вся ветка
Текущий архив: 2006.12.03;
Скачать: CL | DM;
Память: 0.63 MB
Время: 0.058 c