Wątki i komponenty

0

Na formie mam kilka editów i chciałem żeby aktualnie zafocusowany edit robił się żółty a reszta ma być biała. Takie wizualne zaznaczanie aktywnego edita.
Chciałem zrobić to sobie na wątku - tak dla nauki.
Robię coś takiego:

Type
  TKolorAktywny = class(TThread)
    protected
    procedure Execute; override;
  end;

var
  KolorAktywny : TKolorAktywny;

procedure TKolorAktywny.Execute;
 var i : integer;
begin
  FreeOnTerminate := True;
  while not (Application.Terminated) or (Terminated) do
  begin
    for i := 0 to Forma1.ComponentCount - 1 do
      begin
        if Forma1.Components[i] is TEdit then
          begin
            if TEdit(Forma1.Components[i]).Focused then
              TEdit(Forma1.Components[i]).Color := clYellow
             else
              TEdit(Forma1.Components[i]).Color := clWhite;
          end;
      begin
    sleep(200);
  end;
end;

initialization
  KolorAktywny := TKolorAktywny.Create(true);

Dla OnShow formy daję :

KolorAktywny.Resume

a dla OnClose daję:

KolorAktywny.Suspend

No i kiszka bo to nic nie daje.
Czego nie wiem o wątkach?
Czy w wątku sprawdzanie Focused komponentu nie działa ?
Bo zauważyłem że znajdują mi się te komponenty typu TEdit ale już mi nie sprawdza czy akurat jest w nich kursor.
Gdybym dał taką procedurkę w powiedzmy Timerze to to będzie chodziło, a w wątku nie chce.
[???] [glowa]

0

masz źle skonstruowany ten warunek: while not (Application.Terminated) or (Terminated) do
zastanów się, co się stanie, jeśli Application.Terminated = true i Terminated = true...
suspend nic nie da, bo pauzuje wątek, ale go nie zatrzymuje, a jeśli chociaż jeden wątek procesu działa, to proces nie jest zamykany. zamiast suspend daj terminate, albo ustaw terminated na true (i popraw ten skaszaniony warunek zkończenia pętli).

druga sprawa - NIGDY nie zmieniaj właściwości wizualnych komponentów w wątku. użyj do tego Synchronize().

trzecia - sprawdź pod debugerem, co zwraca Focused. sprawdź też, czy pętla na pewno działa prawidłowo w głównym wątku aplikacji, np. w timerze.

czwarta i najważniejsza - po kiego grzyba używasz wątku do przełączania kolorków przy zmianie focusa? obsłuż odpowiednie zdarzenia - onEnter, onExit.

0

a najlepiej zrobić sobie własny komponent, który będzie to robił za Ciebie

0

ad.1
Faktycznie, nie zauważyłem z tym Suspend i Terminated w OnClose formy. To sobie zaraz poprawię.
ad.2
Dlaczego nie można zmieniać właściwości komponentów wizualnych w wątkach ? Możesz coś więcej napisać bo szczegółów nie mogę nigdzie znaleźć.
ad.3
Za debuggera wezmę się wieczorkiem i sprawdzę.
ad.4
chciałem to zrobić w wątku bo chcę pouczyć się troszkę o wątkach. Zadanie dla wątku dobre jak każde inne a nauka i powiększenie wiedzy zawsze zostaje.
Oprogramowanie onExit i onEnter to już umiem ;)

W każdym razie dziękuję bardzo za pomoc i wieczorkiem spróbuję posiedzieć nad problemem i się troszkę podszkolić w wątkach.

0

Ad2. bo komponenty wizualne są obsługiwane także przez główny wątek; jeśli w tym samym momencie Twój wątek i użytkownik będą coś chcieli od tego samego komponentu, to masz problem (jeśli chociaż jeden z wątków zapisuje). to nie ogranicza się do komponentów, tylko do wszystkich elementów, przy których może wystąpić konflikt dostępu.

nie chodzi o Synchronize, równie dobrze może być to każda inna metoda gwarantująca, że w tym samym momencie tylko jeden wątek zapisuje/czyta z danego elementu (sekcje krytyczne, muteksy, semafory, eventy, nawet komunikaty - poczytaj o IPC).

zastanów się co się stanie, jeśli jeden wątek zapisuje to, co drugi w tym samym momencie czyta.

0

Dzięki bardzo za wyjaśnienie.
pozdrawiam
[browar]

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