Makale Özeti

Bu yazımızda MultiPoint SDK ile beraber WPF uygulamalarında MultiPoint programlama dünyasına hızlı bir giriş yaparak birden çok imleç ve fare kullanılabilen uygulamaların nasıl yazılabileceğini inceliyoruz.

Makale

Makalemize ilk olarak MultiPoint programlamanın ne olduğunu tanımlayarak başlayalım. Bugün bilgisayarlarımızda alıştığımız sistem sadece tek bir Pointer / İmleç kontrol etmeye dayanır. Örneğin bilgisayarınıza iki fare bile bağlasanız aslında her ikisi de aynı imleci kontrol eder. Oysa geleceğe baktığımızda artık birden çok Pointer'ın bulunduğu sistemlere doğru ilerliyoruz hatta birden çok imlecin tabi ki farklı kullanıcılar tarafından kullanıldığını da görebiliyoruz. Özellikle i-Phone ile popülerleşen Surface Programming mantığına kısmen yakın olsa da MultiPoint programlamada her bir Point'in kesinlikle ayrı kimliklere ait olduğu varsayılır. Bu varsayımla en azından hangi noktaların hangi kimliğe ait olduğunu bulma gibi bir dertlerle uğraşmaya gerek kalmıyor.

Özetle bu yazımızda amaçladığımız şey bilgisayarımıza bağlı farelerin farklı imleçler şeklinde ekrana yansımasını sağladıktan sonra oluşturacağımız bir düğme kontrolüne de hangi kullanıcının tıkladığını algılayabilecek kodu yazmak.

MultiPoint SDK

Windows ortamında .NET ile MultiPoint uygulamaları geliştirmek istiyorsanız donanımla doğrudan uğraşmamak adına işinizi kolaylaştırabilmek için Microsoft tarafından bir SDK paketi yayınlanmış durumda. MultiPoint SDK olarak geçen paketi bilgisayarınıza yüklediğimizde projelerimizde kullanacağımız kütüphaneleri de edinmiş oluyoruz.

http://www.microsoft.com/downloads/details.aspx?FamilyID=a137998b-e8d6-4fff-b805-2798d2c6e41d&displaylang=en

Yeni bir MultiPoint projesi yaratalım.

Visual Studio içerisinde yeni bir WPF projesi yaratalım ve MultiPoint kütüphanelerini referans olarak ekleyelim. MultiPoint DLL'lerini doğrudan MultiPoint'in yüklendiği klasörün içinde Bin klasöründe bulabilirsiniz. DLL'lerin yanı sıra yarattığımız projeye sağ tuş tıklayarak "Add Existing Item" diyip yine Bin klasöründeki Microsoft.MultiPoint.MultiPointSDK.dll.config dosyasını de eklemeliyiz. Artık her şey hazır, sıra geldi kodlamaya.

İlk olarak uygulamamız için MultiPointSDK'dan bir Instance almamız gerekiyor. Söz konusu değişkenin uygulama genelinde kullanılabilmesi için Application.xaml'ın arkasında tanımlanmasında fayda var.

[VB]

Class Application

 

    Public Shared MultiPointObject As Microsoft.MultiPoint.MultiPointSDK.MultiPointSDK = Microsoft.MultiPoint.MultiPointSDK.MultiPointSDK.GetInstance

 

End Class

