Öğretici: Win32 Uygulamasında Görsel Nesneler 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ız zaman, kodunuzu yeniden yazmak yerine uygulamanıza WPF işlevselliği eklemek daha etkili olabilir. WpF, bir uygulamada eşzamanlı olarak kullanılan Win32 ve WPF grafik alt sistemleri için destek sağlamak için win32 penceresinde nesneleri barındırmaya bir mekanizma sağlar.

Bu öğreticide, WPF görsel nesnelerini Win32 penceresinde barındıran Win32 BirlikteÇalışma Örneği ile Isabet Testi örnek uygulamasının nasıl yaz olduğu açıklanır.

Gereksinimler

Bu öğreticide hem WPF hem de Win32 programlama hakkında temel bilgi sahibi olduğu varsaymaktadır. WPF programlamaya temel bir giriş için bkz. Adım adım: İlk WPF masaüstü uygulamam. Win32 programlamaya giriş için, özellikle Charles Petzold'un programlama ve programlama Windows konu kitabına bakın.

Not

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

Konak Win32 Penceresini Oluşturma

WPF nesnelerini Win32 penceresinde barındırmanın anahtarı HwndSource sınıfıdır. Bu sınıf, WPF nesnelerini bir Win32 penceresinde sarmalar ve kullanıcı arabiriminize (UI) alt pencere olarak dahil edildiklerine olanak sağlar.

Aşağıdaki örnekte, görsel nesneler için HwndSource Win32 kapsayıcı penceresi olarak nesne oluşturma kodu gösterilir. Win32 penceresinin pencere stilini, konumunu ve diğer parametrelerini ayarlamak için nesnesini HwndSourceParameters 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

Not

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

Konak Win32 Penceresine Görsel Nesneler Ekleme

Görsel nesneler için bir konak Win32 kapsayıcı penceresi oluşturduktan sonra, buna görsel nesneler ebilirsiniz. Görsel nesnelerdeki animasyonlar gibi dönüştürmelerin, ana bilgisayar Win32 penceresinin sınırlayıcı dikdörtgeni sınırlarının ötesine genişletilamaması gerekir.

Aşağıdaki örnek, nesnesini oluşturmak ve buna HwndSource görsel nesneler eklemek için kodu gösterir.

Not

nesnenin RootVisualHwndSource özelliği, konak Win32 penceresine eklenen ilk görsel nesnesine ayarlanır. Kök görsel nesnesi, görsel nesne ağacının en üst düğümünü tanımlar. Konak Win32 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 İleti Filtresini Uygulama

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

Görsel HwndSource nesneler için üst öğe olarak tanımlandığı nesne, size sağlandığı pencere iletisi filtre yordamına başvurlanmalıdır. Nesnesini HwndSource oluştururken özelliğini pencere HwndSourceHook yordamına başvurarak ayarlayın.

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

Aşağıdaki örnekte, sol ve sağ fare düğmesi yukarı iletilerini işleme kodu gösterir. Fare isabet konumunun koordinat değeri, parametresinin değerinde lParam yer alan değerdir.

// 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 nesneler hiyerarşisinde bir isabet testinin nasıl gerçekleştirileceklerini gösterir. Bir noktanın görsel nesnesinin geometrisi içinde olup olmadığını belirlemek için kök görsel nesnesini ve teste isabet edecek koordinat HitTest değerini belirtmek için yöntemini kullanabilirsiniz. Bu durumda, kök görsel nesnesi nesnenin RootVisual özelliğinin HwndSource 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ında Isabet Testi.

Ayrıca bkz.