Nesnenin Belirttiğim Olay Metodundaki procedure geçerlimi?

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Nesnenin Belirttiğim Olay Metodundaki procedure geçerlimi?

Mesaj gönderen vkamadan »

Merhaba ,
bir nesnenin örneğin bir TEdit in OnEnter olaymetodunun yazılıp yazılmadığını nasıl anlayabilirim? ben şöyle bir yol izledim ama tutarsız bir sonuç ortaya çıktı;

Kod: Tümünü seç

var
Olay:^TNotifyEvent;
begin
 Olay:=@Edit1.OnEnter;
 if Olay=nil then Showmessage('Olay Yok') else ShowMessage('Olay Var');
end;
Önerileriniz nedir?
Teşekkürler.
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

Aslında yapmak istediğim olay şu;
Bir form üzerindeki bütün Editlere tek bir OnEnter olay metodu atayacağım ancak başka sebeplerden dolayı eğer daha önceden bir OnEnter olayı yaratılmışsa o editin OnEnter olayı çağrıldığında hem daha çnceden yazılan hem beni OnEnter olayım çalıştırılacak.
Inherited; anahtar gelimesiyle oluşturuyorum yeni olayları ama yinede Eziyor. eğer varsa eski olaylar çalışmıyor.
Volkan KAMADAN
www.polisoft.com.tr
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

Inherited atadaki olayın çalışmasını sağlar, ezmek için override etmelisiniz..Bu noktadan yaklaşmanız gerek sanırım olaya..Söz konusu formu türettiniz mi, yani atası var mı?
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

Merhaba ,
oldukça falza sayıda formu ve bu formlar üzerinde yine kayda değr miktarda nesneleri olan bir projem var ,
bütün formlarda li TEdit , TComboBox ve birkaç nesne türünün OnExit ve OnEnter olaylarına ortak bir fonksiyon atamak için böyle bir şeye ihtiyaç doğdu ama bu formlarda Tasarım anında yazılmış OnEnter ve OnExit olaylarına sahip nesneler de var dolayısıyla benim hem yeni atananı hemde eski oalyı çalıştırmam gerekiyor şu şekilde bir yapı kullanıyorum

Kod: Tümünü seç

procedure Tgecici.GlobalOnEnter(Sender: TObject);
Const  Renk:TColor=$00B8CBDE;
begin
  inherited;
   if Sender is TEdit then
     TEdit(Sender).Color:=Renk;

   if Sender is TCurrencyEdit then
     TCurrencyEdit(Sender).Color:=Renk;

   if Sender is TComboBox then
   TComboBox(Sender).Color:=Renk;

   if Sender is TDateTimepicker then
   TDateTimePicker(Sender).Color:=Renk;

   if Sender is TRxDBLookupCombo then
   TRxDBLookupCombo(Sender).Color:=Renk;

   if Sender is TMaskEdit then
   TMaskEdit(Sender).Color:=Renk;
end;

procedure Tgecici.GlobalOnExit(Sender: TObject);
Const  Renk:TColor=$00D2DDDD;
begin
   Inherited;
   if Sender is TEdit then
     TEdit(Sender).Color:=Renk;

   if Sender is TCurrencyEdit then
     TCurrencyEdit(Sender).Color:=Renk;

   if Sender is TComboBox then
   TComboBox(Sender).Color:=Renk;

   if Sender is TDateTimepicker then
   TDateTimePicker(Sender).Color:=Renk;

   if Sender is TRxDBLookupCombo then
   TRxDBLookupCombo(Sender).Color:=Renk;

   if Sender is TMaskEdit then
   TMaskEdit(Sender).Color:=Renk;
end;

Kod: Tümünü seç