[C#]

using Microsoft.MultiPoint.MultiPointSDK;

 

class Application

{

    public static MultiPointSDK MultiPointObject = MultiPointSDK.GetInstance;

}

Application.xaml'ın arkasında yukarıdaki kodumuzu yazdıktan sonra WPF uygulamamızın ana penceresine geçerek MultiPointObject değişkenimizi kullanabiliriz.

[VB]

Application.MultiPointObject.RegisterMouseDevice()

Application.MultiPointObject.CurrentWindow = Me

Application.MultiPointObject.DrawMouseDevices()

MultiPointSDK.SystemCursorPosition = New Point(Me.Left + 10, Me.Top + 10)

MultiPointSDK.HideSystemCursor()

[C#]

Application.MultiPointObject.RegisterMouseDevice();

Application.MultiPointObject.CurrentWindow = this;

Application.MultiPointObject.DrawMouseDevices();

MultiPointSDK.SystemCursorPosition = new Point(this.Left + 10, this.Top + 10);

MultiPointSDK.HideSystemCursor();

Bir sonraki adımda WPF uygulamamızın ana ekranında Page.Load event'ı içerisinde yukarıdaki kodları yazıyoruz. Böylece o an sisteme bağlı fareleri algılayarak ekrana getirebiliyoruz. Bu işlemi yaparken normal imleci de görünmez hale getiriyoruz. Aslında MultiPoint API'ları bizim yerimize donanım olarak var olan her bir fare için ayrı ayrı imleçler yaratıyor. Sistemde o an var olan tüm farelerin bir listesini Application.MultiPointObject.MouseDeviceList dizisinde bulabilir ve her bir MultiPointMouseDevice için ayrı ayrı DeviceVisual tanımlayarak imleçleri değiştirebilirsiniz.

Kendi kontrollerimizi yaratmamız gerek....

Aslında sıfırdan kontrol yaratmaktan bahsetmiyoruz fakat maalesef ki hali hazırdaki WPF kontrollerinin hiçbiri MultiPoint desteklemiyor. Yani hiçbiri farklı imleçler ve onların kimliklerinden haberdar olamıyor. Bu nedenle bizim kendi kontrollerimizi hazırlamamız gerekecek. Bu kontrolleri yaratırken IMultiPointMouseEvents ve IMultiPointGenericDeviceEvents interfacelerini implemente edersek aslında çoğu işlemi yine MultiPoint kütüphanelerine paslamış oluyoruz. Gelin bir Button yaratarak nasıl ilerleyebileceğimizi görelim.

[VB]

Public Class MultiPointColorButton

    Inherits System.Windows.Controls.Button

    Implements IMultiPointMouseEvents

    Implements IMultiPointGenericDeviceEvents

 

End Class

[C#]

public class MultiPointColorButton : System.Windows.Controls.Button, IMultiPointMouseEvents, IMultiPointGenericDeviceEvents

{

}

Yukarıdaki kodları yeni yarattığınız bir VB veya C# dosyasına yapıştırabilirsiniz. Aslında işlemler çok basit; sistemde tanımlı herhangi bir kontrol olarak Button kontrolünü alıp MultiPoint kütüphanelerinden gerekli arayüzleri dahil ediyoruz. Böylece otomatik olarak birçok yeni event tanımlanmış oluyor. İkinci adımda işin biraz karışık kısmına doğru geçiş yapacağız. MultiPoint kütüphanesi ile gelen eventları her bir fare cihazı için ayrı ayrı oluşturuluyor bizim bunları doğru bir şekilde ayrı bir genel geçer eventlar tanımlayarak onlara bağlamamız gerek.

[VB]

    Public Custom Event CustomClick As RoutedEventHandler

        AddHandler(ByVal value As RoutedEventHandler)

            MultiPointMouseEvents.AddMultiPointMouseDownHandler(Me, value)

        End AddHandler

        RemoveHandler(ByVal value As RoutedEventHandler)

            MultiPointMouseEvents.RemoveMultiPointMouseDownHandler(Me, value)

        End RemoveHandler

        RaiseEvent(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)

        End RaiseEvent

    End Event

[C#]

    public event RoutedEventHandler CustomClick {

        add { MultiPointMouseEvents.AddMultiPointMouseDownHandler(this, value); }

        remove { MultiPointMouseEvents.RemoveMultiPointMouseDownHandler(this, value); }

    }

Yukarıdaki kodlarda kendi tanımladığımız eventların ataçlanması ve detaçlanması noktasında yapılacak işlemleri de biz belirliyoruz ve elimizde MultiPoint kütüphanesinden gelen metodları kullanıyoruz. Kodumuzda da görebileceğiniz gibi MultiPoint ile kullanılabilecek her durum için ayrı ayrı event bağlama metodları MultiPointMouseEvents sınıfı altında bulunuyor. Biz şimdilik Button kontrolümüze sadece MultiPoint için Click event'ını tanımlamış olduk. Kullanacağınız tüm event'ları bu şekilde tanımlamak zorundasınız.

Peki nasıl kullanacağız?

İsterseniz kod tarafında otomatik olarak bu kontrollerden yaratıp uygulamanıza ekleyebilirsiniz. Eğer XAML tarafında yarattığımız bu Button kontrolünü kullanmak isterseniz XAML'da uygulamanızın XML NameSpace'larını yaratmanız gerek. Bir anlamda XAML tarafına kodumuzu "import" etmek olarak tanımlayabiliriz bu işlemi.

[XAML]

<Window x:Class="Window1"

  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:Daron="clr-namespace:MPP"

  Title="MultiPointPaint" Height="480" Width="640" >

Yukarıda gördüğünüz kod yarattığımız uygulamanın ana penceresinin XAML kodunun başlangıcı. Burada ben Daron adında bir XML namespace yaratarak onu da arka planda adı MPP olan uygulamamın ana sınıfına bağladım. Zaten tüm bu kodlar otomatik olarak Intellisense içerisinde geliyor.

[XAML]

    <Daron:MultiPointColorButton Background="#FF000000" Content="Exit" x:Name="btnExit" VerticalAlignment="Center" HorizontalAlignment="Center" Width="50"/>

Bir önceki adımda kodunu yazdığımız ve adını da MultiPointColorButton verdiğimiz düğmemizi XAML tarafında yukarıdaki şekilde kullanabiliyoruz. Eğer XML NameSpace tanımını doğru yaptıysanız XAML kodları içerisinde de NameSpace'in adını yazdıktan sonra içerisindeki bütün kontrollerin listesi Intellisense'de görebilirsiniz.

Düğmemizi de yarattığımıza göre son olarak code-behind tarafına geçip daha önce tanımladığımız CustomClick adındaki özel event'ı kullanarak düğmeye tıklayan imleçleri ve kullanıcıları algılayabiliriz.

[VB]

Private Sub Color_CustomClick(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs)

        Dim MyDeviceInfo As DeviceInfo = CType(e, MultiPointMouseEventArgs).DeviceInfo

        Dim MyMultiPointMouseDevice As MultiPointMouseDevice = CType(MyDeviceInfo.DeviceVisual, MultiPointMouseDevice)

        MessageBox.Show(MyMultiPointMouseDevice.DeviceId)

End Sub

[C#]

private void Color_CustomClick(object sender, System.Windows.RoutedEventArgs e)

{

    DeviceInfo MyDeviceInfo = ((MultiPointMouseEventArgs)e).DeviceInfo;

    MultiPointMouseDevice MyMultiPointMouseDevice = (MultiPointMouseDevice)MyDeviceInfo.DeviceVisual;

    MessageBox.Show(MyMultiPointMouseDevice.DeviceId);

}

Kod içerisinde de görebildiğiniz üzere aslında event-listener'lara gelen RoutedEventArgs'ın kendisi bir MultiPointMouseEventArgs. Biz bu parametre üzerinden DeviceInfo'nın DeviceVisual'ını MultiPointMouseDevice olarak alabiliyoruz. Sonuç olarak bu değişken üzerinden de DeviceID geliyor. Tahmin edebileceğiniz gibi sisteme bağlı her cihazın kendine özel bir DeviceID'si var ve biz de bu ID'ler üzerinden imleçlerin kimliklerini ayırt edebiliyoruz. Artık gerisi sizin hayal gücünüze kalmış ;)

Hepinize kolay gelsin.