Merhaba. Öncelikle demeliyim ki başlık canınızı sıkmasın, kafanızı karıştırmasın. Altta yapacağım kısa açıklama her şeyi gün gibi aydınlatacak. (Sanırım... Umarım... Belki... Neyse bakın işte....)
Windows'a neden Windows denildiği genelde yanlış bilinmektedir. Etrafta söylenen pencere yöneticisi kullanması şeklindedir. Aslında yanlış değil ama eksik.
Windows'ta çalışan her nesne bir windowdur(pencere) aslında. Hani sağ üstteki kırmızı çarpı ile kapatabildiğimiz form pencerelerinden bahsetmiyorum sadece. Mesela alttaki taskbar, bir penceredir. Microsoft Word kullanırken gördüğümüz üstteki Dosya, Düzelt, Araçların falan bulunduğu bar da bir penceredir. Hatta onların her birisi de birer penceredir.
Bunda anlaştık mı? Tamam. : )
Elbette Windows bu pencereleri açıp sahipsiz koymaz. Hepsinin yaratılma anında tanımlanmış bir kimlik numarası vardır. İşte onlara "Handle" denir. Bu handlelar aracılığı ile o pencereler hakkında bilgilere, isimlerine, türlerine ulaşabildiğimiz gibi onlara mesajlar da yollayabiliriz. Mesela C#'ta yazdığımız bir programla başka bir programın bir metin kutusundaki değeri okumak hatta onu değiştirmek.
Maskelenmiş(***** şeklinde) şekilde tutulan bir metin kutusunun içindeki parolayı böyle bir teknikle alsak acaba bize ne görünürdü? Maskeli parolayı olduğu halde görür müydük? Denemesi zevkli olur. Ancak şu an onu yapmayacağız. Adım adım gidelim.
Amacımız bir Parent Window(Ana pencere) içindeki Child Window(çocuk pencere)ların handlelarını öğrenmek. En azından bunu yapalım önce. : )
*****************************************************
Bu tür low level işleri ne yazık ki doğrusan .net framework'ü ile yapamıyoruz. Ama elimizde aslanlar gibi Win32 API'ler var. Microsoft Windows'un bel kemikleri. İşletim sistemi bu işleri nasıl yapıyorsa, işte biz de öyle yapacağız.
İhtiyacımız FindWindow ve EnumChildWindows fonksiyonları. İkisi de User32.dll kütüphanesi için unmanaged kodlar. Ne güzel ki C#'ta unmamaged kütüphanelere erişim şansımız var. Bunu da framwork içinden System.Runtime.InteropServices referansınız ekleyerek yapıyoruz.
İsterseniz kodlara geçelim;
using System;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
namespace childhandlesiralama
{
class Program
{
[DllImport("user32.dll", SetLastError = true)]static extern IntPtr
FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]public static extern int
EnumChildWindows(IntPtr hwnd, EnumChildCallback Proc, int lParam);
public delegate bool EnumChildCallback(IntPtr hwnd, ref IntPtr lParam);
static void Main(string[] args)
{
IntPtr pHndl = FindWindow("notepad", null);
EnumChildWindows(pHndl, EnumChildProc, 0);
Console.ReadLine();
}
public static bool EnumChildProc(IntPtr hwndChild, ref IntPtr lParam)
{
Console.WriteLine("Handle: " + hwndChild.ToString());
return true;
}
}
}
Burada programın yaptığı (eğer açıksa) Notepad uygulamasının child handlelarını sıralamak. FindWindow ile Notepad'in handleını buluyoruz. Bu Parent Handle oluyor. Ana Handle diyebiliriz. Bu Parent Handle'ı da EnumChildWindows içinde kullanarak çocukların handlelarını bulacağız. Mesela benim sistemimde 394812, 394814 numaralı iki child handle buldu. Bu değerler 10luk sayı sisteminde. Ancak Windows bunları 16lık sayı sisteminde tutup, işlem yapar.
Yani bulduğu 2 Child Handle 0x6063C ve 0x6063E değerlerine sahip. Bunların ilki (0x6063C) Notepad'in altındaki Status Bar, ikincisi de üste taraftaki "File, Edi vb.." gibi şeylerin bulunduğu toolbar. Elbette sadece handlea gözle bakarak bunları öğrenmek olası değil. Ancak Win32 API'nin büyülü dünyası bunların hepsini sunuyor. : )
Gördüğünüz gibi gayet kısa ve kolay. Burada bahsetmek istediğim tek bir önemli nokta var. Bize child window handlelarını veren EnumChildWindows fonksiyonunun dönüş değeri bool. Bu değerleri fonksiyonun ikinci argümanı olarak kendi tanımladığımız EnumChildCallback türünde bir fonksiyon yaratarak ve onunla değerleri alarak yapıyoruz.
Win32API'deki bazı fonksiyonların böyle bir handikapı var. Doğrudan işini yaptığı sonucu getirmiyor, argüman olarak bir callback fonksiyonu çalıştırarak alıyoruz.
Bundan sonraki yazının konusu da handle değeri bilinen bir windowun (eğer varsa) başlık ismine ve class türüne(açıklayacağım) ulaşmak.
Teşekkürler.
1 yorum:
teşekkür ediyorum uzun süredir aradığım bir konu
devamını merakla bekliyorum (exenin içindeki combo yada text den veri almayla ilgili bir örnek olursa daha çok sevinirim)
teşekkürler
Yorum Gönder