Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Отцы и дети, MDIParent и MDIChild 
:(
    Опции темы
rOOxus
Дата 11.4.2009, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



Имеется MDI приложение состоящее только из одной родительской формы. Дочерние формы поголовно создаються из DLL.
Как узнать в MDI родителе о создании или уничножении MDI child? Естесно в MDIchild-ах которые по DLL живут никакого кода по этому поводу писать нельзя.
PM MAIL   Вверх
aliks
Дата 13.4.2009, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 146
Регистрация: 17.12.2008

Репутация: нет
Всего: 1



О создании MDI child твой родитель узнает, когда ты будешь из главной формы будешь вызывать создание ребенка, при этом надо будет запомнить хендл. А потом отслеживать сообщения и ловить когда будет закрывать форма с данным хенделом, так ты поймаешь уничтожение ребенка.

Приведи код вызова/создания ребенка
--------------------
Любимая кнопка - F1, Любимое спасибо - Плюс в репутацию
PM MAIL Jabber   Вверх
rOOxus
Дата 13.4.2009, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



хм... все не так просто!
я использую компонент из JVCL jvPluginManager, ну и соответственно плагины под него с помощью мастера JVCL, который встраиваеться в Delphi/ Плагины подгружються в событии OnShow родительской формы одной строкой кода:
Код

procedure TMainForm.FormShow(Sender: TObject);
begin
   PluginManager.LoadPlugins;
end;

главная форма ничего не создает она вообще ни сном ни духом сколько у не будет деток т.к. деток плодят плгины. Каждый из них в событии OnPluginMessage, которое обрабатывает сообщеия от главной программы имее примерно такой код:
Код

procedure TModules.JvPlugInPluginMessage(Sender: TObject;
  APluginMessage: Integer; AMessageText: String);
begin
   if AMessageText = 'create_form' then
      ModulesForm := TModulesForm.Create( nil );
end;

то есть если главная программа сделает вот так
Код

PluginManager.Plugins[0].SendPluginMessage( 0, 'create_form' );

то плагин создает MDIChild форму, которая нарисуеться в главной программе. Вот тут-то главной программе и надо узнать, что создана MDIChild-форма. да и сделать это надо так, чтобы в плагине никакого доп.кода для оповещения главной программы не было потому, что основную программу пришет один программист, один плагин - другой, а третий совершенно пятнадцатый.
PM MAIL   Вверх
rOOxus
Дата 16.4.2009, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



я что так всех сильно напугал?
PM MAIL   Вверх
Bose
Дата 16.4.2009, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



Цитата(rOOxus @  16.4.2009,  09:38 Найти цитируемый пост)
я что так всех сильно напугал? 

Не думаю, что тут много людей которые использовали JvPlugins. 

Я когда-то смотрел, но на практике не применял. Удивительно, что это вообще работает.  smile

Могу только посоветовать попробовать копнуть в сторону:
1) Screen.FormCount и Screen.Forms[i]
2) почитать об mdi сообщениях в msdn
Может что-нибудь полезное и найдётся.
PM MAIL WWW Skype   Вверх
rOOxus
Дата 16.4.2009, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



в том то и дело, что MDI сообщения передаються WM_MDIACTIVATE, WM_MDICREATE, WM_MDIDESTROY и т.д. передаються дочернему окну, а не главному. поэтому они бесполезны. а надо чтобы главное реагировало на создание дочернего.
PM MAIL   Вверх
Bose
Дата 17.4.2009, 01:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



У меня вообще не получилось создать MdiChild в плагине.
---------------------------
Debugger Exception Notification
---------------------------
Project MDIAPP.exe raised exception class EInvalidOperation with message 'Cannot create form. No MDI forms are currently active'.
---------------------------
Break   Continue   Help   
---------------------------

rOOxus, покажи как ты MdiChild создаёшь?

А лучше сделай и выложи болванку проекта и простенький плагинчик. Ничего лишнего - только главная форма, загрузчик.

