Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Windows Presentation Foundation (WPF) bietet eine umfangreiche Umgebung zum Erstellen von Anwendungen. Wenn Sie jedoch eine erhebliche Investition in Win32-Code haben, ist es möglicherweise effektiver, Ihrer Anwendung WPF-Funktionen hinzuzufügen, anstatt den Code neu zu schreiben. Um Unterstützung für Win32- und WPF-Grafiksubsysteme bereitzustellen, die gleichzeitig in einer Anwendung verwendet werden, stellt WPF einen Mechanismus zum Hosten von Objekten in einem Win32-Fenster bereit.
In diesem Lernprogramm wird beschrieben, wie Sie eine Beispielanwendung, Hit Test mit Win32-Interoperationsbeispiel, schreiben, die visuelle WPF-Objekte in einem Win32-Fenster hostet.
Anforderungen
In diesem Lernprogramm wird eine grundlegende Vertrautheit mit der Programmierung von WPF und Win32 vorausgesetzt. Eine grundlegende Einführung in die WPF-Programmierung finden Sie unter Exemplarische Vorgehensweise: Meine erste WPF-Desktopanwendung. Eine Einführung in die Win32-Programmierung finden Sie in einem der zahlreichen Bücher über das Thema, insbesondere die Programmierung von Windows von Charles Petzold.
Hinweis
Dieses Lernprogramm enthält eine Reihe von Codebeispielen aus dem zugehörigen Beispiel. Aus Gründen der Lesbarkeit enthält sie jedoch nicht den vollständigen Beispielcode. Den vollständigen Beispielcode finden Sie unter Hit Test with Win32 Interoperation Sample.
Erstellen des Win32-Hostfensters
Der Schlüssel zum Hosten von WPF-Objekten in einem Win32-Fenster ist die HwndSource Klasse. Diese Klasse umschließt die WPF-Objekte in einem Win32-Fenster, sodass sie als untergeordnetes Fenster in die Benutzeroberfläche (UI) integriert werden können.
Das folgende Beispiel zeigt den Code zum Erstellen des HwndSource Objekts als Win32-Containerfenster für die visuellen Objekte. Verwenden Sie HwndSourceParameters das Objekt, um das Fensterformat, die Position und andere Parameter für das Win32-Fenster festzulegen.
// 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
Hinweis
Der Wert der ExtendedWindowStyle Eigenschaft kann nicht auf WS_EX_TRANSPARENT festgelegt werden. Dies bedeutet, dass das Win32-Hostfenster nicht transparent sein kann. Aus diesem Grund wird die Hintergrundfarbe des Win32-Hostfensters auf dieselbe Hintergrundfarbe wie das übergeordnete Fenster festgelegt.
Hinzufügen visueller Objekte zum Win32-Hostfenster
Nachdem Sie ein Win32-Hostcontainerfenster für die visuellen Objekte erstellt haben, können Sie ihr visuelle Objekte hinzufügen. Sie möchten sicherstellen, dass alle Transformationen der visuellen Objekte, z. B. Animationen, nicht über die Grenzen des Umgebenden Rechtecks des Win32-Hostfensters hinausgehen.
Das folgende Beispiel zeigt den Code zum Erstellen des HwndSource Objekts und Hinzufügen visueller Objekte zu diesem Objekt.
Hinweis
Die RootVisual Eigenschaft des HwndSource Objekts wird auf das erste visuelle Objekt festgelegt, das dem Win32-Hostfenster hinzugefügt wurde. Das visuelle Stammobjekt definiert den obersten Knoten der visuellen Objektstruktur. Alle nachfolgenden visuellen Objekte, die dem Win32-Hostfenster hinzugefügt werden, werden als untergeordnete Objekte hinzugefügt.
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
Implementieren des Win32-Nachrichtenfilters
Das Win32-Hostfenster für die visuellen Objekte erfordert eine Fensternachrichtenfilterprozedur zum Verarbeiten von Nachrichten, die aus der Anwendungswarteschlange an das Fenster gesendet werden. Die Fensterprozedur empfängt Nachrichten vom Win32-System. Dabei kann es sich um Eingabenachrichten oder Fensterverwaltungsmeldungen handelt. Sie können optional eine Nachricht in Ihrer Fensterprozedur behandeln oder die Nachricht zur Standardverarbeitung an das System übergeben.
Das HwndSource Objekt, das Sie als übergeordnetes Objekt für die visuellen Objekte definiert haben, muss auf die von Ihnen bereitgestellte Fensternachrichtenfilterprozedur verweisen. Wenn Sie das HwndSource Objekt erstellen, legen Sie die HwndSourceHook Eigenschaft so fest, dass auf die Fensterprozedur verwiesen wird.
parameters.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);
parameters.HwndSourceHook = New HwndSourceHook(AddressOf ApplicationMessageFilter)
Das folgende Beispiel zeigt den Code zum Behandeln der linken und rechten Maustasten-Loslassen-Meldungen. Der Koordinatenwert der Maustreffposition ist im Wert des lParam
Parameters enthalten.
// 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
Verarbeiten der Win32-Nachrichten
Der Code im folgenden Beispiel zeigt, wie ein Treffertest mit der Hierarchie visueller Objekte im Win32-Hostfenster ausgeführt wird. Mithilfe der HitTest Methode können Sie ermitteln, ob sich ein Punkt innerhalb der Geometrie eines visuellen Objekts befindet, indem Sie das visuelle Stammobjekt und den Koordinatenwert angeben, mit dem der Treffertest ausgeführt werden soll. In diesem Fall ist das visuelle Stammobjekt der Wert der RootVisual Eigenschaft des HwndSource Objekts.
// 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
Weitere Informationen zu Treffertests für visuelle Objekte finden Sie unter Treffertests in der visuellen Ebene.
Siehe auch
.NET Desktop feedback