Aracılığıyla paylaş


Öğretici: Win32 Uygulamasında Görsel Nesneleri Barındırma

Windows Presentation Foundation (WPF), uygulama oluşturmak için zengin bir ortam sağlar. Ancak, Win32 koduna önemli bir yatırım yaptığınızda, kodunuzu yeniden yazmak yerine uygulamanıza WPF işlevselliği eklemek daha etkili olabilir. Bir uygulamada eşzamanlı olarak kullanılan Win32 ve WPF grafik alt sistemleri için destek sağlamak için WPF, win32 penceresinde nesneleri barındırmak için bir mekanizma sağlar.

Bu öğreticide, WPF görsel nesnelerini bir Win32 penceresinde barındıranWin32 ile Etkileşim Örneği İsabet Testi adlı örnek bir uygulamanın nasıl yazılacağı açıklanır.

Gereksinimler

Bu öğreticide hem WPF hem de Win32 programlaması hakkında temel bir bilgi olduğu varsayılır. WPF programlamaya temel bir giriş için bkz. İzlenecek Yol: İlk WPF masaüstü uygulamam. Win32 programlamaya giriş için, özellikle Charles Petzold'un Programlama Windows kitabına ve konu hakkındaki sayısız diğer kitaplardan birine bakın.

Uyarı

Bu öğretici, ilişkili örnekten bir dizi kod örneği içerir. Ancak okunabilirlik için örnek kodun tamamını içermez. Örnek kodun tamamı için bkz. Win32 Birlikte Çalışma Örneği ile İsabet Testi.

Win32 Ana Makine Penceresi Oluşturulması

Wpf nesnelerini win32 penceresinde barındırmanın anahtarı HwndSource sınıfıdır. Bu sınıf, WPF nesnelerini bir Win32 penceresine kaydırarak bunların kullanıcı arabiriminize (UI) alt pencere olarak dahil edilmesine olanak tanır.

Aşağıdaki örnekte, görsel nesneler için Win32 kapsayıcı penceresi olarak HwndSource nesnesi oluşturmaya yönelik kod gösterilmektedir. Win32 penceresinin pencere stilini, konumunu ve diğer parametrelerini ayarlamak için HwndSourceParameters nesnesini kullanın.

// Constant values from the "winuser.h" header file.
internal const int WS_CHILD = 0x40000000,
                   WS_VISIBLE = 0x10000000;

internal static void CreateHostHwnd(IntPtr parentHwnd)
{
    // Set up the parameters for the host hwnd.
    HwndSourceParameters parameters = new HwndSourceParameters("Visual Hit Test", _width, _height);
    parameters.WindowStyle = WS_VISIBLE | WS_CHILD;
    parameters.SetPosition(0, 24);
    parameters.ParentWindow = parentHwnd;
    parameters.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);

    // Create the host hwnd for the visuals.
    myHwndSource = new HwndSource(parameters);

    // Set the hwnd background color to the form's background color.
    myHwndSource.CompositionTarget.BackgroundColor = System.Windows.Media.Brushes.OldLace.Color;
}
' Constant values from the "winuser.h" header file.
Friend Const WS_CHILD As Integer = &H40000000, WS_VISIBLE As Integer = &H10000000

Friend Shared Sub CreateHostHwnd(ByVal parentHwnd As IntPtr)
    ' Set up the parameters for the host hwnd.
    Dim parameters As New HwndSourceParameters("Visual Hit Test", _width, _height)
    parameters.WindowStyle = WS_VISIBLE Or WS_CHILD
    parameters.SetPosition(0, 24)
    parameters.ParentWindow = parentHwnd
    parameters.HwndSourceHook = New HwndSourceHook(AddressOf ApplicationMessageFilter)

    ' Create the host hwnd for the visuals.
    myHwndSource = New HwndSource(parameters)

    ' Set the hwnd background color to the form's background color.
    myHwndSource.CompositionTarget.BackgroundColor = System.Windows.Media.Brushes.OldLace.Color
End Sub

Uyarı

