Runtime'da oluşturulan nesneyi yok etmek.

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Seko
Üye
Mesajlar: 11
Kayıt: 07 Ara 2004 01:16

Runtime'da oluşturulan nesneyi yok etmek.

Mesaj gönderen Seko »

Merhaba,

Amacım runtime'da oluşturduğum bileşenleri, Delphi'nin tasarım ekranında
olduğu gibi "del" vaya başka bir tuş ile yok etmek. Aşşağıdaki kod parçası aslında bu işi yapıyor ama her seferinde Access Violation... şeklinde hata veriyor. Ben işin içinden çıkamadın. Şimdiden çok teşekkürler.

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
Var
X :Integer;
xy :TComponent;
begin
Case Key Of
Ord(vk_Delete): For x:=0 to Form1.ComponentCount-1 Do
Begin
xy:= Form1.Components[x];
If (xy as TWinControl).Focused Then (xy as TWinControl).Free;
End;
End;
End;
Kullanıcı avatarı
hbahadir
Kıdemli Üye
Mesajlar: 544
Kayıt: 06 Ara 2004 05:03
Konum: BURSA idi artık İST.
İletişim:

Mesaj gönderen hbahadir »

If (xy as TWinControl).Focused Then (xy as TWinControl).Free;

component üzerindeyken (focused = true) free etmeye çalışırsan hata vermesi gayet normal tabi ki :)

İlk önce free edeceğin componentin focused = False olsun.

Kolay gelsin
Hüseyin BAHADIR
Seko
Üye
Mesajlar: 11
Kayıt: 07 Ara 2004 01:16

Mesaj gönderen Seko »

Componenti free etmeden önce başka bir nesneye setfocus yapsam bile durum değişmiyor.

Forma rastgele nesneler attıktan sonra, formun keypreview özelliğini true yapıp formun onkeyup olayına aşşağıdaki kodları yazarsanız, durum hakkında daha net şeyler ortaya çakabilir.


Var
X :Integer;
xy :TComponent;
begin
Case Key Of
Ord(vk_Delete): For x:=0 to Form1.ComponentCount-1 Do
Begin
xy:= Form1.Components[x];
If (xy as TWinControl).Focused Then
Begin
(xy as TWinControl).Free;
End;
End;
End;
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

@seko ve @hbahadir Merhabalar.

- Her ikinizin de dikkatinizden kaçmış olduğunu değerlendirdiğim önemli bir noktayı bildirmek isterim. :idea:

- Siz herhangi bir nesneyi değil, üzerinde çalıştığınız bir nesneyi free ediyorsunuz. :idea:

- Yanıldığınız nokta şudur ki; focus halinde olmanın hiçbir önemi yoktur. Tab Order neyse diğer nesneye, eğer yoksa owner'ine (sahibine) focus olacaktır zaten. :wink:

- O nesneye tuş ile mesaj gönderiyor ve bu mesajın uygulanmasından önce free ederek geriye başıboş bir mesajı bırakıyorsunuz. Hatanız burada... :idea:

:arrow: Aşağıdaki şekilde deneyiniz..

Kod: Tümünü seç

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  Case Key Of
  Ord(vk_Delete):
    begin
      Key := $0;
      Form1.ActiveControl.Free;
    end;
  end; // Case
end;
Resim
Resim ....Resim
Kullanıcı avatarı
hbahadir
Kıdemli Üye
Mesajlar: 544
Kayıt: 06 Ara 2004 05:03
Konum: BURSA idi artık İST.
İletişim:

Mesaj gönderen hbahadir »

zaten nesne silmek için bu şekilde bir kod da mantıklı değil. Aslında ya bunları bi liste şeklinde gösterirsin, yada delphi 'nin dizaynda yaptığı gibi silmek yada taşımak en mantıklısı (bunun örneği YUNUS projesinde var). Birde eğer illaki bu şekilde yapılacaksa try except bloğu içerisinde yapılırsa hata mesajlarıda kontrol edilmiş olur.

