Jak szybko zablokować wszystkie komponenty na formie?

0

Witam muszę napisać procedurę która szybko zablokuje wszystkie komponenty na formie a potem je odblokuje. Może to polegać na ustawiania wszystkich enabled na False.

Generalnie chodzi mi o taki efekt:

Form1 -> klikam button -> Tworzy się nowa forma2 i jest aktywna a forma 1 jest zablokowana.

Prawie idealnie nadawała by się procedura showmodal, prawie bo po wywołaniu showmodal dalsze wykonywanie programu jest wstrzymywane a ja muszę uzyskać efekt aby nie bylo wstrzymania programu az do zamkniecie okna modalnego..

0

Zapomniałem dodać czy da sie to zrobić jakoś prościej niż

button1.enabled := False;
label.enabled := False;
.....
.....
.....
panel.enabled := False;

0

Na przykład tak:

var
  i: Integer;
  MyComponent: TComponent;
begin
  for i:=0 to ComponentCount - 1 do
  begin
    MyComponent:= Components[i];
    if MyComponent is TControl then
      TControl(MyComponent).Enabled:= False;
  end;
end;

lub tak

procedure DisableAll(AParent: TWinControl);
var
  i: Integer;
  ctrl: TControl;
begin
  for i:= 0 to AParent.ControlCount -1 do
  begin
    ctrl:= AParent.Controls[i];
    ctrl.Enabled:= False;
    if ctrl is TWinControl then
      DisableAll(TWinControl(ctrl));
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  DisableAll(Form1);
end;
0
Rafał D napisał(a)

Generalnie chodzi mi o taki efekt:

Form1 -> klikam button -> Tworzy się nowa forma2 i jest aktywna a forma 1 jest zablokowana.

Taki efekt możesz uzyskać po prostu blokując cały formularz i to jest najszybsze rozwiązanie; To samo uzyskasz wywołując Form2 modalnie;

Nie rozumiem jaki efekt chcesz osiągnąć, bo jeśli wszystkie kontrolki na Form1 zostaną zablokowane, to po co Ci aktywny formularz, skoro i tak nic na nim nie klikniesz? Jeśli chcesz pozostawić jedynie możliwość zamknięcia pierwszego formularza w momencie, gdy Form2 jest aktywne - wykorzystaj sposób @kAzek, a jeśli nie jest Ci to potrzebne, to nie komplikuj sobie sprawy i po prostu zablokuj cały formularz;

Zawsze możesz rozbudować podaną wyżej procedure po to, by mieć jedną do blokowania i odblokowywania kontrolek:

procedure EnableFormControls(AParent: TWinControl; AState: Boolean);
var
  I: Integer;
  Ctrl: TControl;
begin
  for I := 0 to AParent.ControlCount - 1 do
  begin
    Ctrl := AParent.Controls[I];
    Ctrl.Enabled := AState;

    if Ctrl is TWinControl then
      EnableFormControls(TWinControl(Ctrl), AState);
  end;
end;

Wywołanie jak powyżej;

0

Klikasz Button a tam piszesz:
Form2.ShowModal; // Nie Form2.Show;

0

Dziękuję za odpowiedzi. Może trochę niejasno się wyraziłem dlaczego nie może być showmodal. Postaram się to bardziej opisać i podać prosty przykład;

{Form1}
var X : Integer;

Procedure Form1.button;
begin
   X := 50;
end;

Procedure Form1.ProceduraA;
Begin
   X  := 0;
   Form2 := TForm2.Create;
   Form2.Visible := True;
   ->Tu<- {Zablokuj wszystkie komponenty <--}
   Repeat
      Inc(X);
      sleep(1000);
      Application.ProcessMessage;
      Form2.ProceduraB(X);
   Until X = 1000;
   Form2.Close;
End;    

Procedure  Form2.ProceduraB(p: integer);
begin
  Gauge.Progress := P;
  Gauge.UpDate;
end;

//Opis teoretycznego działania;

