My Profile Photo

Mehmet Cem Yücel


Technical Writings.
Architecture, Security, Java, Golang, Devops, Microservices, Spring Boot, Kafka, Distributed Systems and Blockchain


Otomatik Fare Kontrolü

Bugün interop servisleri aracılığıyla windows işletim sistemi üzerinde fare hareketlerini kontrol etme örneği yapacağız.

Konumuza giriş yapalım. Gün boyunca bilgisayarda tekrar tekrar yaptığınız şeyler oluyordur elbet. Farenizin belirli aralıklarla ekranın bir noktasını tıklaması gerektiği ve “keşke bunu benim yerime birisi yapsaydı” dediğiniz şeyler olmuştur. Kendimden örnek vermem gerekirse, Facebook’ta Fishville isimli bir oyun var belki duymuşsunuzdur. Bu tür oyunlarla pek aram olmamasına rağmen son 2 gündür bu oyun sardı ve tam manasıyla sürekli onunla uğraşıyorum. Oyunda belirli aralıklarla balıklarınızı beslemek zorundasınız, yoksa ölüyorlar. Ve her zaman bilgisayar başında olamıyorsunuz, dışarı çıkmanız gerektiğinde veya başka işlerle meşguliyetinizde bir de bakıyorsunuz balıklar mefta :))) Bu belirli aralıklarla balık besleme işi de tam bir angarya!! Angarya olduğu kadar sevimsiz gelen bu işlerimizi otomatikleştirmemiz de mümkün ise niçin yapmayalım :)

Artık biraz teknik konulara girelim. Bugün fare olaylarının tetiklenmesi için ne türlü işlemler yapmamız gerektiği ve nasıl bir yöntem izleyeceğimizden bahsedeceğim. İşletim sistemleri kendi fonksiyonlarının kullanılabilmesi için programcılara bazı kütüphaneler sunar. Bu kütüphaneleri API (Application Programing Interface) olarak adlandırıyoruz. Programcılar bu kütüphaneler içerisindeki fonksiyonları kullanarak kendi programlarına işlevsellikler katabilmektedirler. Biz de projemizde bu API’lerden faydalanacağız.

Kütüphaneler konusunda daha sonra detaylıca bir yazı paylaşmayı düşünüyorum ama şimdilik kısaca değinmek istiyorum. Kütüphaneler, temelde aynı işlemleri yapan farklı uygulamaların her defasında tekerleği baştan icat etmesini engellemek için kullanılırlar. Birden fazla process ilgili koda tek bir kütüphane ile bu sayede ulaşabilir. Diğer bir faydası da bu kodların defalarca belleğe alınması yerine bir kez alınarak processlerin o bellek alanını ortak kullanmalarını sağlayarak performans çözümü üretmektir. Windows ortamında iki tür kütüphane vardır. Statik kütüphaneler (.lib) ve dinamik kütüphaneler (.dll).

Windows programcıların kullanabilmesi için temelde 3 tür API sunmaktadır. Bunlar

  1. Kernel: sistemin kaynak ve bellek yönetimi için
  2. User: temel kullanıcı IO ları için
  3. GDI: sistemin temel arayüz işlemleri içindir.

Programcılar bu API’leri kullanarak projelerinde Windows’a ait bazı işletimleri kullanabilmektedirler. Bugün biz de Windows’un “User32.dll” kütüphanesi yardımı ile mouse ve keyboard olaylarının nasıl yaratılabileceği üzerisinde duracağız.

C# ile API’lerin kullanılabilmesi için ilgili kütüphanenin projemize tanıtılması gerekmektedir. DllImport işlemi için de
1namespace’ini projemize eklememiz gerekiyor. Bu namespace ile CLR’ın (Common Language Runtime) unmanaged kodu managed koda çevirirken kullanılan servisleri kullanabiliyor ve parametre geçebiliyor olacağız.

2
Sıra geldi projemizde kullanacağımız kütüphanenin projemize tanıtılmasına. Kütüphanenin ismini verdikten sonra hangi charseti kullanacağını ve hangi çağırma biçimini kullanacağını parametre olarak veriyoruz. Çağırma biçimleri sistemin işleyişi ile ilgili olup çağırılan kodun nasıl arayüzünü temsil etmektedir. Yani hangi parametrelerin belleğe alınacağı, fonksiyonda hangilerinin kullanılacağı gibi ve bunların hangi şekillerde yapılacağı gibi standartlardan birisini seçmemizi sağlar. Kütüphanemizi projemize tanıttıktan sonra bu kütüphaneden hangi fonksiyonu hangi parametrelerle çağıracağımızı belirliyoruz.