procedure Tgecici.SetGlobalEvents(Form: TForm);
var
i:integer;
begin
  for i:=0 to Form.ComponentCount-1 do
   begin
     if (Form.Components[i] is TEdit) or (Form.Components[i] is TComboBox) or (Form.Components[i] is TCurrencyEdit) or (Form.Components[i] is TMaskEdit) or (Form.Components[i] is TDateTimePicker) or (Form.Components[i] is TRxDBLookupCombo) then
       begin

               if (Form.Components[i] is TEdit) then
                               begin
                                 TEdit(Form.Components[i]).OnEnter:=GlobalOnEnter;
                                 TEdit(Form.Components[i]).OnExit:=GlobalOnExit;
                               end;
              if (Form.Components[i] is TCurrencyEdit) then
                               begin
                                 TCurrencyEdit(Form.Components[i]).OnEnter:=GlobalOnEnter;
                                 TCurrencyEdit(Form.Components[i]).OnExit:=GlobalOnExit;
                               end;
              if (Form.Components[i] is TMaskEdit) then
                               begin
                                 TMaskEdit(Form.Components[i]).OnEnter:=GlobalOnEnter;
                                 TMaskEdit(Form.Components[i]).OnExit:=GlobalOnExit;
                               end;
              if (Form.Components[i] is TDateTimePicker) then
                               begin
                                 TDateTimePicker(Form.Components[i]).OnEnter:=GlobalOnEnter;
                                 TDateTimePicker(Form.Components[i]).OnExit:=GlobalOnExit;
                               end;
              if (Form.Components[i] is TRxDbLookupCombo) then
                               begin
                                 TRxDbLookupCombo(Form.Components[i]).OnEnter:=GlobalOnEnter;
                                 TRxDbLookupCombo(Form.Components[i]).OnExit:=GlobalOnExit;
                               end;
              if (Form.Components[i] is TComboBox) then
                               begin
                                 TComboBox(Form.Components[i]).OnEnter:=GlobalOnEnter;
                                 TComboBox(Form.Components[i]).OnExit:=GlobalOnExit;
                               end;
       end;
   end;
end;
Formların OnCreate Metodlarında hazırladığım SetGlobalEvents (Form :Tform); proceduresine bulunduğum formu geçerek form üzerindeki belitrttiğin neslnlerin olayllarını ayarlıyorum ama eski olaylar ezilip gidiyor.
Volkan KAMADAN
www.polisoft.com.tr
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

Eğer form türeterek yapıyorsanız ata formun eventlerine yazdığınız kodların çalışması için Inherited anahtar kelimesi yeterlidir ve herhangi bir ezilme söz konusu olmaz..Run time esnasında mı yapılıyor yönlendirme tam olarak anlayamadım olayı..?
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

Evet o şekildeymiş, kodları dikkatli inceleyince farkettim..Form türetme olayı var mı?
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

evet ,
Runtime da atama yapılıyor , ve formlar türemiş formlar değil.
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

Şu an , nesnenin geçerli bir OnEnter olayına sahip olup olmadığını kontropl edebilirsem bu benim işimi çözecek;
Volkan KAMADAN
www.polisoft.com.tr
t-hex
Kıdemli Üye
Mesajlar: 531
Kayıt: 18 Mar 2005 02:45
Konum: İstanbul/Antalya
İletişim:

Mesaj gönderen t-hex »

Merhaba,

Bir event'a method bağlanmış mı öğrenmek için klasik pointer karşılaştırma yöntemlerini kullanabilirsiniz.

Kod: Tümünü seç

  if assigned(OnEnter) then ... else ...;
daha önceden bir metod bağlanmışsa OnEnter alanının değeri o metodun adresidir. Delphi, c# gibi multieventdelegate desteklemediği için bir olaya birden fazla metod bağlayamazsınız.

Ama alternatif bir yöntem olarak;
OnEnter metodu önceden atanmış sınıfları ve metodlarını bir listede tutup, sizin yazdığınız OnGlobalEnter ve OnGlobaleExit olaylarındaki kodu da listeyi Sender'a denk gelen nesneye ait önceden eklenmiş bir metod var mı yok mu diye taratarak istediğinizi yapabilirsiniz. Lakin çok uzun iş bu.
aLonE CoDeR
Kıdemli Üye
Mesajlar: 1223
Kayıt: 26 Nis 2005 04:08

Mesaj gönderen aLonE CoDeR »