Rozpoczynamy wykonywanie proceduryA.
Stwarzane jest okno z paskiem postępu po doliczeniu X do 1000 okno jest zamykane.
Zablokować komponenty muszę po to aby podczas wykonywania proceduryA nie było można wykonać żadnej innej procedury aż do zakończenia proceduryA. Jeśli tego nie zrobię to mogę kliknąć buttona który nagle zmieni dane X;
Okienka modalnego nie mogę stworzyć gdyż proceduraA nie zostanie wcale wykonana (można rzec zawiesi się w takim przypadku)

0

Chyba już zmęczenie jak mogłem o tym nie pomyśleć żeby zrobic to tak jak zasugerowaliście tj: Form1.Enabled := False;

0

Zablokować komponenty muszę po to aby podczas wykonywania proceduryA nie było można wykonać żadnej innej procedury aż do zakończenia proceduryA.

No tak, wszelkie kontrolki zablokujesz, ale nie formularz, więc podczas "odliczania" w dalszym ciągu będziesz go mógł:

  • zamknąć,
  • zmaksymalizować/przywrócić,
  • zminimalizować,
  • przenieść,
  • zmienić rozmiar
    czyli to, czego byś nie chciał; Blokując cały formularz nie tylko ograniczasz dostęp do wszelkich kontrolek, ale i także do samego formularza, więc to rozwiązanie będzie jedynym sensownym;

Okienka modalnego nie mogę stworzyć gdyż proceduraA nie zostanie wcale wykonana (można rzec zawiesi się w takim przypadku)

Zatrzyma się rzecz jasna, lecz pod warunkiem, że wykonywana procedura będzie zaimplementowana w klasie Form1; Jeśli stworzysz sobie własne okno dialogowe (poczytaj o podstawach) i w metodzie Execute wykonasz wszystkie potrzebne operacje to program nie zawiesi się; Wystarczy tylko trochę pogłówkować i efekt będzie zadowalający;

0

Jest jeszcze trochę "brzydki" sposób - ustawić image i w razie potrzeby zmieniać visible. Wyłączanie kontrolek wiąże się z problemem przywracania ich stanu (np. gdy kilka było wyłączone przed wyłączeniem wszystkich), więc w międzyczasie trzeba je gdzieś przechować a ten sposób jest generalnie najszybszy i dla użytkownika chyba najmniej upierdliwy (tak jak przez enable=false na formie).

0

A czemu nie zrobić po ludzku:

{Form1}

Procedure Form1.ProceduraA;
Begin
   TForm2.Create.ShowModal;
End;    
 
procedure  Form2.FormShow(Sender:TObject); // koniecznie podłączyć
begin
   Repeat
      sleep(1000);
      Application.ProcessMessage;
      Tag:=Tag+1;
      Gauge.Progress:=Tag;
      Gauge.UpDate;
   Until Tag=1000;
   Close;
end;

procedure  Form2.FormClose(Sender:TObject;var Action:TCloseAction); // koniecznie podłączyć
begin
  Action:=caFree;
end;

procedure  Form2.FormCloseQuery(Sender:TObject;var CanClose:Boolean); // koniecznie podłączyć
begin
  CanClose:=(Tag>=1000);
end;
0
szopenfx napisał(a)

Jest jeszcze trochę "brzydki" sposób - ustawić image i w razie potrzeby zmieniać visible.

A jak chcesz to wykonać? Przecież TImage jest kontrolką bez fokusa, więc zawsze będzie się znajdować pod tymi kontrolkami z fokusem nawet, jeśli będzie widoczna - BringToFront nie pomoże; Nie ma możliwości przesłonić standardowych kontrolek bez dodatkowego kombinowania np. z jeszcze jednym formularzem;

Lepiej przestać cudować i najnormalniej w świecie stworzyć własne okieno dialogowe i w jego klasie zaimplementować ten algorytm "odliczania" lub tak jak pokazał @_13th_Dragon - sterować formularzem z zewnętrznej (dla niego) procedury;

1 użytkowników online, w tym zalogowanych: 0, gości: 1