Форум: "Основная";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];
Вниз
DLL и немодальный формы в них Найти похожие ветки
← →
Rianon © (2005-10-17 23:36) [0]Кто может показать полный код, который покажет как правильно использовать немодальные формы в Dll и потом вызывать их в программе. На разных форумах иного всего написано но не до конца.
А проблема в чем:
Есть Dll в ней немодальная форма, в которую надо потом при вызове передать ряд параметров и потом по завершению тоже ряд других забрать.Dll связывается динамически
Так вот создал 2 функции CreateForm(...), FreeForm но если вызов происходит более или менее нормально то завершить корректно немодальную форму не удается никогда то вообще проэкт закроет то ошибку выдаст.. Делфи то на Free матюгом кричит то на FreeLibrary...
Помогите плз... но лучше всего реально работающим проектом Всю эту муть хочется использовать в некоторое подобие плагинов..
← →
Германн © (2005-10-18 01:04) [1]Имхо, "DLL" и "форма" есть понятия совместимые только с учётом "геморроя"!
И "DLL" изначально разрабатывалось без учета наличия "форм". И "формы" изначально разрабатывались без учета "DLL".
Некая "затычка" в сём вопросе в Дельфи - "BPL". Но и там есть претензии. И есть свой геморрой.
← →
Джо © (2005-10-18 02:58) [2]Вот, например, достаточно "безгеморройный" способ, основанный на отдельном менеджере, занимающемся загрузкой/выгрузкой.
//
// Модуль главного окна тестовой программы
// На форме - одна кнопка и обработчик к ней
//
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
// Менеджер, отвечающий за загрузку/выгрузку модулей
// и уничтожение форм
TFormLoader = class
private
FLibs,
FHandles: TList;
procedure UnloadLibraries;
public
// этот метод вызывает указанную функцию в указанном модуле
// и регистрирует все необходимое для последующей "очистки"
procedure LoadForm (DllName,ProcName: string);
constructor Create;
destructor Destroy; override;
end;
var
FormLoader: TFormLoader;
// щелчок на кнопке
procedure TForm1.Button1Click(Sender: TObject);
begin
// загружаем еще один экземпляр формы
// нашим менеджером
// указывая имя DLL и имя функции в нем
FormLoader.LoadForm("mydll.dll","ShowForm");
end;
{ TFormLoader }
constructor TFormLoader.Create;
begin
inherited Create;
FLibs := TList.Create;
FHandles := TList.Create;
end;
destructor TFormLoader.Destroy;
begin
// уберем за собой
UnloadLibraries;
FLibs.Free;
FHandles.Free;
inherited;
end;
procedure TFormLoader.LoadForm(DllName, ProcName: string);
type
// вызываемая функция должна соответствовать этой декларации!!
TProc = function(MainFrmHandle: Cardinal): Cardinal;
//
var
Lib: THandle;
Proc: TProc;
Err,
WindowHandle: Cardinal;
begin
Lib := LoadLibrary(PChar(DllName));
if Lib <> 0 then
begin
Proc := GetProcAddress(Lib,PChar(ProcName));
if @Proc <> nil then
begin
// выполняем функцию в DLL
// и получаем хэндл созданного окна
WindowHandle := Proc(Application.Handle);
// добавляем модуль и хэндл окна
// в свои списки
FHandles.Add(Pointer(WindowHandle)) ;
FLibs.Add(Pointer(Lib));
end
else
begin
// библиотеку необходимо выгрузить
// ибо GetProcAddress завершился неуспешно
Err := GetLastError;
FreeLibrary(Lib);
raise Exception.Create(SysErrorMessage(Err));
end
end
else
RaiseLastOSError;
end;
procedure TFormLoader.UnloadLibraries;
var
I: Integer;
WH,
LH: Cardinal;
begin
// 1. "убивание" окон если они еще существуют на момент вызова
// 2. выгрузка соответствующих библиотек
for I := 0 to FLibs.Count-1 do
begin
WH := Cardinal(FHandles[I]);
if IsWindow(WH) then
DestroyWindow(WH);
LH := Cardinal(FLibs[I]);
FreeLibrary(LH);
end;
end;
initialization
// инициализируем менеджер при старте программы
FormLoader := TFormLoader.Create;
finalization
// удаляем менеджер
// (при уничтожении он автоматически "убъет" все загруженные формы
// и выгрузит библиотеки)
FormLoader.Free;
end.
Теперь библиотека
library mydll;
uses
SysUtils,
Classes,
Forms,
DllFormUnit in "DllFormUnit.pas" {DllForm};
{$R *.res}
// Функция, вызов которой создает и показывает форму,
// находящуюся в DLL
// Должна возвращать handle созданного окна
// В MainFrmHandle передаем Application.Handle
// вызывающей программы (для того, чтобы не создавать новый tab
// на полосе задач). Можно игнорировать
function ShowForm (MainFrmHandle: Cardinal): Cardinal;
var
Frm: TDllForm;
begin
if MainFrmHandle <> 0 then
Application.Handle := MainFrmHandle;
Frm := TDllForm.Create(nil);
Result := Frm.Handle;
Frm.Show
end;
exports
ShowForm;
end.
Ну, и к ней, разумеется, идет соответствующий модуль с классом формы. Здесь - TDllForm.
------
Надеюсь, все достаточно понятно.
← →
Leonid Troyanovsky © (2005-10-18 09:39) [3]
> Джо © (18.10.05 02:58) [2]
> Вот, например, достаточно "безгеморройный" способ, основанный
..
> Надеюсь, все достаточно понятно.
Понятно, конечно.
Непонятно, почему даже после многочисленних здешних дискуссий на эту
тему оный способ позиционируется как безгеморойный для
немодальных форм.
Ведь, только недавно некто искал потерянные CM_MOUSELEAVE.
IMHO, нельзя создавать немодальные формы в dll.
Или, лучше сказать так: эти dll обязаны быть либо bpl, либо ocx.
Ну, или, какая-нибудь гремучая комбинация.
--
Regards, LVT.
← →
Rianon © (2005-10-18 20:35) [4]Да это конечно все весело, но насчет
- Или, лучше сказать так: эти dll обязаны быть либо bpl, либо ocx.
посмотрите на Тотал Комманлдер там ведь работает....
← →
Джо © (2005-10-18 21:32) [5]
> [4] Rianon © (18.10.05 20:35)
Ты с [2], надо полагать, уже разобрался до конца?
← →
Джо © (2005-10-18 21:35) [6]Кроме того, ГДЕ в TC используется то, о чем ты говоришь? Например, окно Листера создается, насколько я знаю, в программе, а не в ДЛЛ.
← →
Rianon © (2005-10-19 19:34) [7]Да и плагины листера (напр по расширениям) - посмотрите их описания там черным по белому пищут File is Dll есть даже перечень экспортных процедур
но спасибо всеравно я нашел способ
← →
Джо © (2005-10-19 19:57) [8]
> [7] Rianon © (19.10.05 19:34)
Еще раз: главное окно Lister"а создается НЕ в DLL! Оно создается самим TotalCommander, т.е., в программе. См. описание функцииListLoad
в LISTPLUGIN.HLP.
← →
Джо © (2005-10-19 19:59) [9]
> [3] Leonid Troyanovsky © (18.10.05 09:39)
> IMHO, нельзя создавать немодальные формы в dll.
"Форма" создается в DLL. Но для вызывающей программы - это никакая не форма. Все, что она знает об этом окне - это его Handle.
← →
Leonid Troyanovsky © (2005-10-20 09:31) [10]
> Джо © (19.10.05 19:59) [9]
> > IMHO, нельзя создавать немодальные формы в dll.
> "Форма" создается в DLL. Но для вызывающей программы - это
> никакая не форма. Все, что она знает об этом окне - это
> его Handle.
Проблема в том, что в хосте и библиотеке свои копии кода всех ключевых
модулей. И переменных, причем, не только Screen, Application & etc, но и
таких, которые объявлены в разделе implementation.
Ну, и отсюда вытекает много проблем, как известных: hints, actions &etc,
так и малоизученных (кому оно нужно).
Создание модальных форм в длл предложенным способом еще более-менее
терпимо. А от такого использования немодальных (и MDI), прогрессивное
дельфийское сообщество отказалось, AFAIK, еще в прошлом веке.
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.046 c