Tuşa basma işkencesi..

// 15 Mayıs 2009 // Delphi, Programlama

Diyelim ki bir program yazdınız ve programınızın içine sürpriz yumurta koymak istiyorsunuz.Yada kullanıcılara feci eziyet etmek istiyorsunuz. Bu amaçla çok zorlu bir tuş kombinasyonu kullanmak istiyorsunuz. Mesela biz bu örneğimizde Ctrl + Shift + F5 + 7 + 8 tuşlarına basılınca birşeyler yapacağız. (Tabii bu tuşlara aynı anda basmayı becerebilirsek :) )

Yine herzaman ki gibi ne yapıyoruz. Tabii ki önce Help’e bir uğruyoruz. Ve Help’imize GetKeyState yazıyoruz. O da ne TDragObject diye abuk bir class’a ait bir yardım çıktı.Yok yok biz bunu aramıyoruz. Windows API helpinden bakacağız.Heh şimdi bulduk istediğimiz fonksiyonu.Fonksiyondan görebildiğimiz kadarı ile dönüş değeri SHORT diye bir tip. Bu SHORT’da ne ola, diyorsanız o zaman hemen yolumuzu windows.pas’a çeviriyoruz.Ve GetKeyState aratıyoruz. Ve 20.853 ‘üncü satırda şöyle bir tanımlama ile karşılaşıyoruz.

  function GetKeyState(nVirtKey: Integer): SHORT; stdcall;

Eee burada da SHORT diyor. Biz merak ediyoruz, programcı meraklı olur ;) SHORT neye tekabül ediyor diye ve en sonunda buluyoruz.
Yine Windows.pas satır 155 de şöyle bir tanım var.

  SHORT = Smallint;

Hımm demek ki SHORT denilen şey bizim SmallInt imiş..İyi güzel diyoruz. Bakıyoruz Delphi Help’den SmallInt’de 16 bitmiş..Şimdi diyeceksiniz ki neden bu kadar inceledin canım tipi.Açıklayacağım onun da sırası gelecek, hatta geldi :)

Windows API Help’de GetKeyState fonksiyonu için şöyle birşey diyor:

“If the function succeeds, the return value specifies the status of the given virtual key. If the high-order bit is 1, the key is down; otherwise, it is up”

Hımm yani bize diyorki; bu tuşa basıldığını geri dönen değerin High order bitinin 1 olması ile kontrol edebilirsiniz. Şimdi bu fonksiyon bize SmallInt bir değer döndürüyor ve bizde biliyoruz ki SmallInt 2 Byte(16 bit). Windows API yardımında bize bu byte’lardan birinin set edilmiş olarak döneceği söyleniyor.Ne demek bu set edilme. Şu demek, 2nci byte’ın değeri bir Byte değişkeninin alabileceği maksimum değere eşit olacak demek.(Hatırlarsanız bir byte’da 8 adet bit vardır ve yanyana 8 tane 1, 255 sayısına tekabül eder, bu da bir byte’ın alabileceği maksimum değerdir.)

Sözün özü, GetKeyState fonksiyonundan dönecek değerin high byte’ı 255 olacakmış demek ki..Valla ben Help’in yalancısıyım.O halde kodumuza geçelim..

Formunuzun KeyPreview özelliğini true yaptıktan sonra Formun OnKeyDown olay yöneticisinde aşağıdaki şu kodu yazacağız.Aşağıdaki kodda işkenceye başlamadan önce şimdilik sadece F5 tuşunu kontrol edeceğiz.

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
	siResult : SmallInt;
begin
  siResult := GetKeyState(VK_F5);
  ShowMessage('Sonuç=' + InttoStr(siResult));
end;

Güzel sade bir kod, ama istediğimiz değeri göstermedi ki..Hani biz bunun High byte’ını alacaktık..Evet doğru söylüyorsunuz, onun için 2 Byte’lık SmallInt’i parçalayabilmek lazım.Ben bu tarz şeyler için Delphi sağolsun record kullanıyorum.

Şöyle ki:

type
  TKeyRecord= record
    Lo : Byte;
    Hi : Byte;
end;

Şimdi gerçek kodumuzu yazmaya başlayabiliriz nihayet. :)

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  //Ctrl + Shift + F5 + 7 + 8 işkence tuşları
  if (
      (TKeyRecord ( GetKeyState( Vk_Control )).Hi = 255) and
      (TKeyRecord ( GetKeyState( Vk_Shift   )).Hi = 255) and
      (TKeyRecord ( GetKeyState( Vk_F5      )).Hi = 255) and
      (TKeyRecord ( GetKeyState( Ord('7')   )).Hi = 255) and
      (TKeyRecord ( GetKeyState( Ord('8')   )).Hi = 255)
     ) then ShowMessage('Sürpriz');
end;

İşte hepsi bu, iyi işkenceler.. ;)

Yorum Yazın