Kolay gelsin
Hüseyin BAHADIR
Seko
Üye
Mesajlar: 11
Kayıt: 07 Ara 2004 01:16

Mesaj gönderen Seko »

Tekrar merhaba,

mrmcop arkadaşımızın gönderdiği kod sayesinde problemi hallettim. Çok teşekkür ederim. Bu iki satır bakış açımı biraz daha değiştirdi.
Bahadır arkadaşım. Componentleri liste halinde göstersen bile "Delphi tasarım ekranında olduğu gibi silmek" için birkaç satır koda da ihtiyaç var. Try except bloğu her zaman işe yaramıyor. (Benim yazdığım kod bloğunu try except bloğu içine alsan bile çalışma esnasında yine hata mesajını alırsın!!!)
:)
Kullanıcı avatarı
gkimirti
Admin
Mesajlar: 1956
Kayıt: 02 Eyl 2003 04:44
Konum: İstanbul

Mesaj gönderen gkimirti »

try except blogu program kırılmadıgı surece (Fatal Error yada Run Time Error gibi) her turlu hatayı bloke eder ve bu sekilde ister gosterir ister gizler ve isterseniz kontrol edersiniz...

eger delphi idesinde try except kullnıldıgı halde bir hata alıyorsanız muhtemelen
Tools/Debugger Options da
Language Exceptions tabında
Stop On Delphi Exceptions isaretlidir
bunu iptal ederseniz delphi ide sinde de hata almayacaksınız
ÜŞENME,ERTELEME,VAZGEÇME
Seko
Üye
Mesajlar: 11
Kayıt: 07 Ara 2004 01:16

Mesaj gönderen Seko »

Küçük bir bilgi de ben ekleyim.
Try -Except buloğu, "Access voilation at adress..." şeklindeki hatalarda malesef işe yaramıyor.
Stop on Delphi Exception veya Break on Exception ifadeleri ise programı delphi'de çalıştırıp denerken bu hata yakalama bloklarında veya başka bir satırda hata oluştuğunda delphi'nin programı durdurup cursor'u hata olan satıra konumlandırmasını sağlıyor.
Kullanıcı avatarı
gkimirti
Admin
Mesajlar: 1956
Kayıt: 02 Eyl 2003 04:44
Konum: İstanbul

Mesaj gönderen gkimirti »

yanlış, AccesViolation ı da yakalar
asagıdaik ornegi inceleyin

Kod: Tümünü seç

procedure TFrmMain.Button1Click(Sender: TObject);
var
  a:TStringList;
begin
  try
    a.Add('fdfdsfds');
  except
    //on E:Exception do ShowMessage(e.Message+#13#10+'Hatası oldu.');
  end;
