Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C# İle Mouse’a Hükmedelim

Merhaba,

İçeriğimizin başlığından dolayı C# Mouse eventlarını kullanacağımızı sanmış olanlar olabilir. Baştan söylemekte fayda var ki, bu makalede Win32 API’lerinden faydalanarak işletim sisteminin nimetlerini kullanacak, faremize fiziksel müdahalede bulunacağız.

C# İle Win32 API Entegrasyonu Nasıl Yapılır? başlıklı makalemde C# ile Win32 API entegrasyonuna değinmiş bulunmaktayım. Haliyle bu içeriğimizde kullanacağımız yapıları tanımlayabilmeniz için öncelikle verdiğim adresteki makaleye göz atmanızda fayda olduğunu belirtiyor, alışılagelmişin dışındaki gramersel kullanımı bildiğinizi varsayarak ilgili konumuzu ele almaya başlıyorum…

Mouse’a fiziksel olarak müdahale edebilmemiz için “User32.DLL” kütüphanesindeki nimetlere erişmemiz gerekmektedir. Aşağıdaki sınıfımız ilgili kütüphaneyi import ederek fareye hükmedecek metotları extern etmektedir.

    public class Win32
    {
        [DllImport("User32.Dll")]
        public static extern long SetCursorPos(int x, int y);

        [DllImport("User32.Dll")]
        public static extern bool ClientToScreen(IntPtr hWnd, ref POINT point);

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int x;
            public int y;
        }
    }

Yukarıdaki kod bloğunu incelerseniz eğer “ClientToScreen” extern metodu farenin lokasyonunu tutmakla, “SetCursorPos” extenr metodu ise fareyi ilgili lokasyona çakmak işleviyle yükümlüdürler.

Hade gelin ilgili sınıfı kullanarak faremize hareket kabiliyeti kazandıralım.

    class Program
    {
        static void Main(string[] args)
        {
            Win32.POINT p = new Win32.POINT();
            p.x = 280;
            p.y = 320;

            Win32.ClientToScreen(IntPtr.Zero, ref p);
            Win32.SetCursorPos(p.x, p.y);
        }
    }

Yukarıdaki gibi kodumuzu oluşturduktan sonra projemizi derleyip çalıştırdığımız zaman aşağıdaki videoda da olduğu gibi fademizin lokasyonu değişecektir.

Eğer ki farenin lokasyonunu öğrenmek istiyorsak Win32 sınıfımıza “GetCursorPos” metodunu extern etmemiz gerekcektir.

    public class Win32
    {
        .
        .
        .
        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(out POINT lpPoint);
        .
        .
        .
    }

Bu metodu aşağıdaki gibi kullanırsak eğer ekranın herhangi bir yerindeki farenin lokasyonunu elde edebilmekteyiz.

    class Program
    {
        static void Main(string[] args)
        {
            Win32.GetCursorPos(out Win32.POINT point);
            Console.WriteLine(point.x + " " + point.y);
        }
    }

out olarak gelen point değişkeni sayesinde farenin koordinatlarını elde edebilmekteyiz.

Anlayacağınız C# ile Win32 API’sini kullanarak fareye müdahale etmiş bulunmaktayız. Ama buradan bakınca biraz önce yapmış olduğumuz işlemde fare çok hızlı bir şekilde anlık olarak verilen lokasyona gitmektedir. Eğer ki olaya biraz animasyon katmak isterseniz aşağıdaki gibi bir çalışma yapabilirsiniz.

    public class Win32
    {
        .
        .
        .
        [DllImport("user32.dll")]
        public static extern bool GetCursorPos(out POINT lpPoint);
        public static System.Drawing.Point GetCursorPosition()
        {
            POINT lpPoint;
            GetCursorPos(out lpPoint);

            return lpPoint;
        }
        .
        .
        .
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int x;
            public int y;

            public static implicit operator System.Drawing.Point(POINT point)
            {
                return new System.Drawing.Point(point.x, point.y);
            }
        }
        .
        .
        .
    }

