Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Hello, World!
  
 

Фильтр по датам

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  09:26[Войти] | [Зарегистрироваться]

О загрузке дочерней формы (MDIChild) из DLL.

Алексей Еремеев
дата публикации 07-08-2000 00:00

О загрузке дочерней формы (MDIChild) из DLL.

Данную статью меня заставило написать огромное количество вопросов в Круглом Столе (а теперь еще и в Подводных Камнях) насчет размещения дочерней формы в библиотеке DLL. Честно говоря, у меня никогда не возникало такой необходимости и я обходился простым приложением. Но масса вопросов без ответа посадило меня за кнопки вечерком. Говорят, что те ответы, которые, тем не менее, присутствуют, не работающие. И проверять мне их совсем не хотелось. Я решил начать решать проблему с нуля.

Поначалу я решил досконально разобраться в работе TForm и TApplication дабы точно представлять себе, как эти оболочки взаимодействуют с Windows, но потом понял, что ковыряться в сотнях строк исходников мне совсем неохота. Я просто посмотрел и увидел, что кроме, собственно handl-ов эти компоненты оперируют со своими всяческими внутренними служебными списками (обычно TList) и передачей хэндла тут не обойдешься. Для работы форм необходимы оба глобальных (для программы) объекта: и TApplication и TScreen. Подгружаемая DLL, если использует разного рода формы и контролы их тоже создает. Но они другие! В смысле другие instances, которые и знать не знают о таких-же объектах в главном приложении. Но они есть и убивать их тоже не хочется (мало-ли чего случится, если убить объект TApplication, даже в DLL). Поэтому решение пришло следующее. Создаем в нашей DLL две служебные функции, функцию вызова нашей дочерней формы и две переменные (пишу StdCall потому что всегда DLL-ки так оформляю, это удобно):

var 
  DLLApp: TApplication;
  DLLScr: TScreen;

procedure InitPlugin(App, Scr: integer); StdCall;
begin
  DLLScr := Screen;
  Screen := TScreen(Scr);
  DLLApp := Application;
  Application := TApplication(App);
end;

procedure DonePlugin; StdCall;
begin
  Screen := DLLScr;
  Application := DLLApp;
end;

function CreateMDI: integer; StdCall;
begin
  Result := integer(TfrmMyChildForm.Create(Application));
end;

exports
  InitPlugin,
  DonePlugin,
  CreateMDI;

Итак, в начале программы я открываю библиотеку (LoadLibrary), получаю функции (GetProcAddress) и инициализируюплагин (InitPlugin(integer(Application), integer(Screen))), передавая ему ссылки на объекты Application и Screen и они сохраняются в переменных внутри DLL. По окончании работы я его деинициализирую (DonePlugin), восстанавливая для dll-ки его объекты (для корректной деинициализации этих самых внутренних TApplication и TScreen), потом выгружаю библотеку (FreeLibrary). Функция создания дочернего окна возвращает объект формы (а по сути указатель) и с ним можно работать, либо используя переменную - родителя (TForm например) или абстрактный класс с которого наследуется форма в DLL (MyForm := TForm(CreateMDI)).

Неприятности такого похода состоят в том, что разные инструменты разработки (и даже разные версии одной и той же среды) могут быть (скорее всего, но я не проверял) несовместимы. Т.е. DLL с формой, изготовленной в одной версии Дельфи может не работать с приложением, скомпилированным в другой. Ведь внутренние структуры объектов и таблицы методов могут не совпадать. Но это не слишком дорого. Есть еще проблема дублирования кода VCL. Но что делать! Или так или пакеты. Вообще говоря в наше время гигабайтов и Win2K спорить о сотне килобайт просто скучно.

Для дех, у кого не вышло: я написал и скомпилировал тестовый пример (Delphi 2). Он работает. Все возможности MDI сохраняются, вроде menu-merging, меню Window и Caption в главной форме. Тексты и скомпилированное приложение прилагаются.

Напоследок. Я не претендую на полное исследование темы. Возможно в других версиях Дельфи есть и другие необходимые глобальные обьекты. Возможно, если формы будут использовать печать, то необходимо передать таким-же образом и объект Printer, однако это сами можете проверить. Стоит посмотреть, чем занимается delphimm.dll, ведь она устраивает общий менеджер памяти, может и еще чего интересное делает. Удачи всем.

Скачать проект Test_MD.zip (198 K)






Смотрите также материалы по темам:
[TList] [TForm] [TApplication] [TScreen] [Размещение форм в DLL] [MDI-интерфейс]

 Обсуждение материала [ 15-01-2009 04:35 ] 33 сообщения
  
Время на сайте: GMT минус 5 часов

Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
Функция может не работать в некоторых версиях броузеров.

Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

 
© При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
Все используемые на сайте торговые марки являются собственностью их производителей.

Яндекс цитирования