PM MAIL WWW Skype   Вверх
rOOxus
Дата 17.4.2009, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



без проблем.
вот тестовый проектик, который содержит главное приложение и dll-плагин, который в свою очередь содержит дочернюю форму и которую главное приложение может вежливо попросить плагин создать.
только для компиляци есть тонкость - я немного изменил код JVCL, а точнее в JvPluginManager.pas и JvPlugin.pas согласно теме, которая обсуждалась тут это необходимо для нормального оображения формы в окне родителя.

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  PluginManager.rar 368,21 Kb
PM MAIL   Вверх
Лапоть
Дата 17.4.2009, 19:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 3.4.2009

Репутация: нет
Всего: 2



Цитата(rOOxus @  11.4.2009,  11:21 Найти цитируемый пост)
Имеется MDI приложение состоящее только из одной родительской формы. Дочерние формы поголовно создаються из DLL

Позвольте спросить - а зачем такой изврат?
PM MAIL   Вверх
rOOxus
Дата 17.4.2009, 21:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



Цитата(Лапоть @ 17.4.2009,  19:22)
Позвольте спросить - а зачем такой изврат?

конечно. с удовольствием объясню.
дело в том, что разработка коллективная т.е. приложение разбито на несколько модулей, первый разарабатывает один программист, второй - другой а третий - совершенно пятнадцатый и т.д. и т.п. ядро т.е. приложение с главной формой, которая являеться MDI-родителем разрабатываю я.
модули реализованы в виде dll, которые создаються с помощью инструментария JVCL для плагинов, т.е. в dll сосредоточено ядро плагина и несколько форм для реализации интерфейса пользователя. центральная форма плагина - MDI-ребенок, ну остальные в основном будут вызываться модально для разных целей.
так вот охота мне чтобы MDI интерфейс напоминал окно Opera или Internet Explorer последних версий, а именно: в главном окне есть ToolBar, на котором отображаються кнопки всех MDI-окон-детей, которые создаються при создании ребенка, утпливаються при активации ребенка и удалються при закрытии ребенка. конечно проблема решаеться предельно просто если в события OnCreateOnActivate и OnClose форм-детей всех плагинов внедрить код на создание, изменение статуса и удаления той самой кнопеи на ToolBar, но каждому разработчику не объяснишь накой ему грузить свой плаагин этим кодом, да и совершенно неоправдано это.
вот я и ищу способ как заставить главную форму регировать на создание, активцию и удаление в ней дочереней дабы сей функционал был релизован единожды в еёйном коде
PM MAIL   Вверх
Bose
Дата 18.4.2009, 02:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



Цитата(rOOxus @  17.4.2009,  18:12 Найти цитируемый пост)
только для компиляци есть тонкость - я немного изменил код JVCL, а точнее в JvPluginManager.pas и JvPlugin.pas согласно теме, которая обсуждалась тут это необходимо для нормального оображения формы в окне родителя. 

Ой-ой-ой. Я не могу внятно сформулировать причину, но почему-то мне кажется, что так делать ни в коем случае не стоит. 

Во-первых - передавать классы в DLL-ку - это больше чем зло. Особенно учитывая, что плагины будут писать разные программисты, и нет никаких гарантий того, что у них будет та же самая версия Delphi и будут установлены все те же самые апдейты, что и у Вас.

Прежде чем двигаться дальше, настоятельно советую прочитать материал о плагинах в блоге Александра Алексеева.

PM MAIL WWW Skype   Вверх
rOOxus
Дата 18.4.2009, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



2 Bose
вы же попоросили выложить пример но даже не скачали его а слеовательно не посмотрели, а сразу испугались того как там что релизовно... странно
да и потом давайте немного претормозим и вернемся к вопросу самой темы. а он заключаеться в следующем: как зставить MDI-родителя узнать о том, что создан/активирован/удален MDI-ребенок без создания какого либо код в ребенке. ну неужто нет никаких способов. мне тут кто-то на днях посоветовал hook-ами воспользоваться, но я к сожалению с ними никогда не имел дела. может кто выскажет мнение имеет ли перспективу такой подход?
PM MAIL   Вверх
Bose
Дата 18.4.2009, 20:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



