Problem z śledzeniem zmian w właściwości komponentu

0

Dobry wieczór
Piszę sobie komponent w Delphi, i mam taki problem.
Fragment kodu:

unit Thumbs;
{$R *.dcr}
interface
type TKlasa=class
public
   ...
   zmienna1:boolean;
   zmienna2:boolean;
   procedure procka;
end;
type TKlasaGlowna=class(TComponent)
private
  ...
  FKlasa:TKlasa;
  procedure SetKlasa(x:TKlasa);
published
  ...
 property Klasa:TKlasa read FKlasa write SetKlasa;
 ...
end;
implementation
...
procedure TKlasa.procka;
begin;
 zmienna2:=not zmienna2;
end;
procedure TKlasaGlowna.SetKlasa(x:TKlasa);
begin;
 showmessage('Zmiana');
FKlasa:=x;
end;
...
end.

I teraz główna część problemu.
Jeżeli jakaś tam część przykładowego programu zmieni zawartość zmienna1 poprzez coś takiego:

var KlasaGlowna:TKlasaGlowna;
...
 KlasaGlowna.Klasa.Zmienna1:=true;

wtedy jak wiadomo nastąpi przekazanie sterowania do:

procedure TKlasaGlowna.SetKlasa(x:TKlasa);
begin;
 showmessage('Zmiana');
FKlasa:=x;
end;

i wyświetlenie komunikatu.Jednym słowem zostanie zauważona zmiana w klasie

A jak wykona coś takiego:

var KlasaGlowna:TKlasaGlowna;
...
 KlasaGlowna.klasa.procka;

i procedura zmieni wartość zmiennej zmienna2, to ta zmiana dla procedury SetKlasa przejdzie nie zauważona.
Czy da się to jakoś zmienić, za pomocą jakieś klauzuli, bądź czegoś innego?

Thx

0

Możesz zrobić właściwość OnChange w klasie TKlasa
składowe zmienna1 i zmienna2 zrobić prywatnymi i zmienić nazwy na fzmienna1 i fzmienna2
dopisać właściwości zmienna1 i zmienna2 read bezpośrednio zaś write wywołuje setZmienna1 i setZmenna2;
Podobnie jest zrobiona klasa TFont, każdy komponent ma właściwość Font, podpina się pod OnChange i wie kiedy cokolwiek zmieniło składowe.

procedure TKlasa.setZmenna2(Value:Boolean);
begin
  if fzmenna2<>Value then
  begin
     fzmenna2:=Value;
     if Assigned(OnChange) then OnChange(Self);
  end;
end;

procedure TKlasaGlowna.Zmiana(Sender:TObject);
begin
  showmessage('Zmiana');
end;

procedure TKlasaGlowna.SetKlasa(x:TKlasa);
begin;
   if FKlasa<>x then
   begin
      FKlasa:=x;
      FKlasa.OnChange:=Zmiana;
      Zmiana(FKlasa);
   end;
end;
0

Pierwotnie miałem taki zamysł aby tak zrobić, ale myślałem że będzie jakiś ładniejszy sposób.
Ale trudno, inaczej się chyba nie da.

Dziękuję za zainteresowanie.

0
gandzia400 napisał(a)
 ...
 property Klasa:TKlasa read FKlasa write SetKlasa;
 ...

i wyświetlenie komunikatu.Jednym słowem zostanie zauważona zmiana w klasie

not true - komunikat się nie pojawi gdyż nie jest wywoływane SetKlasa a jedynie odczyt FKlasa. Aby nastąpiło wywołanie SetKlasa musiał byś wykonać coś takiego

KlasaGlowna.Klasa := InnaKlasa;
  1. Odnośnie pkt. 1 - pisanie właściwości klasowych jako read/write a nie tylko read to proszenie się o kłopoty - wystarczy, że gdzieś w kodzie zrobisz
KlasaGlowna.Klasa := nil;

i już masz po pierwsze wyciek pamięci bo zmienna FKlasa nigdy nie zostanie zwolniona bo właśnie straciłeś do niej referencję a po drugie dostaniesz AV w destruktorze TKlasaGlowna, przy próbie wywołaniaFKlasa.Free;

3. jeśli chcesz być powiadamiany o zmianach właściwości to musisz je zrobić właściwościami a nie zmiennymi (tak jak podał Ci trzynasty)
0

Pierwotna koncepcja była taka, że Klasa nie była właściwością, a normalną zmienną w sekcji public, tworzoną w konstruktorze i zwalnianą w destruktorze TKlasaGlowna.
Podczas jej tworzenia KlasaGlowna, przypisywała procedurę obsługi zdarzenia, tak jak to napisał _13th_Dragon, chciałem tylko sprawdzić, czy nie można tego zrobić jakoś inaczej,schludniej.

Dziękuję za odpowiedzi

0

Jak skończę pisać ten komponent, to może go tu wrzucę żeby ktoś ocenił

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