|
|
|||||||||||||
|
|
Windows'un Pencereleri - III • Pencereleri Bulmak Windows'un pencerelerine ulaşmak ve pencere bilgilerini elde etmek çok çeşitli yollarla mümkündür. Belirli özellikteki pencerelere doğrudan ulaşılabilmesi dışında sınıf ve başlık bilgilerine göre arama yapılabilir, pencerelere göreceli olarak ulaşılabilir veyahut tüm pencerelerin listesi bir kerede elde edilebilir. Windows'un Pencereleri'nin üçüncü ve son bölümündeki PencereBul ve ListeMatik örnek uygulamaları ile pencereler farklı özelliklere göre aranabiliyor, pencereler üzerinde çeşitli işlemler yapılabiliyor. PencereBul'da ek olarak Windows'taki not metin (memo) kutularının içerikleri elde edilebiliyor. Geçen ay bahsettiğimiz ListeMatik'in kodları bu ay CD'mizde yer alıyor. PENCERELERİ BULMAK Windows'taki pencerelere ulaşmak bazı hallerde çok gerekli olabilir. Genellikle çalışan diğer uygulamalardan birine ulaşmak ihtiyacı duyulmaktadır. Elde özel hiçbir bilginin olmadığı durumlarda pencereleri bulmanın en kolay yollarından biri FindWindow işlevini kullanmaktır. FindWindow'u kullanmak için hedef pencerenin sınıf türünü ve pencere başlığını biliyor olmak gerekir. (Sınıf türleri -yani class- her pencereye göre ve hatta pencerenin geliştirildiği uygulamaya göre değişebilir. Örneğin Delphi'de oluşturulan düğmeler TButton sınıfında olurken, VB düğmeleri genellikle ThunderRT6CommandButton gibi bir sınıf türünde olurlar.)
FindWindow( Pchar('Notepad'), Pchar('Untitled - Notepad') );
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long MsgBox FindWindow("Notepad", "Untitled - Notepad")
H:=GetWindow(12345, GW_HWNDNEXT); //Sonraki komşu Bir pencerenin içindeki tüm alt pencereleri listelemek için daha önce yaptığımız gibi, GetWindow'u döngü ile kullanmak yerine sayısallaştırıcı EnumChildWindows işlevini kullanmayı deneyelim. procedure AltPencereler(var h:hwnd; l:lParam); procedure TAnaForm.Button1Click(Sender: TObject); EnumChildWindows 12345 HWND değerine sahip pencerenin alt pencerelerini listelemek için, her alt pencere için yeniden olacak şekilde AltPencereler genel yordamını sırayla çağırıyor. EnumChildWindows AltPencereler işlevinin h geçiş değişkenine alt pencerenin HWND değerini gönderiyor. Pencere bulmak için kullanılan işlevlerin önemli bir diğeri de WindowFormPoint'tir. Doğrusu pencerenin kullanıcı tarafından bulunmasının istendiği durumlarda bu işlev etkindir. WindowFromPoint ekranda belirli bir noktada görüntülenen pencerenin HWND değerini verir. Örnekte fare işaretçisinin bulunduğu noktadaki pencere getiriliyor. var
Windows hemen tüm pencereler üzerinde neredeyse sınırsız sayıda işlem yapılmasına olanak vermektedir. HWND değerini bildiğiniz herhangi bir pencerenin, kendi uygulamanızdaymış gibi özelliklerini değiştirmeniz mümkündür. Ekteki PencereBul'da genel pencere işlevlerinin bir kısmı yer alıyor. Doğrusu pencereler üzerinde işlem yapmak için işlevlerin yanında Windows mesajları da kullanılmaktadır. Örneğin GetWindowText işlevi ile WM_GETTEXT mesajı benzer iş yapar. WM_GETTEXT pencere başlıklarını alabilmekle birlikte Windows'taki metin kutularının içeriğini getirebilir. Aşağıdaki kodda h penceresinin başlığının ilk 1000 karakteri s'ye aktarılıyor. Pencere bir not metin kutusu (memo) olduğunda kutunun içeriğini getirir. SendMessage( h, WM_GETTEXT, 1000, s ); Metin kutularının içeriğini tam olarak almak için öncelikle WM_GETTEXTLENGTH ile kutudaki metnin boyunu öğrenmek gerekir. uzunluk:=SendMessage( h, WM_GETTEXTLENGTH, 0, 0 ); Windows'taki standart metin kutuları bu komutları aynı şekilde destekler.
Windows'taki genel not metin kutularında hemen her türlü işlem mesaj gönderme yoluyla yapılabilir. Basitçe bir not kutusunun sonuna metin eklemek için, aşağıdaki NotSatiriEkle işlevi kullanılabilir.
metin:= M + #13#10; SatirAdedi:= SendMessage(NotAdres,EM_GETLINECOUNT,0,0); SendMessage(NotAdres,EM_SETSEL,SatirSira,SatirSira); SendMessage(NotAdres,EM_REPLACESEL,0,integer(PCHAR(metin))); end; ... Spymon++ ya da Spy++ ile geçerli bir not metin kutusu bulduktan sonra yukarıdaki kodu çalıştırmayı deneyin.
BringWindowToTop ile bir pencere en üste getiriliyor: CascadeWindows pencere altındaki çocuk pencereleri ekrana döşüyor: CloseWindow pencereleri simge durumuna (minimize) getiriyor. Formlar dışında
düğme ve metin kutusu gibi pencereler de simge durumuna getirilebilir: WM_CLOSE mesajı ise pencereyi kapatıyor: Bunun dışında MoveWindow pencereleri taşıyıp, ShowWindow da pencereleri büyütür ve küçültür. MoveWindow(12345, sol, üst, genişlik, yükseklik, True); ShowWindow(12345, SW_MINIMIZE);
Her pencere, görüntüsüyle ilgili bilgileri stil özelliklerinde depolar. Pencerelerin normal ve gelişmiş stil özellikleri vardır. Normal stillere GetWindowLong işlevine GWL_STYLE değeri gönderilerek ulaşılır. Gelişmiş stiller için ise GWL_EXSTYLE kullanılır. Stilleri kullanarak pencerenin görüntüsünde birçok değişiklik yapılabilir. Örneğin bir Windows formunun sağ üst köşesindeki küçültme, büyütme, kapatma düğmeleri, pencerelerin kenarlıkları, başlık çubukları, hareket yetenekleri stillerle ayarlanır.
Resimdeki pencere Windows Gezgini'nin biraz değiştirilmiş hali. Pencerenin stil bilgilerine ulaşarak başlık çubuğunu, sistem menüsünü, üst düğmeleri kaldırdık ve pencereye yatay ve düşey kaydırma çubukları ekledik.
PencereBul'daki Stiller sayfasında bu tür değişiklikler yapılabilir. Stil bilgileri GetWindowLong ile aşağıdakine benzer şekilde alınır. var Stil bilgilerinin tamamı Integer tipinde bir tamsayıda tutulmaktadır. Bu, bit sayısı kadar özelliğin GWL_STYLE türündeki stilde depolanabileceği anlamına gelir. Nitekim en fazla 32 olabilse de GWL_STYLE ile halihazırda 27 civarında özellik depolanıyor: WS_BORDER, WS_CAPTION, WS_CHILD, WS_CHILDWINDOW, WS_CLIPCHILDREN, WS_CLIPSIBLINGS, WS_DISABLED, WS_DLGFRAME, WS_GROUP, WS_HSCROLL, WS_ICONIC, WS_MAXIMIZE, WS_MAXIMIZEBOX, WS_MINIMIZE, WS_MINIMIZEBOX, WS_OVERLAPPED, WS_OVERLAPPEDWINDOW, WS_POPUP, WS_POPUPWINDOW, WS_SIZEBOX, WS_SYSMENU, WS_TABSTOP, WS_THICKFRAME, WS_TILED, WS_TILEDWINDOW, WS_VISIBLE, WS_VSCROLL Bu özelliklerin herbiri stil içinde var veya yok kabul edilir. Bir özelliğin stil içinde olup olmadığına bakmak için değerleri AND ile karşılaştırmak yeterlidir. if (stil and özellik) = özellik then .. koşulu gerçekleştiğinde özelliğin stil içinde olduğunu söyleyebiliriz. Tersi ise aşağıdaki gibi. if (stil and özellik) <> özellik then .. PencereBul'daki Stiller sayfasında Getir düğmesi bu şekilde çalışıyor. Uygula düğmesi ise stilde değişiklikler yapıp bu stili pencereye geri yüklüyor. Stil yüklemek SetWindowLong ile yapılır ve GW_STYLE ile birlikte yeni stil bilgisini de geçiş değeri olarak alır. SetWindowLong( 12345, GWL_STYLE, stil ); Genel sayfasındaki Ters Çevir düğmesi pencerenin yatayda yönünü değiştirmek için GW_STYLE yerine GW_EXSTYLE ve WS_EX_LAYOUTRTL özelliklerine başvurur. Stilde değişiklik yapmak için ilgili özelliği sayısal olarak stile eklemek ya da stilden çıkarmak gerekir. Örnekte bu, inc ve dec ile yapılıyor.
procedure TAnaForm.btnTersCevirClick(Sender: TObject); h:=12345; stil:= GetWindowLong(h, GWL_EXSTYLE); //WS_EX_LAYOUTRTL var ise çıkar, yok ise ekle. SetWindowLong(h, GWL_EXSTYLE, stil); end; Gerçekte WS_EX_LAYOUTRTL Arap alfabesi için sağdan-sola (Right-To-Left) çevirme yapmaktadır.
Windows, geliştirme araçlarında kullanılması için bazı ortak bileşenler sunmaktadır. Zengin metin kutuları, düz listeler, ağaç listeleri gibi bileşenler bunlardan birkaçıdır. Örneğin Delphi'de Win32 sayfasındaki kontroller aslında Windows'un ortak bileşenlerindendir. Ortak bileşenler her uygulamada aynı temel özelliklere sahiptir. Bunların karakteristiği VB'de ya da Delphi'de ayrı kullanıldıklarında değişmez. Bu bileşenler Windows'ta çok sık kullanılır. Delphi'deki TreeView ve ListView ile Windows Gezgini'ndeki ağaç dizin ve dosya listeleri aynı özelliktedir. Bu durumda başka uygulamalardaki listelere ait bilgileri elde etmek, hatta onlarda değişiklik yapmak olanaklıdır. Ekteki ListeMatik, Windows'taki listelerden bilgi alabiliyor ve düz listelerde çeşitli değişiklikler yapabiliyor. Listelerde, salt mesaj gönderme yoluyla değişiklik yapılabilmektedir. Aşağıdaki iki satır ile, HWND değeri bilinen bir düz listeye yeni bir değer ekleniyor ve eklenen yeni satır seçiliyor. SendMessage( hwnd, LB_INSERTSTRING, sıra, Integer(PChar('Yeni
Eklenen Değer'))); ListeMatik'in ekteki kodlarında listelere mesaj göndermekle ilgili daha ayrıntılı örnekler bulacaksınız.
İyi seneler. DOSYALAR: |