Podaję rozwiązanie, być może kiedyś komuś będzie to potrzebne tak jak mi.
Posłużę się prostym przykładem.
Mamy dwa formularze:
Form1 - okno główne i
Form2 - okno wtórne.
Na
Form1 w zdarzeniu
Form1->Buttton1->OnClick wywołujemy okno wtórne jako modalne:
- Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2->ShowModal();
}
W ten sposób wywołany zostaje formularz
Form2, ale
Form1 jest teraz nieaktywny i nie można wykonywać w nim żadnych operacji, dopóki
Form2 nie zostanie zamknięty.
Stan okna
Form2 można zmienić na niemodalny, trzeba w tym celu po pierwsze uczynić go nieaktywnym, czyli zmienić mu właściwość
Enabled na
false. Można to zrobić na dwa sposoby. Pierwszy sposób to po prostu ustawić mu właściwość
Enabled na
false, drugi to wysłać komunikat za pomocą funkcji
EnableWindow. Po drugie trzeba uaktywnić okno główne
(i wszystkich inne widoczne okna w programie) zmieniając mu właściwość
Enabled na
true, to jednak można zrobić tylko wysyłając komunikat za pomocą funkcji
EnableWindow. Po trzecie trzeba ponownie uaktywnić okno wtórne
Form2 zmieniając mu właściwość
Enabled na
true, w jeden z podanych sposobów.
Przykład zmiany modalnego okna Form2 na niemodalne po kliknięciu w zdarzenie
Form2->Button1->OnClick:
- Kod: Zaznacz cały
#include "Unit1.h"
void __fastcall TForm2::Button1Click(TObject *Sender)
{
this->Enabled = false;
EnableWindow(Form1->Handle, true);
this->Enabled = true;
}
Od teraz obydwa okna są aktywne, jednak co ciekawe, to że okno wtórne
Form2 zawsze pozostaje na wierzchu mimo iż ma właściwość
FormStyle = fsNormal, czyli po uaktywnieniu
Form1 powinno się za nim chować, tak się jednak nie dzieje. Póki co nie wiem jak to zmienić, gdyż mi akurat potrzebne jest dokładnie takie zachowanie, czyli okno wtórne na górze. Dlaczego akurat tak jest lepiej? A no dlatego, że jeżeli np. uruchomimy okno wtórne poleceniem
Show(), czyli niemodalne i ustawimy je tak by zawsze było na wierzchu, czyli
FormStyle = fsStayOnTop, a następnie wywołamy w tym oknie komunikat funkcją np.
ShowMessage(""), to tenże komunikat schowa się za oknem wtórnym i nie będzie widoczny. Można oczywiście wywołać okno komunikatu
MessageBox z flagÄ…
MB_SYSTEMODAL lub
MB_APPLMODAL, ale nie o to teraz przecież chodzi.
Po takiej modyfikacji okien, można oczywiście uczynić okno
Form2 znów modalnym, ale tylko poprzez wyłączenie innych okien, czyli w przykładzie trzeba zmienić właściwość
Enabled formularza
Form1 na
false. Można to zrobić zarówno z poziomu
Form1 jak i
Form2.
Na przykład w zdarzeniu
Form2->Button2->OnClick:
- Kod: Zaznacz cały
#include "Unit1.h"
void __fastcall TForm2::Button2Click(TObject *Sender)
{
EnableWindow(Form1->Handle, false);
}
Można też tak zmodyfikować zdarzenie
Form1->Button1->OnClick by w zależności od tego czy okno
Form2 jest uruchomione czy nie, albo je wywoływało jako modalne, lub zmieniało jego stan na modalny:
- Kod: Zaznacz cały
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(!Form2->Visible) Form2->ShowModal();
else EnableWindow(this->Handle, false);
}
Jeżeli wywołujemy okno wtórne z okna głównego i po twych wszystkich operacjach zamkniemy to okno wtórne, to okno główne automatycznie zmieni stan
Enabled na
true, ale nie stanie się tak w przypadku innych okien też wtórnych, jeżeli mamy ich więcej w programie. Dlatego zamykając okno wtórne
Modalne <-> Nie-Modalne należy wysłać do wszystkich otwartych okien komunikat
EnableWindow(NazwaFormularza->Handlem, true) by je uaktywnić, w przeciwnym razie wszystkie okna za wyjątkiem głównego, którym wyłączono
(Enabled = false) pozostanÄ… nieaktywne.