Aracılığıyla paylaş


Eğitmen: 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ı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, Win32 penceresinde WPF görsel nesnelerini barındıran Win32 Birlikte Çalışma Örneği ile İsabet Testi adlı örnek bir uygulamanın nasıl yazıldığı açıklanmaktadı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, konuyla ilgili sayısız kitaplardan herhangi birine, özellikle de Charles Petzold'un Programlama Pencereleri'ne bakın.

Dekont

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.

Konak Win32 Penceresi Oluşturma

WPF nesnelerini win32 penceresinde barındırmanın HwndSource anahtarı 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 nesne oluşturmaya HwndSource yönelik kod gösterilmektedir. Win32 penceresinin pencere stilini, konumunu ve diğer parametrelerini ayarlamak için nesnesini kullanın HwndSourceParameters .

// 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

Dekont

özelliğinin ExtendedWindowStyle 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.

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 ekleyebilirsiniz. Görsel nesnelerin animasyonlar gibi dönüştürmelerinin konak Win32 penceresinin sınırlayıcı dikdörtgeninin sınırlarının ötesine genişletilmediğinden emin olmak isteyeceksiniz.

Aşağıdaki örnekte, nesneyi oluşturma ve nesneye HwndSource görsel nesneler eklemeye yönelik kod gösterilmektedir.

Dekont

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. 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 Filtresi Uygulama

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.

HwndSource Görsel nesneler için üst öğe olarak tanımladığınız nesne, sağladığınız pencere iletisi filtre yordamına başvurmalıdır. Nesnesini oluşturduğunuzda HwndSource , pencere yordamına HwndSourceHook başvurmak için ö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 parametresinin lParam 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. Kök görsel nesnesini ve teste isabet etmek için koordinat değerini belirtmek için yöntemini kullanarak HitTest bir noktanın görsel nesnenin geometrisi içinde olup olmadığını belirleyebilirsiniz. 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 İsabet Testi.

Ayrıca bkz.