İlk mesajınızda yazdığınız kodlar ilgili eventin olup olmadığını kontrol eder...
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

Merhaba ,
olayı , halletik kısmen , yani en azından geçerli bir adresi olup olmadığını anlayabiliyoruz ,
if @OnEnter =nil ... şeklinde , bakalım eski olayıda geçici bir değişkene alıp yeni olayın içinden önce eskisini çağırabilirsem sonuca uklaşmış oalcağım.
İlgilenen arkadaşlara teşekkürler.
Volkan KAMADAN
www.polisoft.com.tr
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Selamlar,

Neden sonradan eski event'e ekleme yapman gereksinimini anlamadım. Ancak eski event handler içine yeni handler'ı çağıracak şöyle birşey eklemen sorunu çözmüyor mu? İlla runtime'da dinamik mi yapman lazım?

Kod: Tümünü seç

procedure TForm.GlobalOnEnter(Sender....
begin
   // Eski kodun

  YeniGlobalOnEnter(Sender);
end;
şeklinde yapamıyor musun?

İlla dinamik değiştireceğim diyorsan:

Kod: Tümünü seç

procedure TForm.RuntimeOnEnter(Sender....
begin
    GlobalOnEnter(Sender);
    YeniGlobalOnEnter(Sender);
end;
Değiştirmek istediğinde OnEnter:= RuntimeOnEnter; yapıp eski haline getirmek istediğinde OnEnter:= GlobalOnEnter yaparsın.
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

coderlord yazdı: Neden sonradan eski event'e ekleme yapman gereksinimini anlamadım.
Bazı nesnelerin OnEXit ve ONEnter larında çeşitli hesaplamaların yapıldığı procedureler çalıştırılıyor, benim kullanacağım onEnter ve OnExit ta ise her zaman sabit olan mesela nesnenin içindeyken renginin farklı görünmesi gibi bir takım özellik ayarlamaları yapan olaların gerçekşemesini istiyorum . Çok fazla nesne olduğu için runtime da dinamik olarak olay ataması yapıyorum. aslında olmasını arzu ettiğim olay Inherited formlarda olduğu gibi Olayın eski olayın üzerinden çalışmaya devam etmesi. yani bir nevi tali olay.
Teşekkürler.
Volkan KAMADAN
www.polisoft.com.tr
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Daha iyi bir yöntem bulana kadar şöyle yapabilirsin. Bu yöntemde eski handler'ın pointer'ını bir stringlist te bir string ile ilişkilendirerek saklıyoruz ki sonradan geri çağırabilelim. Belki sana faydası olabilir.

Kod: Tümünü seç

unit Unit1;

interface

uses Forms, StdCtrls, Classes, Controls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Button1: TButton;
    Edit2: TEdit;
    procedure Edit1Enter(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    FHandlerList: TStringList;
    procedure SonrakiEnter(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

uses Dialogs;

{$R *.dfm}

procedure TForm1.Edit1Enter(Sender: TObject);
begin
  // Eski Handler kodu.
  ShowMessage('1 - Giriş yapıldı.');
end;

procedure TForm1.SonrakiEnter(Sender: TObject);
var
  Index: Integer;
  Proc: TNotifyEvent;
begin
  // Eski handler pointer'ı yüklenip çalıştırılıyor.
  Index:= FHandlerList.IndexOf('SonrakiEnter');
  if Index <> -1 then
  begin
    @Proc:= FHandlerList.Objects[Index];
    Proc(Sender);
  end;

  // Yeni handler kodu.
  ShowMessage('2 - Yeniden giriş yapıldı.');
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(Edit1.OnEnter) then
    FHandlerList.AddObject('SonrakiEnter', @Edit1.OnEnter);
  Edit1.OnEnter:= SonrakiEnter;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FHandlerList:= TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FHandlerList.Free;
end;

end.
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Mesaj gönderen vkamadan »

@coderlord;
bahsettiğin metodla sorunumu uzun yoldanda olsa çözdüm,
iyi çalışmalar.
Volkan KAMADAN
www.polisoft.com.tr
Cevapla