Butonları taşıma

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Kullanıcı avatarı
mrmarman
Üye
Mesajlar: 4740
Kayıt: 09 Ara 2003 08:13
Konum: İstanbul
İletişim:

Re: Butonları taşıma

Mesaj gönderen mrmarman »

Bu linktekini indirip farkı incele...
Resim
Resim ....Resim
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Butonları taşıma

Mesaj gönderen thelvaci »

Bu tarz şeyler için hazine kutusunun içine bakmalısınız; yani Delphi'nin kaynak kodlarına. Neler yapmanız gerektiğinden biraz bahsedelim. TButton sınıfının OnStartDrag olayı var ama TSpeedButton'un yok değil mi. Bu durumda TButton sınıfının içinde OnStartDrag olayı nasıl tanımlanmış bir bakmalısınız. Aşağıdaki gibi bir tanım göreceksiniz:

Kod: Tümünü seç

property OnStartDrag;
Bu tanım, ilgili property'nin üst sınıflardan birisinden miras alındığını gösterir. Bu durumda bir üst sınıfa çıkalım bakalım yani TCustomButton'a ve orada OnStartDrag arayalım. Orada bulamadık bir üst sınıfa yani TButtonControl'e gidelim ve orada arayalım, orada da bulamadık. Bu sefer TWinControl'deyiz ve OnStartDrag arıyoruz ama burada da bulamıyoruz, bir üst sınıfı olan TControl'e geçip aramamızı orada yapalım ve nihayet TControl sınıfının protected bloğunda tanımlanmış olan aşağıdaki gibi bir property buluyoruz:

Kod: Tümünü seç

property OnStartDrag: TStartDragEvent read FOnStartDrag write FOnStartDrag;
Bu ne demek peki; TControl sınıfından türeyen her sınıf bu property'i kullanabilir demek. Peki TSpeedButton hangi sınıftan türüyor bir de ona bakalım.

Kod: Tümünü seç

TSpeedButton = class(TGraphicControl)
TGraphicControl = class(TControl)
Görüldüğü üzere, TSpeedButton; TGraphicControl sınıfından ve o da TControl'den türüyor. Bu durumda TSpeedButton sınıfı için OnStartDrag olayını kullanabiliriz ama bizim için Object Inspector'a koymamışlar; yani property'i published bölümüne yazmamışlar. Bu durumda ne yapacağız peki; interposer class denilen kavramı kullanacağız. Şöyleki:

Kod: Tümünü seç

  TSpeedButton = class(Vcl.Buttons.TSpeedButton)
  end;

  TForm1 = class(TForm)
    Button1: TButton;
    SpeedButton1: TSpeedButton;
    ...
    ...
    ...	
Bu noktadan sonra, kodunuzda herhangi bir yerde SpeedButton1.OnStartDrag'a erişebilir ve kullanabilir olursunuz; neden ? Onu'da siz araştırın bakalım ;)
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Butonları taşıma

Mesaj gönderen thelvaci »

Ayrıca belirtmeden geçemeyeceğim, birden fazla arkadaşımızın birden fazla defa kullanmasından ötürü. Lütfen TSpeedButton'u TButton, TPanel gibi sınıflara cast etmeyin. Çünkü TSpeedButton ne bir TButton'dur ne de bir TPanel'dir. TSpeedButton bir TControl'dür kalıtım hiyerarşisi gereğince; bir TSpeedButton'u TControl'e cast edebilirsiniz ama diğerleri hatalı sonuçlar verebilir. Özellikle de Access Violation gibi. Şu zamana dek bu tarz bir sorun ile karşılaşmamış iseniz ya çok şanslısınız demektir; ya da sadece ortak ata sınıflarında kullanılan metodları yada property'leri kullanmışsınız demektir.

Örneğin; TButton hiyerarşisine bakalım:

Kod: Tümünü seç

  ...
  TControl
    TWinControl
      TButtonControl
        TCustomButton
          TButton
ve TSpeedButton'un hiyerarşisine bakalım :

Kod: Tümünü seç

  ...
  TControl
    TGraphicControl
      TSpeedButton
görünümündedir. Hiyerarşiden sizin de gözlemleyeceğiniz gibi TSpeedButton ve TButton'un tek ortak noktaları her ikisinin de TControl'den türemeleridir. Bu bağlamda her iki class'ı da ata sınıfı olan TControl'e cast edebilirsiniz, ama onun aksi hatalı durumlara neden olur.

Örneğin;

Kod: Tümünü seç

  TX = class
  private
    FDummy : Integer;
  end;

  TY = class(TX)
  end;

  TZ = class(TY) // Button'u temsil etsin
  private
    FButtonIndex : Integer;
  end;

  TA = class(TX)
  end;

  TS = class(TA) // SpeedButton'u temsil etsin
  end;

  ...
  ...
procedure TForm3.Button1Click(Sender: TObject);
var
  Z : TZ;
  S : TS;
begin
  Z := TZ.Create;
  S := TS.Create;

  TZ(S).FButtonIndex := 1453; // Sizce burada ne olur ?
  ShowMessage(TZ(S).FButtonIndex.ToString());

  Z.Free;
  S.Free;
end;
TS tipli ve S isimli bir nesne örneğimiz var ve bu nesnenin türediği sınıf hiyerarşisinde FButtonIndex adlı bir üye yok; ama biz S isimli nesnemizi TZ isimli sınıfa cast ederek, ilgili üyeye erişebiliyoruz kod ortamında. Peki gerçekte ne oluyor; TS sınıfı için asla ayrılmamış bir hafıza bloğuna bir şeyler yazmaya çalışıyoruz. Eğer gerçekten de etrafınızdan bal damlıyor ise bu kodda hata almazsınız ama normalde "Access violation at adress ....." gibi bir hata alırsınız.

Umarım ne demek istediğimi izah edebilmişimdir.
Kullanıcı avatarı
Dostk
Üye
Mesajlar: 144
Kayıt: 22 Ağu 2015 12:21

Re: Butonları taşıma

Mesaj gönderen Dostk »

Muharrem hoca eline sağlık, buton taşıma olayında ufak bir sıkıntı var mesela buton taşımak için butona tıkladığımızda bu seferde butonun kılik işleme gerçekleşiyor...
thelvaci
Kıdemli Üye
Mesajlar: 770
Kayıt: 11 Tem 2010 07:17
Konum: Istanbul
İletişim:

Re: Butonları taşıma

Mesaj gönderen thelvaci »

mrmarman yazdı:Bu linktekini indirip farkı incele...
Dostk yazdı:Muharrem hoca eline sağlık, buton taşıma olayında ufak bir sıkıntı var mesela buton taşımak için butona tıkladığımızda bu seferde butonun kılik işleme gerçekleşiyor...
Üstad, işte tam olarak bundan bahsediyorum. Öğrenme odaklı değil, maalesef sadece çözüm odaklıyız.
dnzmobile
Üye
Mesajlar: 17
Kayıt: 06 Ağu 2015 01:58

Re: Butonları taşıma

Mesaj gönderen dnzmobile »

mrmarman hocam paylaşımınız için çok teşekkürler.
Sizin paylaştığınız uygulamayı Android de çalıştıramıyorum. Aslında yapmak istediğim işlem bir TImage nesnesini başka bir TImage üzerine sürükleyip bırakınca ekrana bir mesaj gelmesi. Tabiki bunu Android'de derlemek istiyorum.
Bunu nasıl yapabileceğim hakkında fikri olan varmıdır?
Cevapla