her ne kadar bilgisayardan uzak kalmis olsak, baska bir hayata adim atmis olsakta hicbirsey beni delphi hakkinda yazmaktan alikoyamaz :)

interposer siniflar icin bir cesit taklit siniflarda diyebiliriz aslinda. Tek yaptiklari sey varolan siniflara yeni ozellikler eklemek. “e biz bunu zaten yapiyoruz” diyebilirsiniz ama bu siniflari digerlerinden ayiran fark ozelliklerini genislettikleri siniflar ile ayni adlara sahip olmalari. Bu sayede siz delphi idesinde yer alan normal bilesenleri kullanarak tasarima devam edebiliyorsunuz fakat arka planda kullanilan sinif sizin ozellikler eklediginiz sinif oluyor.

Benim acimdan ise en yararli ozelliklerini su sekilde ifade edebilirim.

Bazen olmazsa olmazlarimiz oluyor. Mesela fareyle uzerine geldigimizde rengi, fontu degisen fareyi uzerinden cektigimizde tekrar eski haline donen bilesenler. TLabel’in bu ozelligi mevcut (onMouseEnter, onMouseLeave) ama ben bu ozelligi TButton’a uygulamak istedigimde iki yolum var.

1: TButton’un ve Cevresindeki bircok bilesenin onMoseMove olayini kullanmak. Bu hicte iyi bir cozum degil. Hatta cozum olmaktan bile uzak bir yol. Boyle bir seyi asla dusunmeyin.

2: TButton’dan yeni bir sinif tureterek onMouseEnter ve onMouseLeave olaylarini eklemek. Guzel bir cozum lakin bu cozumun kotu tarafi projeyi baska bir makinede derlemek isterseniz oncelikle bu yeni gelistirdiginiz bileseni delphiye yuklemeniz gerekir. Bu da zamanla ortami bayan bir hareket olur.

diger bir cozum ise interposer siniflari kullanmak.
Bu yontemin kotu tarafi ise TButton’u sectiginiz zaman eklediginiz yeni olaylar object inspector da gozukmemesi. Ilgili olaylarin metodlarini bir kereligine manuel atamaniz gerekir. getirdigi faydalar yaninda gozardi edilebilecek bir zahmettir.

ufacik bir ornek yapalim.

Yapacagimiz sey Unit2 icerisinde yeni bir TButton sinifi olusturmak ve sinifin atasi olarak TButton’u secmek. Onemli olan nokta ata sinif olarak belirttigimiz TButton’un bulundugu unitin adinida belirtmemiz gerekir.

unit Unit2;

interface

uses ....,....,...,..., StdCtrls; //StdCtrls --> orjinal TButton'un oldugu sinif

type

TButton = class(StdCtrls.TButton)
//--> burdaki tanima dikkat !
//isin sirri olinde
//iki kere rafine :)
</code>

yeni TButton'un tanimi.

<code>
TButton = class(StdCtrls.TButton)
  private
    FOnMouseLeave  : TNotifyEvent;
    FOnMouseEnter : TNotifyEvent;
  protected
    procedure CMMouseEnter(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
  published
    property OnMouseLeave : TNotifyEvent
      read FOnMouseLeave write FOnMouseLeave;

    property OnMouseEnter : TNotifyEvent
      read FOnMouseEnter write FOnMouseEnter;

end;

ilgili metodlarin govdeleri…

procedure TButton.CMMouseEnter(var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseEnter) then
    FOnMouseEnter(Self);

end;

procedure TButton.CMMouseLeave(var Message: TMessage);
begin
  inherited;
  if Assigned(FOnMouseLeave) then
    FOnMouseLeave(Self);

end;

şimdi form1 e donelim ve forma bir adet Tbutton yerlestirelim ardindan uses satirinin sonuna gelerek unit2 yi ekleyelim. burasi onemli. bizim artik 2 tane TButton sinifimiz var ve bizim kullanmak istedigimiz TButton Unit2 nin icindeki. Bu nedenle Unit2 en sonda olmasi gerekir. Zaten Button1: TButton; yazan yerde fareyi TButton uzeri getirirseniz TButton un nerde tanimlandigini gosteren bir hint cikacaktir. Type Unit2.TButton yaziyorsa mesele yok :)

bir kereligine yazmamiz gereken kodlar :)


procedure TForm1.FormCreate(Sender: TObject);
begin
  button1.OnMouseLeave :=Button1MouseLeave;
  button1.OnMouseEnter:=Button1MouseEnter;
end;

procedure TForm1.Button1MouseEnter(Sender: TObject);
begin
(sender as tbutton).Font.Style :=(sender as tbutton).Font.Style - [fsunderline];
end;

procedure TForm1.Button1MouseLeave(Sender: TObject);
begin
(sender as tbutton).Font.Style :=(sender as tbutton).Font.Style + [fsunderline];
end;

inter1.jpg

inter.jpg

farkli kullanim alanlari da mevcut tabi. mesela tek bir komutla form uzerindeki TLabel, TButton, TCombobox gibi bilesenlerin bazi ozelliklerini set etmek istiyorsunuz. Yeni olusturacagimiz TLabel, TButton ve TCombobox bilesenleri IMyInterface arabirimini desteklyecek sekilde yazarsak daha sonra programda asagidakine benzer bir kodla islemlerimizi halledebiliriz.


for i:=0 to ComponentCount  - 1 do
   if Supports(Components[i],IMyInterface) then
      YapilacakIslemler....
6 Responses to “Interposer sınıflar”
  1. Tuğrul says:

    Eline sağlık güzel bir makale.

  2. cemaliozan says:

    Bencede eline sağlık hocam. Bu hangi sürümden bu yana vardı merak ettim doğrusu

  3. Sadettin Polat says:

    hangi surumden itibaren boyle ufak bir hile iceriyor bilmiyorum ama eminim cok eskilere uzaniyordur

  4. Furkan Duman says:

    sadettin bu harika bir makale olmuş . Niye? Çünkü bahsettiğin şeyi daha önce duymamıştım ve hep kendi kendime Delphi’de böyle bir özellik isterdim. Ellerine sağlık. :)

  5. Furkan Duman says:

    Yine erken davrandım. Sonunu doğru dürüst okumamışım. Aslında bu tam anlamıyla istediğim şey değil ve bunu yöntemi zaten bildiğimi farkettim. :) Eline sağlık tekrar.

  6. Sadettin Polat says:

    furkan, bahsettigin ozellik neymis merak ettim dogrusu.

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>