Есть новая надежда? Создание дочернего окна MDI

Есть некоторые формы / элементы управления C #, которые можно вызывать либо из элемента управления C # в Winform в приложении Winforms MDI, либо из того же элемента управления C #, который используется приложением PowerBuilder MDI через COM.

Я использовал вызов WinAPI SetParent для прикрепления форм к MDI.

  1. Он работает (или кажется, работает) в обеих средах.
  2. Это позволяет дочернему окну иметь собственное состояние WindowState (Normal, Maximized) вместо того, чтобы принимать состояние уже открытых дочерних окон (что было настоящей проблемой).

Скажем, элемент управления называется T. Код элемента управления T вызывает форму D.

Элемент управления T находится в форме X.
Элемент управления T также находится в форме Y.

В .Net все хорошо, и форма D остается в пределах MDI.

в PB:
Control T находится на PB control PX. Элемент управления T также находится на элементе управления PB PY.

Для PX все хорошо.
Для PY, однако, есть проблема - форма D, похоже, не становится дочерним элементом MDI - она ​​может выходить за пределы приложения и имеет значок на панели задач. Я подчеркиваю, что здесь используются те же объекты, что и те, которые действительно работают. SetParent - это буквально та же строка кода.

Дальнейшие исследования показали, что SetParent действительно не работает для правильного формирования MDI - но это нормально, потому что нам не нужно объединять меню и т. Д.

Интересно, что обнаружили, что, хотя SetParent, кажется, «работает», вы не получите дескриптор обратно, если попробуете GetParent ...

Form form = new MyForm();
WindowsMessageHelper.SetParent(form.Handle, MDIParentHandle); //passed down 
int parentHandle = WindowsMessageHelper.GetParent(form.Handle);

parentHandle всегда будет 0 ....

Есть ли способ заставить форму D вести себя при любых обстоятельствах? Мои собственные исследования не были многообещающими. Я действительно не хочу возвращаться и переписывать свои формы как элементы управления и чтобы PowerBuilder управлял ими - в основном потому, что может быть несколько экземпляров каждой формы, и PowerBuilder должен будет обрабатывать это (вместо класса / базового класса контроллера, который я сделал это в приложении .net).

Могу ли я подчеркнуть, что в .Net нет проблем, проблема проявляется только в приложении PowerBuilder.


person kpollock    schedule 24.02.2009    source источник
comment
Пожалуйста, отредактируйте теги, поскольку комментарии к ответам показывают, что это не WinForms, но вопрос касается Winforms (первое предложение).   -  person Richard    schedule 25.02.2009


Ответы (3)


В конце концов, мы обнаружили, что разница заключалась в том, что PB выполнял эквивалент установки .MDIParent для элемента управления PX (того, где работал вызов формы D), но не для PY.

Как только это было отсортировано, мы получили правильный дескриптор MDIParent, и теперь все в порядке.

person kpollock    schedule 25.02.2009

Ваш дочерний элемент должен быть System.Windows.Forms.Form и установить для его свойства MdiParent значение окна MDI Patent (а не его Parent).

Контейнер также должен соответствовать нескольким правилам.

Прочтение инструкций по MDI в MSDN может в дальнейшем помочь.


Вариант второй: возможно, вы не сможете сделать это с помощью одного элемента управления. Instad рассматривает композицию основной реализации в двух обертках. Первая оболочка действует как дочерний MDI WinForms, вторая - как оболочка COM для использования в любой среде графического интерфейса PowerBuilder.

person Richard    schedule 24.02.2009
comment
Я отредактировал вопрос, чтобы, надеюсь, прояснить, почему этого ответа недостаточно - ваше решение является исключительно решением .Net, и здесь нет никаких проблем. - person kpollock; 25.02.2009
comment
Я отредактировал вопрос, чтобы, надеюсь, прояснить, почему этого ответа недостаточно - ваше решение является исключительно решением .Net, и здесь нет никаких проблем. - person kpollock; 25.02.2009
comment
вариант два - это то, что мы сделали для других форм, но это означает, что PB должен их контролировать - в любом случае см. мой ответ ниже ... - person kpollock; 25.02.2009

Если единственная проблема, которую вы еще не решили, - это не работает GetParent, возможно, вы сможете с этим смириться.

РЕДАКТИРОВАТЬ: но у спрашивающего больше проблем.

Есть несколько «тыков» API, каждый из которых должен выполняться по очереди, чтобы эта работа работала. Вам будет проще сделать это пользовательским элементом управления и разместить его в родном родительском элементе MDI при использовании ЧЕРЕЗ интерфейс COM или в дочернем элементе .NET MDI при помещении его в родительский элемент .NET MDI.

Существуют различные базовые оконные процедуры (DefWindowProc и DefMdiChildProc), которые необходимо использовать здесь, и для выполнения этой работы вы в конечном итоге реализуете DefMdiChildProc.

Если вы использовали рефлектор .NET, вы могли бы найти способ заставить System.Windows.Forms.Form вызывать для вас DefMdiChildProc.

person Joshua    schedule 24.02.2009
comment
Я отредактировал вопрос, чтобы, надеюсь, прояснить, почему этого ответа недостаточно. SetParent не вызывает ожидаемого поведения для формы D во втором случае. - person kpollock; 25.02.2009