Megosztás a következőn keresztül:


Oktatóanyag: Visual Objects üzemeltetése Win32-alkalmazásban

A Windows Presentation Foundation (WPF) gazdag környezetet biztosít az alkalmazások létrehozásához. Ha azonban jelentős befektetéssel rendelkezik a Win32-kódba, hatékonyabb lehet WPF-funkciókat hozzáadni az alkalmazáshoz a kód átírása helyett. Az alkalmazásokban egyidejűleg használt Win32- és WPF-grafikus alrendszerek támogatásához a WPF egy Win32-ablakban található objektumok üzemeltetésére szolgáló mechanizmust biztosít.

Ez az oktatóanyag bemutatja, hogyan készítsen egy mintaalkalmazást, Hit Test with Win32 Interoperation Sample, amely WPF-vizuális objektumokat helyez el egy Win32-ablakban.

Követelmények

Ez az oktatóanyag a WPF és a Win32 programozás alapszintű ismeretét feltételezi. A WPF-programozás alapszintű bemutatása: Útmutató: Az első asztali WPF-alkalmazásom. A Win32-programozás bemutatása érdekében tekintse meg a témával kapcsolatos számos könyv bármelyikét, különösen charles Petzold Windows- programozását.

Megjegyzés:

Ez az oktatóanyag számos példakódot tartalmaz a társított mintából. Az olvashatóság érdekében azonban nem tartalmazza a teljes mintakódot. Teljes mintakód elérhető itt: Hit Test with Win32 Interoperation Sample.

A gazdagép Win32 ablakának létrehozása

A WPF-objektumok Win32-ablakban való üzemeltetésének kulcsa a HwndSource osztály. Ez az osztály egy Win32-ablakban burkolja a WPF-objektumokat, így azok gyermekablakként beépíthetők a felhasználói felületbe .

Az alábbi példa a vizualizációobjektumok Win32-tárolóablakaként a HwndSource objektum létrehozásának kódját mutatja be. A Win32 ablak ablakstílusának, pozíciójának és egyéb paramétereinek beállításához használja a HwndSourceParameters objektumot.

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

Megjegyzés:

A ExtendedWindowStyle tulajdonság értéke nem állítható be WS_EX_TRANSPARENT értékre. Ez azt jelenti, hogy a gazdagép Win32 ablaka nem lehet áttetsző. Ezért a gazdagép Win32 ablakának háttérszíne a szülőablakával megegyező háttérszínre van állítva.

Vizuális objektumok hozzáadása a gazdagép Win32 ablakához

Miután létrehozott egy Gazdagép Win32 tárolóablakot a vizualizációs objektumokhoz, vizuális objektumokat adhat hozzá. Gondoskodnia kell arról, hogy a vizuális objektumok, például az animációk átalakításai ne terjedjenek túl a Win32 ablak határoló téglalapjának szélein.

Az alábbi példa a HwndSource objektum létrehozására és vizuális objektumok hozzáadására szolgáló kódot mutatja be.

Megjegyzés:

A RootVisual objektum HwndSource tulajdonsága a Win32 gazdaablakhoz hozzáadott első vizuális objektumra van állítva. A legfelső szintű vizualizáció objektum határozza meg a vizualizáció objektumfája legfelső csomópontját. A gazdagép Win32 ablakához hozzáadott további vizuális objektumok gyermekobjektumokként hozzáadódnak.

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

A Win32 üzenetszűrő implementálása

A vizuális objektumok házigazdájának Win32-ablakához ablaküzenet-szűrési eljárás szükséges az alkalmazási üzenetsorból érkező, és az ablakba kerülő üzenetek kezeléséhez. Az ablakos eljárás üzeneteket fogad a Win32 rendszertől. Ezek lehetnek bemeneti üzenetek vagy ablakkezelő üzenetek. Igény szerint kezelheti az üzeneteket az ablakműveletben, vagy átadhatja az üzenetet a rendszernek alapértelmezett feldolgozás céljából.

A vizualizációobjektumok szülőjeként definiált HwndSource objektumnak hivatkoznia kell a megadott ablaküzenet-szűrési eljárásra. A HwndSource objektum létrehozásakor állítsa be a HwndSourceHook tulajdonságot az ablak eljárására való hivatkozásra.

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

Az alábbi példa a bal és a jobb egérgomb felfelé mutató üzeneteinek kezelésére szolgáló kódot mutatja be. Az egér találati pozíciójának koordináta-értékét a lParam paraméter értéke tartalmazza.

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

A Win32-üzenetek feldolgozása

Az alábbi példában szereplő kód bemutatja, hogyan történik a találatellenőrzés a gazda Win32 ablakban található vizuális objektumok hierarchiájában. A HitTest metódus használatával meghatározhatja, hogy egy pont a vizuális objektum geometriáján belül van-e, megadva a gyökér vizuális objektumot és a tesztelni kívánt koordinátaértéket. Ebben az esetben a gyökér vizuális objektum az RootVisual objektum HwndSource tulajdonságának értéke.

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

További információt a vizuális objektumokon végzett találattesztelésről a Vizualizációs Rétegben keresd itt: Találattesztelés a Vizualizációs Rétegben.

Lásd még