Runtime'da oluşturulan nesneyi yok etmek.
Forum kuralları
Forum kurallarını okuyup, uyunuz!
Forum kurallarını okuyup, uyunuz!
Runtime'da oluşturulan nesneyi yok etmek.
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;
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;
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;
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;
@seko ve @hbahadir Merhabalar.
- Her ikinizin de dikkatinizden kaçmış olduğunu değerlendirdiğim önemli bir noktayı bildirmek isterim.
- Siz herhangi bir nesneyi değil, üzerinde çalıştığınız bir nesneyi free ediyorsunuz.
- 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.
- 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...
Aşağıdaki şekilde deneyiniz..
- Her ikinizin de dikkatinizden kaçmış olduğunu değerlendirdiğim önemli bir noktayı bildirmek isterim.

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

- 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.

- 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...


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;
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
Kolay gelsin
Hüseyin BAHADIR
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!!!)

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!!!)

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
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
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.
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.
yanlış, AccesViolation ı da yakalar
asagıdaik ornegi inceleyin
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....
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;
yorum isareti (//) ni kaldırıp derlerseniz hata mesajına ilave yapmıs olacagız....
ÜŞENME,ERTELEME,VAZGEÇME
Hangi duruma göre yanlış?
Sizin yazdığınız koda göre söylediğiniz doğru.
Yukarıdaki koda göre söylediğiniz yanlış.

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ış.
@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.
- 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.
hatanız burda
çünkü 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ıcayazı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
Kod: Tümünü seç
For x:=0 to Form1.ComponentCount-1 Do......
Kod: Tümünü seç
If (xy as TWinControl).Focused Then (xy as TWinControl).Free;
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;
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 !!!
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5
Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!