rOOxus, я не скачивал его, потому что узнав о необходимость править исходники JvPluginManager я потерял интерес к исследованию вашей проблемы. 
п.с. На мой взгляд, делать так - это то же самое, что закладывать фундамент на месте захоронения часовых бомб, в надежде пострить здание и продать до того, как хотя бы одна из них рванёт. 

Но даже если бы я его и скачал, то обнаружил бы там, что в выложенном вами архиве не хватает юнита child_unt. Если вернуться к вопросу, то я повторю, что я не знаю способа станцевать чечётку на поле с граблями и не получить ни разу по носу решить вашу проблему.

А общее моё мнение такого, что лучше сразу изменить архитектуру плагинов, придумав свой API, чем постоянно сталкиваться с разными странными глюками. А они, поверьте мне, будут.  smile 
PM MAIL WWW Skype   Вверх
rOOxus
Дата 18.4.2009, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



за недостающий юнит уж простите не углядел. на всякий случай выкладываю полный архив.
а насчет арихитектуры плагинов - да забудте вы о ней этот вопрос пока открыт. тема же другая совсем и намного шире. к тому же приложение предназначено для внутрикорпоративного использования так что если я его кому-то и продам, то только себе же самому.
хотелось бы услышать мнение насчет hook-ов. можно ли с их помощью перехватить сообщение внутри приложения о предаче тех самых WM_MDICREATE, WM_MDIACTIVATE, WM_MDIDESTROY от приложения к MDI окну? или я опять в направлении грабель иду?

Это сообщение отредактировал(а) rOOxus - 18.4.2009, 22:26

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  PluginManager.rar 372,12 Kb
PM MAIL   Вверх
Bose
Дата 18.4.2009, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



Насчёт hook-ов, сорри, не знаю - никогда с ними не работал. Но я видел что-то подобное реализованным TBX-Toolbar-ах Алекса Денисова.

Вот здесь можно посмотреть этот модуль.
Смотреть все упоминания фразы CBTHook.
Не знаю, сгодится ли.
PM MAIL WWW Skype   Вверх
rOOxus
Дата 19.4.2009, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



вы знаете - сгодилось! сверстал на основе исходников того модуля, ссылку на который вы дали. так что если кто еще интересуеться, то вот:
  •  Создаем функцию, котораая определит являеться ли окно окном MDIChild
  •  Пишем функцию hook-а, которая отловит все действия с окнами в данном приложении (т.е. имеем локальную ловушку)
  •  В событии OnCreate главной формы устанавливаем hook
  •  В событии OnDestroy главной формы снимаем hook
  •  Ну и при создании кнопки вешаем ей на OnClick событие, которое по ее Tag отышет MDI е таким же Handle и покажет его
небольшая тонкость - hook отлавливает события до их наступления, поэтому невозможно определить станет ли создаваемое окно MDIChild до его создания. поэтому создание кнопки окна на ToolBar делаеться при наступлении события установки форкуса на окно т.е. вместо HCBT_CREATEWND ловушка реагирует на HCBT_SETFOCUS и если кнопка окна уже есть, то топит ее, а если нет, то создает и топит.
Код

...

var
  CBTHookHandle: HHOOK;

// функци определения являеться ли окно MDIChild и определения его заголовка
function WindowIsMDIChild(W: HWND; var WinCaption : String ): Boolean;
var
  i: Integer;
  MainForm, ChildForm: TForm;
begin
  MainForm := Application.MainForm;
  if Assigned(MainForm) then
    for i := 0 to MainForm.MDIChildCount-1 do begin
      ChildForm := MainForm.MDIChildren[i];
      if ChildForm.HandleAllocated and (ChildForm.Handle = W) then
      begin
        WinCaption := ChildForm.Caption;
        Result := true;
        Exit;
      end;
    end;
  Result := False;