3
Projemizde fare olayını tetikleyeceğiz. Fare ile ilgili bir olay tetiklendiğinde, örneğin tıklandığında aygıt bir interrupt üretir. Bu interrupt aygıtın controller ı aracılığıyla CPU a iletilir. CPU gelen interrupt ın içerisinde hangi aygıttan geldiği ve ne yapmak istediği ile ilgili bilgiler mevcuttur. CPU da bu işlem ile ilgili kodların nerede olduğunu öğrenmek için interrupt vector e bakar. Bu kodlar aslında donanımlara ait kodlardır ve interruptın nasıl işletileceğini belirlerler. Interrupt vectorden ilgili kodun başlangıç adresini öğrenen CPU, ardından o adresteki kodları işletmeye başlar. Bu kadar uzun ve anlatması dahi sıkıcı aşamalar bizlerin farkında olmadığımız bilgisayarın arkada çalışırken gerçekleştirdiği işlemler. Bizim yapmak istediğimiz ise fare tıklanmadan yani interrupt oluşmadan ilgili kodun işlenmesini sağlamak. Kesintiyi bir donanımdan almayacağımıza göre CPU’ya hangi bellek adresindeki kodları işleteceği bilgisini kendimiz vermek zorundayız. Fare olaylarına ait bellek adreslerini tanımlayan flag hexadecimallerini aşağıda bulabilirsiniz.
4
Aslında bu adımdan sonra yapmamız gereken şey olarak sadece bu metodumuzu çağırmak oluyor. Kısaca yazdığım bir uygulamayı paylaşırsam sanırım daha anlaşılır olabilir. Parça parça kodlarımızı inceleyelim.
11
Buraya kadar yukarıda bahsettiğimiz işlemleri yapıyoruz. Dll imizi tanıtıyor ve flaglerimizi tanımlıyoruz.

12
Programımızın içerisinde kullanacağımız global değişkenlerimizi tanımlıyoruz.

13
Formumuz açılır açılmaz bilgisayarımızın ekran çözünürlüğüne göre trackBar ımızın her bir tick’inde faremizin kaç piksel hareket edeceği değerlerimizi set ediyoruz.

14
Faremizin pozisyonunu ayarlamak için faremizle ilgili trackBar’ı tıkladıktan sonra klavyemizin sağ ve sol ol tuşları ile faremizin konumlanacağı noktayı ayarlıyoruz. Bunu ekranda gösterebilmek için mouseMove methodunu kullanacağız. Ve dikey-yatay ayrımının yapılabilmesi için enum ekledim.

15
Faremizin görüntüsünü ekranda görerek noktamıza karar verdik. Noktamızın koordinatları X ve Y isimli 2 integer değişkende tutuluyor. Zaman bilgimizi de set ettikten sonra programımızı çalıştırabiliriz.

16
TextBox ımızdaki verinin doğruluğunu kontrol ettikten sonra timer ımızı aktifleştirebiliriz. Tıklama durumu aktif iken fare koordinatlarının ve tıklama sıklığının değiştirilmemesi için kontrollerimizi kapatıyoruz.

17
Geri kalan ıvır zıvır methotlar da burada :P Burada dikkat çekmek istediğim nokta programın başında DllImport ile tanımladığımız mouse_event methodunu doğrudan kullanabiliyoruz. Bu da bizim COM objelerine ulaşabildiğimizi ve projemizde kullanabildiğimizi gösteriyor.

Umarım faydalı olmuştur. Başka makalelerde görüşmek üzere. Aşağıda projeye ait dosyalar bulunmaktadır.

  • Programın çalıştırılabilir haline ulaşmak için burayı tıklayabilirsiniz.

  • Programın proje dosyasına ulaşmak için burayı tıklayabilirsiniz.

  • Fishville oyunu oynayanlar için balık besleme programı için de burayı tıklayabilirsiniz :))




May interest this topics

If you interested in Blockchain Technologies,


comments powered by Disqus