ExtendedWindowStyle özelliğinin değeri WS_EX_TRANSPARENT olarak ayarlanamaz. Bu, konak Win32 penceresinin saydam olamayacağı anlamına gelir. Bu nedenle, ana bilgisayar Win32 penceresinin arka plan rengi, üst penceresiyle aynı arka plan rengine ayarlanır.

Ana Win32 Penceresine Görsel Nesneler Ekleme

Görsel nesneler için bir konak Win32 kapsayıcı penceresi oluşturduktan sonra, buna görsel nesneler ekleyebilirsiniz. Herhangi bir görsel nesne dönüşümünün, örneğin animasyonların, konak Win32 penceresinin sınırlayıcı dikdörtgeninin sınırlarını aşmadığından emin olmak isteyeceksiniz.

Aşağıdaki örnekte, HwndSource nesnesi oluşturma ve nesneye görsel nesneler ekleme kodu gösterilmektedir.

Uyarı

RootVisual nesnesinin HwndSource özelliği, konak Win32 penceresine eklenen ilk görsel nesneye ayarlanır. Kök görsel nesnesi, görsel nesne ağacının en üst düğümünü tanımlar. Win32 ana penceresine eklenen sonraki görsel nesneler, alt nesneler olarak eklenir.

public static void CreateShape(IntPtr parentHwnd)
{
    // Create an instance of the shape.
    MyShape myShape = new MyShape();

    // Determine whether the host container window has been created.
    if (myHwndSource == null)
    {
        // Create the host container window for the visual objects.
        CreateHostHwnd(parentHwnd);

        // Associate the shape with the host container window.
        myHwndSource.RootVisual = myShape;
    }
    else
    {
        // Assign the shape as a child of the root visual.
        ((ContainerVisual)myHwndSource.RootVisual).Children.Add(myShape);
    }
}
Public Shared Sub CreateShape(ByVal parentHwnd As IntPtr)
    ' Create an instance of the shape.
    Dim myShape As New MyShape()

    ' Determine whether the host container window has been created.
    If myHwndSource Is Nothing Then
        ' Create the host container window for the visual objects.
        CreateHostHwnd(parentHwnd)

        ' Associate the shape with the host container window.
        myHwndSource.RootVisual = myShape
    Else
        ' Assign the shape as a child of the root visual.
        CType(myHwndSource.RootVisual, ContainerVisual).Children.Add(myShape)
    End If
End Sub

Win32 Mesaj Filtresini Uygulamak

Görsel nesneler için konak Win32 penceresi, uygulama kuyruğundan pencereye gönderilen iletileri işlemek için bir pencere iletisi filtre yordamı gerektirir. Pencere yordamı, Win32 sisteminden iletiler alır. Bunlar giriş iletileri veya pencere yönetimi iletileri olabilir. İsteğe bağlı olarak pencere yordamınızdaki bir iletiyi işleyebilir veya iletiyi varsayılan işleme için sisteme geçirebilirsiniz.

Görsel nesnelerin üst öğesi olarak tanımladığınız HwndSource nesnesi, sağladığınız pencere iletisi filtre yordamına başvurmalıdır. HwndSource nesnesini oluşturduğunuzda, pencere yordamına başvurmak için HwndSourceHook özelliğini ayarlayın.

parameters.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);
parameters.HwndSourceHook = New HwndSourceHook(AddressOf ApplicationMessageFilter)

Aşağıdaki örnekte, sol ve sağ fare düğmesini yukarı iletileri işlemeye yönelik kod gösterilmektedir. Fare isabet konumunun koordinat değeri, lParam parametresinin değerinde yer alır.

// Constant values from the "winuser.h" header file.
internal const int WM_LBUTTONUP = 0x0202,
                   WM_RBUTTONUP = 0x0205;

