Zwalnianie pamięci po formatce

0

Witam!

To już moje drugie pytanie w ciągu tygodnia - nie jest dobrze ;-)

A więc tak. Mam formę w pliku DLL i eksportuję z niego parę funkcji, m.in. ShowForm, która tworzy dynamicznie nową instancję formy i ją pokazuje. Problem leży w tym, że gdy taką formę zamknę [x] to nie jest zwalniana pamięć po niej.
Pytanie jest oczywiście takie: czy i jak można automatycznie zwalniać pamięć po zamykanej formie.

Na razie wymyśliłem takie rozwiązanie:
W OnCloseQuery zabraniam zamykania formy i powiadamiam program główny, że dana forma ma być zamknięta. Aplikacja nadrzędna dostaję taką informację i wywołuje specjalną eksportowaną funkcję, która zwolni pamięć wskazanej formy.

Trochę to przypomina ping-pong, ale chyba tak to będzie musiało wyglądać. Szczególnie, że każdy obiekt w programie głównym (jego wizualną reprezentacją jest właśnie ta forma) musi posiadać swoje niezależne zmienne, więc chyba utworzę wektor struktur. W każdej strukturze dam potrzebne mi zmienne oraz pole, które będzie wskaźnikiem do formatki. Wtedy powyższa funkcja ShowForm będzie dodawała do wektora nową strukturę, tworzyła dynamicznie formę i jej wskaźnik przypisywała do odpowiedniego pola.

Wtedy przy zamykaniu formy aplikacja główna będzie wywoływała funkcję, która zwolni zarówno pamięć po formie, jak i wyrzuci daną strukturę z wektora.

Co o tym myślicie - czy to dobry pomysł? A może ktoś ma ciekawsze rozwiązanie? Jeśli coś jest niejasne, to pytać. Wyjaśnię.

0

Nie wiem czy to możliwe, ale czy nie lepiej napisać destruktor, który zwolni pamięć ?

0

Dzięki za chęci, ale widać, że nie znasz podstaw programowania obiektowego.
Destruktor jest wywoływany przy niszczeniu obiektu. A ja właśnie pytam, jak go niszczyć.

0

ja sie przyłączam do pytania bo miałem podobny problem, też go rozwiązałem za pomocą jak to określiłeś heh "ping - ponga"

0

Witam!
A nie można by dla tej formy oprogramować zdarzenie OnClose. Tam jest taki parametr jak Action i można by go ustawić na caFree. Może pomoże :-)

0

Ja może podam nieco odmienne rozwiązanie: przeniesienie klasy z DLLa i utworzenie formy dopiero w programie (bibliotekę można spokojnie odłączyć). Kod w delphi, ale czyje niby jest to "wybacz BCB, przetłumaczysz sobie"? :P Do rzeczy.

W bibliotece:

library Test;
uses
  {tutaj moduł z formą i ew. inne potrzebne, przede wszystkim Forms};

type
  TFormClass = class of TForm;

function GetFormClass: TFormClass;
begin
  Result:=TTestForm; // czy jak tam się klasa nazywa
end;

exports
  GetFormClass;

begin
end.

W programie:

...
type
  TFormClass = class of TForm;
...

procedure LoadDLLForm(const LibName: string);
var HLib: THandle;
  TmpForm: TForm;
  TmpFormClass: TFormClass;
  GetFormClass: function: TFormClass;
begin
  HLib:=LoadLIbrary(PChar(LibName));
  @GetFormClass:=GetProcAddress(HLib,'GetFormClass');
  TmpFormClass:=GetFormClass;
  //FreeLibrary(HLib);
  //kod, który faktycznie kopiuje dane gdzieś mi się zapałętał, a to przeniesie tylko wskaźnik więc odłączenie biblioteki usunie wskazywane dane. Dla ciebie to chyba nic trudnego do poprawienia.
  TmpForm:=TmpFormClass.Create(Application);
  TmpForm.Width:=550;
  TmpForm.Height:=400;
end;
0

my_nick - dzięki za ciekawe rozwiązanie. Pomysł godny uwagi. Jak wstanę, to go przeanalizuję :-)
Teraz raczej idę w kimę, bo właśnie zapikała 4:00.

A jakbyś jeszcze przy okazji znalazł ten fragment kopiujący, to było by ql, ale spróbuję sobie poradzić. Odpalę BCB i Delphi i będę modził :>.

0

No i minął cały dzień a postęp marny :-8

Chodzi mi o ten fragment:


type
  TFormClass = class of TForm;

function GetFormClass: TFormClass;
begin
  Result:=TTestForm; // czy jak tam się klasa nazywa
end;

Wszystko pięknie, ale po dogłębnym przekopaniu helpa jak i wyników na google oraz długich rozmowach z paroma ludźmi z 4p znającymi się na rzeczy stwierdzam jedno:
nie mogę znaleźć odpowiednika tego kodu w BCB.

Nie wiem, czy w BCB nie można przekazywać (zwracać) klasy, czy jak - ja tego nie znalazłem.
Jedyne, do czego doszedłem, to TMetaClass ale to działa tylko dla klas dziedziczących z TObject oraz __classid - działa tylko dla klas VCL. Niestety - klasy, które chcę zwrócić dziedziczą z mojej klasy bazowej, która nie może dziedziczyć z żadnej innej.

I druga sprawa.
Dzięki maniaks_w!! Rzeczywiście - domyślną wartością było caHide. Sprawa zwalniania pamięci przy zamykaniu formatki jest już więc załatwiona, ale ponieważ wskaźnik do formatki jest tylko jednym z pól mojej klasy, to czekam na rozwiązanie problemu opisanego powyżej.

0

Hehehe, następny dowód na to, że Delphi jest lepsze ;). Można by wykorzystać tę ciekawą właściwość BCB, że przyjmuje moduły *.pas - zadeklarować w takim zmienną globalną typu TForm, umieścić mój kod i przerobić go tak, żeby tworzoną formę przypisał do tej zmiennej, która, z kolei, powinna być dostępna w modułach C++. To tylko teoretyczne rozważania, nie wiem czy możliwe w realizacji, bo nie mam jak sprawdzić.

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