[çözüldü] Form u Destroy , Release etmek....

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
varyemez
Üye
Mesajlar: 262
Kayıt: 01 Oca 2009 11:00
Konum: Bursa
İletişim:

[çözüldü] Form u Destroy , Release etmek....

Mesaj gönderen varyemez »

Bir formda çalışırken 2. bir formu create edip içinden bilgiyi alıp sonra da onu yok etmeye çalışıyorum. Ancak en sonda
Form.Free veya Form.Destroy satırında Access violation hatası veriyor.. Formu nasıl free edeceğiz. Gerçi free yapmazsam da çalışıyor sorunsuzca, ama boş yere hafıza kullanmama kuralına uyayım dedim..

Kod: Tümünü seç

begin
if not Assigned(PaydasDlg) then
       Application.CreateForm(TPaydasDlg, PaydasDlg);
if Paydasdlg.ShowModal =mrOK then
begin
.....
......
......

end;

PaydasDlg.Release;  // formu yoketmek....
//PaydasDlg.Free;

end;
En son varyemez tarafından 18 Nis 2015 01:45 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Form u Destroy , Release etmek....

Mesaj gönderen xozcanx »

Kod: Tümünü seç

begin
if not Assigned(PaydasDlg) then
       Application.CreateForm(TPaydasDlg, PaydasDlg);
if Paydasdlg.ShowModal =mrOK then
Try
.....
......
......

finally
freeandnill(PaydasDlg) ;
//PaydasDlg.Release;  // formu yoketmek....
//PaydasDlg.Free;
end;
hocam tabletten yazdığım için kontrol edemiyorum umarım işinizi görür.
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen mrmarman »

Bir alternatif bilgi sunalım...

Formların her birine peşin peşin
- OnClose eventine

Kod: Tümünü seç

action := caFree;
- OnDestroy eventine de (örnekteki adiyla PaydasDlg := nil;)

Kod: Tümünü seç

FormunAdi := Nil;
koyarsanız, close etmeniz yeterli olur, bu saydıklarınız kendiliğinden olur. :idea:

Bir de @xozcanx
@xozcanx yazdı:

Kod: Tümünü seç

if Paydasdlg.ShowModal =mrOK then
Try
eğer bu şekilde bir if kurarsanız ModalResult = mrOk atanmadığı diğer hallerde (örneğin formu köşedeki çarpıya basıp kapatmak vb.) -ki dışarıdan close edilince zaten mrOk da olmayacaktır-, dolayısı ile TRY bloğu çalışmayacaktır.

Tabletten yazdığın için gözden kaçmış olacak...

Başarılar.
Resim
Resim ....Resim
Kullanıcı avatarı
xozcanx
Üye
Mesajlar: 362
Kayıt: 05 Oca 2012 12:55

Re: Form u Destroy , Release etmek....

Mesaj gönderen xozcanx »

ewet gözden kaçan birşeyler var gibi :)
form runtime da oluşturulmuyorsa varolan bir form ise muharrem hocamın dediği gibi yapmak gerekir :wink:
Nasibinde varsa, alırsın karıncadan bile ders, Nasibinde yoksa, bütün cihan önüne serilse, sana ters..
varyemez
Üye
Mesajlar: 262
Kayıt: 01 Oca 2009 11:00
Konum: Bursa
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen varyemez »

Önerilerin hepsini deneyeceğim..
Ancak Arman hocamın dediği gibi yokedilecek formun içine kapanışta free , nil etmek işime gelmiyor. Çünkü o formun içinde tanımladığım birkaç değişkeni, çağıran formda kullanıyorum önce ve işi bitince yoketmeye yelteniyorum. Kısacası hani veritabanından bir cari kaydı ( firma adı , adres vs. gibi bilgileri) alıp fatura başlığında kullanmak gibi...
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen mrmarman »

Kaygılarını anlıyorum, aslında ShowModal ile çağıran procedure sonlanana kadar FREE edilecek formdaki değerler korunacaktır ama şöyle başka bir alternatif önereyim o zaman.

Form2 kapandığında istediğiniz değerler topluca Form1'e taşınsın... Siz dilediğiniz zaman kullanın, form2 zaten kendini imha etmiştir. :D

Örneği şöyle çeşitlendirdik, formu direkt kapatırsanız hiçbir değer istenmeyecek, Onaylı Kapat butonuna basınca CLOSE edilirse bu değerler aktarılacak.

Örnek proje ekte...

Form1'de tDegerler diye bir record tanımladım, Form2 içindeki veriler geri bununla dönecek...

Kod: Tümünü seç

var
  Form1: TForm1;

Type
  tDegerler = Record
    aDeger,
    bDeger : String;
    cDeger : Integer;
  end;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.BitBtn1Click(Sender: TObject);
Var
  YeniDeger : tDegerler;
