Zmiana okna modalnego na niemodalne.

dział ogólny

Zmiana okna modalnego na niemodalne.

Nowy postprzez Cyfrowy Baron » niedziela, 27 grudnia 2009, 19:53

Uruchamiam okno programu jako modalne:

Kod: Zaznacz cały
Form2->ShowModal();


Jak z poziomu tego okna zmienić jego stan na niemodalne?
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana

Re: Zmiana okna modalnego na niemodalne.

Nowy postprzez mckri » wtorek, 29 grudnia 2009, 15:09

Może to w czym pomoże. Zdaje się, że nalezy wysłac odpowiednie komunikaty do formularza.
http://blogs.teamb.com/deepakshenoy/2006/08/21/26864

Za ten post autor mckri otrzymał podziękowanie od:
Cyfrowy Baron
Avatar użytkownika
mckri
Intelektryk
Intelektryk
 
Posty: 160
Dołączył(a): piątek, 15 sierpnia 2008, 13:48
PodziÄ™kowaÅ‚ : 10
OtrzymaÅ‚ podziÄ™kowaÅ„: 2
System operacyjny: Windows Vista SP2
Kompilator: BCB 5/2007/2009
    NieznanyNieznana

Re: Zmiana okna modalnego na niemodalne.

Nowy postprzez Cyfrowy Baron » poniedziaÅ‚ek, 4 stycznia 2010, 15:17

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.
Avatar użytkownika
Cyfrowy Baron
Administrator
Administrator
 
Posty: 4716
Dołączył(a): niedziela, 13 lipca 2008, 15:17
PodziÄ™kowaÅ‚ : 12
OtrzymaÅ‚ podziÄ™kowaÅ„: 442
System operacyjny: Windows 7 x64 SP1
Kompilator: Embarcadero RAD Studio XE2
C++ Builder XE2 Update 4
SKYPE: cyfbar
Gadu Gadu: 0
    NieznanyNieznana


Powrót do Ogólne problemy z programowaniem

Kto przeglÄ…da forum

Użytkownicy przeglądający ten dział: Google [Bot] i 6 gości