end;

// собственно Hook
function CBTHook(Code: Integer; WParam: WPARAM; LParam: LPARAM): LRESULT;
stdcall;
var
   i, Index : Integer;
   WndExists : Boolean;
   Item : TTBItem;
   WinCaption : string;
begin
   case Code of
      // активация окна
      HCBT_SETFOCUS :
      begin
         // если окно MDICild
         if WindowIsMDIChild ( HWND(WParam), WinCaption ) then
         begin
            // определяем есть ли на ToolBar кнопка с Tag равным
            // Handle окна
            WndExists := False;
            for i := 0 to MainForm.tb_WindowTB.Items.Count - 1 do
            begin
               if MainForm.tb_WindowTB.Items.Items[i].Tag = HWND(WParam) then
               begin
                  WndExists := True;
                  Index := i;
               end;
            end;

            // если нет, то создаем ее
            if not WndExists then
            begin
               Item := TTBItem.Create( nil );
               Item.Caption := WinCaption;
               Item.GroupIndex := 1;
               Item.AutoCheck := true;
               Item.Tag := HWND(WParam);
               Item.OnClick := MainForm.OnWinBtnClick;
               MainForm.tb_WindowTB.Items.Add( Item );
               Item.Checked := True;
            end
            // если есть, то топим
            else
            begin
               MainForm.tb_WindowTB.Items.Items[Index].Checked := True;
            end;
         end;
      end;
      // окно уничтожено
      HCBT_DESTROYWND :
      begin
         // если окно MDICild
         if WindowIsMDIChild ( HWND(WParam), WinCaption ) then
         begin
            // ищем на ToolBar кнопку с Tag равным Handle окна...
            for i := 0 to MainForm.tb_WindowTB.Items.Count - 1 do
            begin
               if MainForm.tb_WindowTB.Items.Items[i].Tag = HWND(WParam) then
               begin
                  Index := i;
               end;
            end;
            // ... и уничтожаем ее
            MainForm.tb_WindowTB.Items.Delete( Index );
         end;
      end;
   end;
   Result := CallNextHookEx(CBTHookHandle, Code, WParam, LParam);
end;

...

procedure TMainForm.FormCreate(Sender: TObject);
begin
   // Устанавливаем Hook
   if CBTHookHandle = 0 then
      CBTHookHandle := SetWindowsHookEx( WH_CBT, CBTHook, 0, GetCurrentThreadId );
end;

...

// Событие нажатия кнопки
procedure TMainForm.OnWinBtnClick(Sender: TObject);
var
   i : Integer;
begin
   TTBItem (Sender).Checked := true;
   for i := 0 to MainForm.MDIChildCount - 1 do
   begin
      if TTBItem (Sender).Tag = MainForm.MDIChildren[i].Handle then
         MainForm.MDIChildren[i].Show;
   end;
end;

...

procedure TMainForm.FormDestroy(Sender: TObject);
begin
   // Снимаем Hook
   UnhookWindowsHookEx(CBTHookHandle);
end;


Это сообщение отредактировал(а) rOOxus - 19.4.2009, 21:55
PM MAIL   Вверх
Bose
Дата 20.4.2009, 03:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1458
Регистрация: 5.3.2005
Где: Riga, Latvia

Репутация: 23
Всего: 51



Цитата(rOOxus @  19.4.2009,  20:52 Найти цитируемый пост)
вы знаете - сгодилось! сверстал на основе исходников того модуля, ссылку на который вы дали.

Вы знаете, я забыл упомянуть. Те исходники распространяются по какой-то хитрой лицензии. Для коммерческого использования там что-то особенное требовалось. Хотя, до автора, за последние пару лет никому не удалось достучаться. Но всё-таки лучше использовать этот код только как справочное пособие, и писать свой самому.
PM MAIL WWW Skype   Вверх
rOOxus
Дата 20.4.2009, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 95
Регистрация: 28.8.2006

Репутация: нет
Всего: нет



спасибо. учту smile 
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0932 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.