begin
  if NOT Assigned(Form2) then
    Application.CreateForm( TForm2, Form2 );

  Case Form2.ShowModal of
  mrOk     : begin
               YeniDeger := Form2Degerler;
               With YeniDeger do
                 ShowMessageFmt('OK ile kapandı...'#13'aDeger=%s, bDeger=%s, cDeger=%d', [ aDeger, bDeger, cDeger ]);
             end;
  mrCancel : ShowMessage('Cancel ile kapandı...');
  End;
end;
From2'de ise şöyle gerçekleşiyor...( ana USES satırına Unit1 eklendi...)

Kod: Tümünü seç

var
  Form2: TForm2;
  Form2Degerler : tDegerler;

implementation

{$R *.dfm}

procedure TForm2.BitBtn1Click(Sender: TObject);
begin
  Close;
  With Form2Degerler do begin
    aDeger := 'Muharrem';
    bDeger := 'ARMAN';
    cDeger := 1234;
  end;
  Self.ModalResult := mrOk;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  action := caFree;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  Form2 := Nil;
end;
Dosya ekleri
Form1_Form2_VeriTransfer_Record.rar
Form2'den Form1'e Close anında veri transferi
(174.26 KiB) 100 kere indirildi
Resim
Resim ....Resim
varyemez
Üye
Mesajlar: 262
Kayıt: 01 Oca 2009 11:00
Konum: Bursa
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen varyemez »

record ile yapmak ilgimi çekti, aynı şekilde programıma uyguladım. ilk geçişte sorun yok ancak ikinci geçişte
if not Assigned(PaydasDlg) then
Application.CreateForm(TPaydasDlg, PaydasDlg); kısmında paydasDlg isimli component var diyerek hata veriyor ve diğer formu açmıyor. Sanırım free veya destroy olamıyor tam olarak.
caFree ve nil satırlarını kaldırırsam hiç hatasız çalışıyor.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen mrmarman »

PaydasDlg'nin OnDestroy olayına

Kod: Tümünü seç

PaydasDlg := Nil;
demeyi ihmal etmiş olmalısın ondandır

ama koydum demişsin, verdiğim örnekte de aynı sorun çıkıyor mu sende ?

Formu açan procedure kodlarını yazarsan beraber bakarız.
Resim
Resim ....Resim
varyemez
Üye
Mesajlar: 262
Kayıt: 01 Oca 2009 11:00
Konum: Bursa
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen varyemez »

Formun onDestroy olayında paydasDlg:=nil yaptım tabii.. onClose olayında da caFree var. Akşama her iki uniti de olduğu gibi yollarım size... Sizin gönderdiğiniz proje sorunsuz çalışıyor , önce onu inceledim zaten.
varyemez
Üye
Mesajlar: 262
Kayıt: 01 Oca 2009 11:00
Konum: Bursa
İletişim:

[çözüldü] Form u Destroy , Release etmek....

Mesaj gönderen varyemez »

Her ne hikmetse
if not Assigned(PaydasDlg) then
Application.CreateForm(TPaydasDlg, PaydasDlg); deki if not assigned i kaldırıp direkt
Application.CreateForm(TPaydasDlg, PaydasDlg); yazıp showmodal den sonra da en son
paydasdlg.destroy yaparsam sorun kalmıyor. teşekkürler muharrem bey.
bu arada bir temel soru sorayım size.. uses unit..... 2 yerde kullanıyoruz , en yukarda ve implementation da..
ikisi arasındaki fark nedir? hangi durumlarda hangisini kullanmalıyız?
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Form u Destroy , Release etmek....

Mesaj gönderen mrmarman »

Şöyle ki,

(1) ilgili UNIT içeriği, USES satırından itibaren daha aşağıdaki satırlarda kullanılabilmektedir. Bir üstte tanımsız sayılmaktadır.

(2) Buradan yola çıkarak implementation üzerinde ilgili unit'e ihtiyaç varsa daha üstlerde bir USES satırında yer almalıdır.
Resim
Resim ....Resim
Kullanıcı avatarı
The_aLiEn
Üye
Mesajlar: 28
Kayıt: 09 Kas 2010 02:35
Konum: Trabzon
İletişim:

Re: [çözüldü] Form u Destroy , Release etmek....

Mesaj gönderen The_aLiEn »

Çözüldü etiketi gelmiş olmasına rağmen kapsamı biraz genişletmek istedim naçizane:

Form1 ve Form2'nin tanımlandığını, Form1 içerisinden Form2 yi Create edip iş bitince Free etmek maksatlarını varsayarak class function kullanımı da gayet hoş olacaktır düşüncesindeyim.

Form2 de public alanına bir class function ekleyin ve Form2'nin tanımlı olduğu unit içerisindeki global var bloğu altındaki Form2: TForm2 şeklindeki değişken tanımını silin:

Kod: Tümünü seç

...
	public
		class function ShowAndGetResults: TResults; // bir record olabilir, gene yaşam döngüsünü sizin yöneteceğiniz bir sınıf nesnesi olabilir
...
//var
//	Form2: TForm2;
...
class function TForm2.ShowAndGetResults: TResults;
var
	frm: TForm2;
	MR: TModalResult;
begin
	// Result bir nesne ise, ki benim tercihim nesne üzerine olacaktır. Form1 içinde çağırdığım yerde <> nil kontrolü yapar ona göre aksiyon alırım
	// Result := nil;
	
	frm := TForm2.Create(nil);
	
	try
		MR := frm.ShowModal;

		if MR = mrOK then
		begin
			...
			Result := frm.BirSeyler;
			...
		end;
		// gerekliyse else ve başka şeyler...
	finally
		frm.Free;
	end;
end;
Böylece hem mümkün olduğunca Application.CreateForm'dan kaçmış hem de Form2 de sizin yazdıklarınız doğrultusunda ortak bir kullanıma sahip bir şeyse, tüm yönetimi tek bir noktaya bağlamış olurum ve çağırdığım yerde yalnızca TResults ile ilgilenirim. Zira gene anladığım kadarıyla asıl ilgilenmem gereken şey TResults; Form2 değil..
Cevapla