end;
bunu direkt calıstırırsanız hic hata mesajı vermeyecektir,
yorum isareti (//) ni kaldırıp derlerseniz hata mesajına ilave yapmıs olacagız....
ÜŞENME,ERTELEME,VAZGEÇME
Seko
Üye
Mesajlar: 11
Kayıt: 07 Ara 2004 01:16

Mesaj gönderen Seko »

Hangi duruma göre yanlış? :idea:
Sizin yazdığınız koda göre söylediğiniz doğru.

Kod: Tümünü seç

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
Var
X         :Integer;
xy        :TComponent;
begin
Case Key Of
  Ord(vk_Delete): For x:=0 to Form1.ComponentCount-1 Do
                  Begin
                  xy:= Form1.Components[x];
                  If (xy as TWinControl).Focused Then
                          Try
                          xy.Destroy;
                          Exit;
                          except
                          end;
                  End;
End;

end;

Yukarıdaki koda göre söylediğiniz yanlış.
Kullanıcı avatarı
gkimirti
Admin
Mesajlar: 1956
Kayıt: 02 Eyl 2003 04:44
Konum: İstanbul

Mesaj gönderen gkimirti »

bu kodda ben bir exception olusturamadım, hatta xy.Destroy ardına bir tane daha xy.destroy; ekledim olusan hata yakalanıyor.
ÜŞENME,ERTELEME,VAZGEÇME
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4741
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Mesaj gönderen mrmarman »

@gkimirti ve @Seko Merhabalar...

- Aynı şeyi söyleyip farklı algılamayalım. Fatal Error (Fahiş Hata olarak Türkçeleştirmek istiyorum)

- Şahsi fikrim (katılmaya da bilirsiniz) Access Violation başında Fatal Error denmese de asılsız erişim ve türevi hatalar da programın çalışma yönüne etki edeceğinden (yani olay (event) doğuran bir işlemin, handled veya Abort gibi kontrol altında bertaraf edilmemesi durumundan bahsediyorum) fahiş hata kategorisindedir. Try Excep altına alınması ise göz göre göre bug'a davet çıkarmaktır.

- Try Excep bloklarını kullanırken buna dikkat edilmeli ve programcı hatasını tümüyle gizlemek yerine, normal şartlar altında hata vermesi sağlanarak programın kontrollü bir şekilde sonlanmasına izin verilmeli. Dosya sistem farklılıkları, kullanıcı usul/işlem sırlaması, veritabanı bozulması, programımız dışından 3.ncü parti program etkisi (hack), disk yönetimi vb. öngörülebilecek hataların kontrol altına alınması kafidir.

- Ben de kendi hatamı zor kabullenenelerdenim ama programın yanlış çalışmasına izin vermek istemem. Sözüm meclisten dışarı, buradaki örnekteki gibi nesne silmek için belirlenen tuş doğru çalışmıyorsa, özür diler gibi except altında hata verdirmek gibi bu durumun oluşmasına izin vermek da bana aynı derece ayıp geliyor.
Resim
Resim ....Resim
Seko
Üye
Mesajlar: 11
Kayıt: 07 Ara 2004 01:16

Mesaj gönderen Seko »

mrmcop çok haklısın bence. Ben eğer nesneyi silmek için aylarladığım tuşun arada bir çalışmamasından veya kullanıcıya bir "özür mesajı" :) döndürmesindense runtime'da hiç nesne oluşturmamayı tercih ederim. Eğer problem çözülmeseydi (çok teşekkürler) kesinlikle nesne oluşturmaktan da vazgeçerdim.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2381
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Mesaj gönderen freeman35 »

hatanız burda

Kod: Tümünü seç

For x:=0 to Form1.ComponentCount-1 Do......
çünkü

Kod: Tümünü seç

If (xy as TWinControl).Focused Then (xy as TWinControl).Free; 
aradan bir component sildiğinizde ComponentCount zaten 1 değer düşer. ama döngü devam eder. ve olmayan yani silinmiş kayda ulaşmaya çalışıncada acses.... hatası alırsın. Bu yüzden for değil while döngüsü kullanılmalı.
for başlangıç ve bitişi belli olan döngüler(döngü içinde başlangıç ve bitiş değeri değişmemek şartı vardır)
while eğer koşul sağlanmıyorsa döngüye hiç girmesi istenmiyorsa
repeat untilmutlaka döngüye bir kez girmeli, ve koşul sağlanmazsa çıkmalı ise

ayrıca

Kod: Tümünü seç

If assigned(xy)and (xy as TWinControl).Focused Then (xy as TWinControl).Free; 
yazılırsa eğer xy tanımlı ise çalışır. bahsi daha öncede geçmişti. delphi compiler ın en büyük özelliklerinden birisidir. eğer ilk koşul sağlanmazsa ikinci koşula bakılmaz. yani xy tanımsızsa xy nin twincontrol mü olduğu kontrolü yapılmaz ve koşul sağlanmadı işlemi uygulanır.

ayrıca benim herzaman tavsiye ettiğim, runtime oluşturulacak tüm class ve componentları eğer adet i fazla ve belirsizse TList kullanılması

kolay gele
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Cevapla