Öncelikle Win32 sınıfımızda “GetCursorPosition” isimli farenin koordinatlarını bize System.Drawing.Point tipinde dönen bir metot oluşturuyoruz. Ayriyetten POINT struct’ımızda System.Drawing.Point tipine implicit çevrimi yapabilmek için “implicit operator” yapısını kullanmaktayız.

Ve ardından;

    class Program
    {
        static Win32.POINT hedeflenenkonum;
        static int x, y;
        static Timer tmr;
        static void Main(string[] args)
        {
            hedeflenenkonum = new Win32.POINT();
            hedeflenenkonum.x = 280;
            hedeflenenkonum.y = 320;

            Win32.ClientToScreen(IntPtr.Zero, ref hedeflenenkonum);

            tmr = new Timer();
            tmr.Interval = 1;
            tmr.Elapsed += Tmr_Elapsed;
            tmr.Start();

            Console.Read();
        }

        private static void Tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            Win32.ClientToScreen(IntPtr.Zero, ref hedeflenenkonum);

            if (Win32.GetCursorPosition().X < hedeflenenkonum.x)
            {
                if (Win32.GetCursorPosition().X - Win32.GetCursorPosition().X < 10)
                    Win32.SetCursorPos(Win32.GetCursorPosition().X + 1, Win32.GetCursorPosition().Y);
                else
                    Win32.SetCursorPos(Win32.GetCursorPosition().X + 10, Win32.GetCursorPosition().Y);
            }
            else if (Win32.GetCursorPosition().X > hedeflenenkonum.x)
            {
                if (Win32.GetCursorPosition().X - hedeflenenkonum.x < 10)
                    Win32.SetCursorPos(Win32.GetCursorPosition().X - 1, Win32.GetCursorPosition().Y);
                else
                    Win32.SetCursorPos(Win32.GetCursorPosition().X - 10, Win32.GetCursorPosition().Y);
            }
            if (Win32.GetCursorPosition().Y < hedeflenenkonum.y)
            {
                if (hedeflenenkonum.y - Win32.GetCursorPosition().Y < 10)
                    Win32.SetCursorPos(Win32.GetCursorPosition().X, Win32.GetCursorPosition().Y + 1);
                else
                    Win32.SetCursorPos(Win32.GetCursorPosition().X, Win32.GetCursorPosition().Y + 10);
            }
            else if (Win32.GetCursorPosition().Y > hedeflenenkonum.y)
            {
                if (Win32.GetCursorPosition().Y - hedeflenenkonum.y < 10)
                    Win32.SetCursorPos(Win32.GetCursorPosition().X, Win32.GetCursorPosition().Y - 1);
                else
                    Win32.SetCursorPos(Win32.GetCursorPosition().X, Win32.GetCursorPosition().Y - 10);
            }

            if (Win32.GetCursorPosition().X == hedeflenenkonum.x && Win32.GetCursorPosition().Y == hedeflenenkonum.y)
                tmr.Stop();

        }
    }

şeklinde kodumuzu inşa edersek eğer aşağıdaki ekran görüntüsünde olduğu gibi bir animasyonlu fare hareketiyle karşılaşacağız. Tabi buradaki algoritmik durumu ayrıştırmayı sizlere bırakıyorum.

Gördüğünüz üzere faremizi Win32 API sayesinde hareket ettirmiş olduk.

Düşünsenize… Yazılımsal olarak fare ve klavye gibi donanım kontrollerini bot yazılımlarına entegre ederek yapabileceklerinizin sınırsızlığını hissedin.

Sonraki yazılarımızda bu konuya benzer nitelikte olan Win32 API’leriyle fareye direkt olarak tıklama, sürükleme vs. gibi olaylar yarattıracağız.

Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

2 Cevaplar

  1. Alican dedi ki:

    farenin tıklandığını nasıl algılayabilirim ?

  1. 20 Nisan 2017

    […] yazılarımdan C# İle Mouse’a Hükmedelim başlıklı yazımda Win32 API kullanarak mouse’a programatik müdahale ederek hareket […]

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir