Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Модальная MDIChild


Автор: StayAtHome 4.4.2005, 01:08
Возникла потребность отобразить модально MDIChild-форму. C удивлением, обнаружил, что ShowModal не работает, т к Child-форма видима сразу после создания Кроме того ей вообще невозможно установить Visible:=False
Мож кто прояснит, зачем существует такое ограничение, и как его обойти?

Автор: FRAGNATIC 4.4.2005, 14:57
Цитата
ей вообще невозможно установить Visible:=False
убрать форму из автосоздания и создовать при необходимости

Автор: StayAtHome 5.4.2005, 01:06
Я так и сделал, но после создания формы и ДО ее появления на экране, мне нужно выполнить кое-какой код, а MDIChild сразу отображается после Create (при установке FormStyle=fsMDIChild). И ShowModal все равно в результате не пашет.

Автор: <Spawn> 5.4.2005, 04:49
Можешь явным образом изменить видимость у окна:

Код

  ShowWindow(Handle, SW_HIDE);


и потом восстановить, когда нужно будет

Код

  ShowWindow(Handle, SW_SHOW);

Автор: Girder 5.4.2005, 11:42
1. Убераеш свою MDIChild форму из автосоздания: (MainMenu)Project->Options->Forms. Там её перебрасываеш в: Available forms
2. Переключаешся на свою MDIChild форму и дописываеш в описание класса(пусть например твой класс формы для MDIChild называется TForm2):
Код
...
 TForm2 = class(TForm)
    ...
    procedure CreateWindowHandle(const Params: TCreateParams); override;
  private
    { Private declarations }
  public
...

3. Реализуеш енту процедуру:
Код
procedure TForm2.CreateWindowHandle(const Params: TCreateParams);
var Comp:TForm2;
begin
 inherited;
 Comp:=TForm2(Application.Components[Application.ComponentCount-1]);
 Comp.Visible:=false;
end;



4.Ну и например создание ентой формы:
Код
uses Unit2; //ссылка на модуль MDIChild формы

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var vv:TForm2;
begin
 vv:=TForm2.Create(Application);
 //... Здесь форма не видна
 vv.Memo1.Lines.Add('123123'); //Типо что-то заполняем на MDIChild форме
 Caption:='2';
 Sleep(2000);
 Caption:='0';
 //.. Здесь форма до сих пор не видна
 vv.Show;
end;


Удачи.

Автор: StayAtHome 6.4.2005, 01:20
Исчерпывающий ответ. Спасибо! smile
С Show все работает, но ShowModal использовать так и не удалось. Там в первой же строке реализации черным по белому:
Код
  if Visible or not Enabled or (fsModal in FFormState) or
    (FormStyle = fsMDIChild) then
    raise EInvalidOperation.Create(SCannotShowModal);

Увы, вопрос остается открытым.

Автор: Петрович 6.4.2005, 07:44
Не совсем понятно зачем бы делать ShowModal для MDI формы. Дело в том, что у MDI форм очень сложные взаимоотношения с другими окнами.
Если уж есть какая-то необходимость, то перед созданием этого окна сделай его не MDI.
Ааа. Кажется понял. Ты хочешь уже созданное окно отображать то модально, то нет. Тогда тебе не повезло.
Правда мне все равно не понятно зачем такое делать. По своей природе, дочернии MDI-окна равноправны. А ты хочешь сделать как всегда: все равны, но некоторые ровнее. smile

Автор: Girder 6.4.2005, 11:17
Цитата(StayAtHome @ 6.4.2005, 02:20)
Увы, вопрос остается открытым.
smile

Создаем "модульную" MDIChild форму:
Код
procedure TForm1.CreateShowModal();
var vv:TForm2;
    i:integer;
begin
 vv:=TForm2.Create(Application);
 vv.Show;
 for i:=0 to MDIChildCount-1 do
  EnableWindow(MDIChildren[i].Handle,false);
 EnableWindow(vv.Handle,true);
end;


И гл́авное! Не забываем востановить все при закрытии "модальной" MDIChild формы smile :
Код
uses Unit1;

{$R *.dfm}

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
var i:integer;
begin
 Action:=caFree;
 for i:=0 to Form1.MDIChildCount-1 do
  EnableWindow(Form1.MDIChildren[i].Handle,true);
end;

Автор: StayAtHome 6.4.2005, 20:48
Петрович
Ты угадал, я создаю формы-экземпляры одного класса, но некоторые -- модальные, а некоторые нет. Такой изврат нужен для отображения таблиц БД связанных по Foreign Key. Т. е. при добавлении записи в таблицу в которой есть FK на другую, пользователь значение поля по которому создан FK сможет выбирать из формы-справочника, которая, естественно, должна отображаться в модальном режиме. Если же мне нужно просто посмотреть/поправить справочники -- та же форма (точнее другой ее экземпляр) должна открываться в обычном режиме (немодальном).
Возможно это все дикий изврат, но мне показалось так удобнее и мне и пользователю. smile

Girder
Это уже интересней! (аж стыдно, что сам не догадался) Попробую. Пока сделал на OnDeactivate
Код

procedure MDIChildFormDeactivate(Sender: TObject);
begin
if IsModal then
  begin
  BringToFront;
  SetFocus;
  end;
end;

Автор: Medved 10.4.2005, 23:19
Цитата
Правда мне все равно не понятно зачем такое делать. По своей природе, дочернии MDI-окна равноправны. А ты хочешь сделать как всегда: все равны, но некоторые ровнее. smile


Согласен на сто процетов. smile

Я так и не понимаю зачем это делать. В этом решении больше геммороя, чер практической пользы.

Автор: icc 11.4.2005, 08:58
Не знаю насколько это правильно, но я использую такую конструкцию.
Форма создается при вызове.

with TEmterpriseCard.Create(Application) do
begin
// код до создания
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)