Makale Özeti

Bu makalede sistem tarafından gönderilen mesajların yakalanışı anlatılmaktadır.

Makale

Sistem Tarafından Gönderilen Mesajların Yakalanması

Windows mesaj tabanlı çalışan bir sistemdir ve her mesaj belirli bir nedenden dolayı oluşur. Örneğin kullanıcının klavyede bir tuşa basması ya da mouse ile çift tıklaması gibi. Windows, oluşan mesajı, özel bir veri yapısı biçiminde ifade ederek, mesaj kuyruğuna yerleştirir. Win32 sistemlerinde aşağı seviyeli API programlaması yapan kişiler ise, geleneksel olarak bu mesajları yakalama teması üzerine hareket ederek, Windows uygulamalarını yazmaktadırlar. Ancak sistem mesajlarının oluşturulması, mesaj kuyruğuna eklenmesi ya da kuyruktan alınması gibi rutinler, Windows un aşağı seviyeli çalışması ile ilgili bilgi gerektirir. İstisnai durumlar dışında Visual Basic .NET ya da C# ile managed uygulamalar yazan bir programcının mesaj işleme rutinlerini kullanması gerekmemekle birlikte .NET Framework Base Class Library içerisine benzer işlemlerin kolay yapılabilmesini sağlayacak IMessageFilter isimli bir arayüz (interface) eklenmiştir.

IMessageFilter Arayüzünün Kullanımı

Bu arayüz, bir mesajın kontrol ya da pencereye gönderilmeden, araya girilerek (hook işlemi) yakalanmasını sağlar. IMessageFilter arayüzü içerisinde tanımlanmış olan PreFilterMessage() isimli metot bir sınıf içerisinde implemente edilmek sureti ile kullanılır.

Function PreFilterMessage( _
   ByRef m As Message _
) As Boolean

PreFilterMessage() metodu, Message yapısı türünde bir parametre almaktadır. Bu parametreye ilişkin Msg property’si yakalanmak (filtrelenmek) istenen mesaja ilişkin ID değerini taşır. Metodun implementasyonu sırasında bu property’nin taşıdığı değere bakılarak, gönderilen mesajın ne olduğu anlaşılabilir. Metodun dönüş değeri true ise; söz konusu mesajın gönderilemeden yakalandığı yani filtre edildiği anlaşılır.

Dikkat : Metodun parametresine geçilen bu değer, metot içerisinde değiştirilemez !

Örnek : Aşağıdaki uygulamada IMessageFilter arayüzünü implemente eden CMessageFilter isimli bir sınıf yazılmıştır. PreFilterMessage() metodu, ID değeri 513 olan mesajı yakalayacak biçimde tasarlanmıştır. Bu değer; pencere çalışma alanı içerisinde mouse’un sol tuşuna tıklandığı sırada gönderilen mesajı ifade eder.

Imports System.Windows.Forms
Imports Microsoft.Win32

Public Class CMessageFilter

    Implements IMessageFilter

    Public Function PreFilterMessage( _
    ByRef m As System.Windows.Forms.Message) _
    As Boolean _
    Implements _
    System.Windows.Forms.IMessageFilter.PreFilterMessage

         If (m.Msg = 513) Then
             MessageBox.Show("WM_LBUTTON : " & m.Msg)
             Return True
         End If
         Return False
     End Function
End Class

Mesajları yakalamak üzere oluşturulan bu sınıfın bir pencerede kullanılabilmesi için; söz konusu pencereyi temsil eden Form sınıfı içerisine CMessageFilter türünde bir veri elemanı eklenmelidir.

Form sınıfının başlangıç fonksiyonu içerisinde ise bu nesne Application sınıfının AddMessageFilter() statik metodu kullanılarak uygulama ile ilişkilendirilmek zorundadır.

Public Class Form1
     Inherits System.Windows.Forms.Form

     Private msgFilter As CMessageFilter = New CMessageFilter 

#Region " Windows Form Designer generated code "

     Public Sub New()
         MyBase.New()
         InitializeComponent()
         Application.AddMessageFilter(msgFilter)
     End Sub

...

End Class

Yukarıda sayılan eklentiler form sınıfı içerisine yapıldıktan ve uygulama çalıştırıldıktan sonra pencere çalışma alanı üzerinde herhangi bir yere mouse’un sol tuşu ile tıklanırsa yakalanan mesajın ID bilgisini gösteren bir mesaj kutusu gözlemlenir.

Uyarı : Mesaj filtrelerinin bilinçsiz kullanımı uygulamanın performansını olumsuz etkileyebilir.



Aykut TAŞDELEN
MVP Most Valuable Professional

aykuttasdelen@yazgelistir.com