Wskaźnik na formę

0

Witam,
piszę program w którym będzie sobie pewna zdefiniowana wcześniej forma, i będzie tworzona dynamicznie w bliżej nieokreślonych ilościach.
Nie chcę robić tablicy form bo po otwarciu i zamknięciu 100 form dalej będą zajmowały miejsce w pamięci (chyba że się mylę).
Wykombinowałem sobie że zrobię tablicę wskaźników, ale póki co (na razie bez tablicy, jeden wskaźnik) nawet tyle nie chce ruszyć.
Gdzieś tam na górze:

MagDetails:^TForm5;

i 2 procedurki:procedure TForm1.MagDblClick(Sender: TObject);
var
Form:TForm5;
begin
if(Mag.Selected=nil) then
exit;
Form:=TForm5.Create(nil);
Form.Caption:='ID' + Mag.ItemFocused.Caption;
Form.Show;
MagDetails:=@Form;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
MagDetails^.Opakowanie.Caption:='qwerty';
end;

w pierwszej procedurze wszystko działa, a w drugiej w linii `MagDetails^.Opakowanie.Caption:='qwerty';` jest błąd access violation...
Ogólnie rozumiem po co są wskaźniki tylko brakuje mi praktyki ;)
0

U mnie tak działa:

var
  Form1: TForm1;
  Form : TForm2;
  Wsk  : ^TForm2;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form := TForm2.Create(Nil);
 Form.Caption := 'ID: ...';
 Form.Show;
 Wsk := @Form;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Wsk^.Memo1.Text := 'Hello';
end;

Ty coś musiałeś źle zrobić...


Swoją drogą, jak zadeklaruje się Form: TForm2 w Button1Click, to zmiana czegokolwiek poprzez wskaźnik powoduje zmianę caption Button2
Ciekawe ;)

0

Ogólnie to większego pojęcia nie masz o tym o czym piszesz

Nie chcę robić tablicy form bo po otwarciu i zamknięciu 100 form dalej będą zajmowały miejsce w pamięci (chyba że się mylę).
mylisz się - jeśli coś zostało zniszczone nie zajmuje miejsca w pamięci. BTW taka tablica już istnieje - Screen.Forms, Screen.FormCount

Wykombinowałem sobie że zrobię tablicę wskaźników
wiesz ile zajmuje taka zmienna w pamięci Form: TForm5;? - dokładnie tyle samo ile taka Form: ^TForm5; - zmienna klasowa to tak naprawdę wskaźnik tylko traktowany specjalnie (nie trzeba używać ^, pamięć rezerwuje się przez TKlasa.Create a zwalnia przez Free) przez delphi.
Zamiast wymyślać sztuczne problemy lepiej postaraj się, żebyś nie miał wycieków pamięci i AV bo widzę, że będziesz miał albo jedno albo drugie

0

czyli mogę spokojnie zrobić tablicę MagDetails:array of TForm5; tak? bo gdzieś na forum był podobny kod i tak ktoś kogoś zj... pouczył, że wyszło że lepiej to zrobić przez FindComponent. BTW tak właśnie zrobiłem w trakcie czekania na odpowiedź tutaj i działa. I nawet dałem Create(self) i samo się zniszczy na końcu ;)
Patryk27, jak już deklaruję zmienną Form tak jak Ty w tym kodzie, to wskaźnik mogę już sobie raczej odpuścić ;) chodziło mi o to że jak w procedurze jest var Form:TForm5; to póki procedura się wykonuje mam władzę nad formą przez Form.cośtam ale potem forma zostaje a "uchwyt" do niej znika, i właśnie dlatego chciałem zrobić tablicę wskaźników.

0
  1. zamiat array of TForm5 zainteresuj się TList
  2. listę form już masz - Screen.Forms
  3. co do zjebania to szukanie formy przez FindComponent to taki średni pomysł
  4. I nawet dałem Create(self) i samo się zniszczy na końcu czyli jak user otworzy na początku 1000 form i zaraz je wszystkie zamknie to zniszczone one zostaną DOPIERO jak wyłączy program. No a potem się ludzie dziwią że windows się wiesza, zamula i jest do d**y...
0

no fakt, to dać Free do OnClose tej formy?
a FindComponent świetnie się póki co sprawdza-po utworzeniu formy ustawiam jej nazwę na 'ID' + id z bazy mysql, potem przypisuję tam gdzie potrzebna: Form:=TForm5(Self.FindComponent('ID'+ id_z_bazy)); czy coś w tym stylu, z pamięci piszę.

0

poczytaj co można przypisać do zmiennej Action ze zdarzenia OnClose

0

Misiekd, dzięki za wskazówkę..
a powiedzcie, czy wskaźniki na klasy tworzy się jakoś inaczej niż na zwykłe zmienne?
mam TreeView, i w nim drzewko kategorii, w drzewku są oczywiście same nazwy, a .AbsoluteIndex itema to nie jest to samo co ID z bazy. więc mam taką zmienną:

CatIDs:array of ^TTreeNode;

gdzieś tam w kodzie jest:

        	Current:=Kategorie.Items.AddChild(Current,Form1.Query.FieldByName('name').AsString);
          CurrentID:=Form1.Query.FieldByName('id').AsInteger;
          if(CurrentID>=Length(CatIDs)) then
          	SetLength(CatIDs,CurrentID+1);
            CatIDs[CurrentID]:=@Current;

a w innej funkcji:

	Kategorie.Selected:=CatIDs[id]^;

no i niezmiennie access violation...kończą mi się pomysły :/

EDIT: teraz dopiero skojarzyłem (tak myślę ;) ) o co chodziło Misiekd w pierwszym poście-wywaliłem ^ i @ z tego kodu i działa wszystko.
Bo myślałem że jak gałąź drzewka będzie w Drzewku i w mojej tablicy, to zajmie 2 razy więcej pamięci, ale skoro nazwa klasy to tylko wskaźnik to mogę sobie daszki i małpy odpuścić ;)

0

gdzieś tam w kodzie jest:

                Current:=Kategorie.Items.AddChild(Current,Form1.Query.FieldByName('name').AsString);
          CurrentID:=Form1.Query.FieldByName('id').AsInteger;
          if(CurrentID>=Length(CatIDs)) then
                  SetLength(CatIDs,CurrentID+1);
            CatIDs[CurrentID]:=@Current;

a teraz powiedz mi co będziesz miał w tablicy jak najpierw dostaniesz ID=5, potem ID=3 a na końcu ID=4

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