internal static IntPtr ApplicationMessageFilter(
    IntPtr hwnd, int message, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    // Handle messages passed to the visual.
    switch (message)
    {
        // Handle the left and right mouse button up messages.
        case WM_LBUTTONUP:
        case WM_RBUTTONUP:
            System.Windows.Point pt = new System.Windows.Point();
            pt.X = (uint)lParam & (uint)0x0000ffff;  // LOWORD = x
            pt.Y = (uint)lParam >> 16;               // HIWORD = y
            MyShape.OnHitTest(pt, message);
            break;
    }

    return IntPtr.Zero;
}
' Constant values from the "winuser.h" header file.
Friend Const WM_LBUTTONUP As Integer = &H202, WM_RBUTTONUP As Integer = &H205

Friend Shared Function ApplicationMessageFilter(ByVal hwnd As IntPtr, ByVal message As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr, ByRef handled As Boolean) As IntPtr
    ' Handle messages passed to the visual.
    Select Case message
        ' Handle the left and right mouse button up messages.
        Case WM_LBUTTONUP, WM_RBUTTONUP
            Dim pt As New System.Windows.Point()
            pt.X = CUInt(lParam) And CUInt(&HFFFF) ' LOWORD = x
            pt.Y = CUInt(lParam) >> 16 ' HIWORD = y
            MyShape.OnHitTest(pt, message)
    End Select

    Return IntPtr.Zero
End Function

Win32 İletilerini İşleme

Aşağıdaki örnekteki kod, ana bilgisayar Win32 penceresinde bulunan görsel nesnelerin hiyerarşisinde isabet testinin nasıl gerçekleştirildiğini gösterir. Bir noktanın görsel nesnenin geometrisi içinde olup olmadığını belirlemek için HitTest yöntemini kullanarak kök görsel nesnesini ve teste isabet etmek için koordinat değerini belirtebilirsiniz. Bu durumda, kök görsel nesnesi RootVisual nesnesinin HwndSource özelliğinin değeridir.

// Constant values from the "winuser.h" header file.
public const int WM_LBUTTONUP = 0x0202,
                 WM_RBUTTONUP = 0x0205;

// Respond to WM_LBUTTONUP or WM_RBUTTONUP messages by determining which visual object was clicked.
public static void OnHitTest(System.Windows.Point pt, int msg)
{
    // Clear the contents of the list used for hit test results.
    hitResultsList.Clear();

    // Determine whether to change the color of the circle or to delete the shape.
    if (msg == WM_LBUTTONUP)
    {
        MyWindow.changeColor = true;
    }
    if (msg == WM_RBUTTONUP)
    {
        MyWindow.changeColor = false;
    }

    // Set up a callback to receive the hit test results enumeration.
    VisualTreeHelper.HitTest(MyWindow.myHwndSource.RootVisual,
                             null,
                             new HitTestResultCallback(CircleHitTestResult),
                             new PointHitTestParameters(pt));

    // Perform actions on the hit test results list.
    if (hitResultsList.Count > 0)
    {
        ProcessHitTestResultsList();
    }
}
' Constant values from the "winuser.h" header file.
Public Const WM_LBUTTONUP As Integer = &H0202, WM_RBUTTONUP As Integer = &H0205

' Respond to WM_LBUTTONUP or WM_RBUTTONUP messages by determining which visual object was clicked.
Public Shared Sub OnHitTest(ByVal pt As System.Windows.Point, ByVal msg As Integer)
    ' Clear the contents of the list used for hit test results.
    hitResultsList.Clear()

    ' Determine whether to change the color of the circle or to delete the shape.
    If msg = WM_LBUTTONUP Then
        MyWindow.changeColor = True
    End If
    If msg = WM_RBUTTONUP Then
        MyWindow.changeColor = False
    End If

    ' Set up a callback to receive the hit test results enumeration.
    VisualTreeHelper.HitTest(MyWindow.myHwndSource.RootVisual, Nothing, New HitTestResultCallback(AddressOf CircleHitTestResult), New PointHitTestParameters(pt))

    ' Perform actions on the hit test results list.
    If hitResultsList.Count > 0 Then
        ProcessHitTestResultsList()
    End If
End Sub

Görsel nesnelere karşı isabet testi hakkında daha fazla bilgi için bkz. Görsel Katmanİsabet Testi.

Ayrıca bakınız