przez Cyfrowy Baron » wtorek, 12 października 2010, 10:14
Funkcja SetFocus ustawia fokus na obiekt w odniesieniu do którego została wywołana, czyli czyni ten obiekt aktywnym, gdyż w aplikacji okienkowej tylko jeden obiekt na raz może być aktywny. NIe działa to na wszystkie obiekty.
Załóżmy, że masz na formularzu kilka obiektów np. Button1, Edit1, Memo1 i chcesz po kliknięciu na przycisku Button1 przejść do pola Edit1, czyli uczynić obiekt Edit1 aktywnym, czyli ustawić focus na ten obiekt. Gdy klikasz na przycisku Button1 to focus jest automatyczni ustawiany na ten przycisk, ale wstawiając w zdarzenie OnClick tego przycisku odpowiedni kod możesz zmienić focus na inny obiekt:void __fastcall TForm1::Button1Click(TObject *Sender)
{
Edit1->SetFocus();
}
Przećwicz to a zrozumiesz w czym rzecz.
Funkcja ProcessMessages() odświeża kolejkę komunikatów, czyli pozwala na pobranie oczekującego komunikatu. Prościej? Gdy np. program jest zajęty jakaś czynnością, np. długo wykonującą się pętlą to nie jest w stanie odbierać komunikatów napływających do aplikacji. Wtedy te komunikaty odkładają się w kolejce i czekają, aż aplikacja zakończy wykonywanie operacji, wtedy pobiera kolejne komunikaty z kolejki i je wykonuje. Funkcja ProcessMessages pozwala przerwać na chwilę operację wykonywaną przez program by ten mógł obsłużyć komunikaty oczekujące w kolejce.
Załóżmy, że uruchamiasz w programie pętlę, która wykonuje się w nieskończoność. Jeżeli nie odświeżysz kolejki komunikatów w każdym obiegu pętli, lub co któryś obieg, to aplikacja cały czas będzie wykonywała jedno zadanie, czyli pętlę.
Umieść na formularzu dwa przyciski Button1 i Button2. W zdarzeniu OnClick przycisku Button1 umieść pętlę wykonującą się w nieskończoność, a w przycisku Button2 umieść polecenie zamknięcia aplikacji:
bool przerwij = false;
void __fastcall TForm1::Button1Click(TObject *Sender)
{
for(;;)
{
/* tutaj jakieś obliczenia */
if(przerwij == true) break;
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
przerwij = true;
Close();
}
Nie będziesz mógł wcisnąć przycisku Button2 gdyż aplikacja wygląda tak jakby się zawiesiła, a to dlatego, że jest zajęta jednym zadaniem i nie przyjmuje żadnych komunikatów, dopóki tego zadania nie zakończy. Wszystkie komunikaty wysyłane do aplikacji odkładają się w kolejce i czekają na zakończenie zadania przez aplikację, ale to się nigdy nie stanie, gdyż pętla działa w nieskończoność.
By móc nacisnąć przycisk Button2, żeby pobrać komunikat z kolejki należy w pętli for umieścić funkcję ProcessMessages. Z pętlą jest jednak ten problem, że aby można było zamknąć aplikację, pętla musi zakończyć działanie, w przeciwnym razie nawet po wydaniu polecenia zamknięcia program i tak będzie czekał na zakończenie pętli by wykonać to polecenie, dlatego dodałem zmienną przerwij, która w przypadku zmiany stanu na true, przerywa działanie pętli. Od razu da się zauważyć, że funkcja ProcessMessages coś zmieniła - możesz teraz kliknąć na przycisk Button2, a wcześniej nie było to możliwe. Dzieje się tak dlatego, że teraz w każdym obiegu pętli program sprawdza kolejkę komunikatów i wykonuje te komunikaty nim wykona kolejny obieg pętli.
bool przerwij = false;
void __fastcall TForm1::Button3Click(TObject *Sender)
{
for(;;)
{
/* tutaj jakieś obliczenia */
if(przerwij == true) break;
Application->ProcessMessages();
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
przerwij = true;
Close();
}
By zamknąć aplikację, która nie daje się zamknąć, a uruchomioną przez IDE środowiska C++Builder, wybierz w menu tego środowiska polecenie: Run Program Reset, lub naciśnij Ctrl + F2.
By zamknąć aplikację, która nie daje się zamknąć, a uruchomioną poza środowiskiem C++Builder uruchom Menadżera Zadań, na pierwszej zakładce Aplikacje odszukaj swój program na liście Zadanie, zaznacz go i kliknij na przycisku Zakończ zadanie. Nie rób tego numeru z Menadżerem Zadań, gdy uruchomiłeś program poprzez IDE C++Builder'a, gdyż może to spowodować zawieszenie się tego środowiska.
-
Za ten post autor Cyfrowy Baron otrzymał podziękowanie od:
- niemamkolan