Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Windows Presentation Foundation (WPF) offre un ambiente avanzato per la creazione di applicazioni. Tuttavia, quando si ha un notevole investimento nel codice Win32, potrebbe essere più efficace aggiungere funzionalità WPF all'applicazione invece di riscrivere il codice. Per fornire supporto per i sottosistemi grafici Win32 e WPF usati simultaneamente in un'applicazione, WPF fornisce un meccanismo per l'hosting di oggetti in una finestra Win32.
Questa esercitazione descrive come scrivere un'applicazione di esempio, Hit Test con l'esempio di interoperabilità Win32, che ospita oggetti visivi WPF in una finestra Win32.
Requisiti
Questa esercitazione presuppone una familiarità di base con la programmazione WPF e Win32. Per un'introduzione di base alla programmazione WPF, vedere Guida: Prima applicazione desktop WPF. Per un'introduzione alla programmazione Win32, vedi uno dei numerosi libri sul tema, in particolare Programmazione di Windows di Charles Petzold.
Annotazioni
Questa esercitazione include diversi esempi di codice dell'esempio associato. Tuttavia, per la leggibilità, non include il codice di esempio completo. Per il codice di esempio completo, vedere Hit Test con l'esempio di interoperabilità Win32.
Creazione della finestra Host Win32
La chiave per ospitare oggetti WPF in una finestra Win32 è la classe HwndSource. Questa classe avvolge gli oggetti WPF in una finestra Win32, consentendo di incorporarli nell'interfaccia utente (UI) come finestra figlia.
Nell'esempio seguente viene illustrato il codice per la creazione dell'oggetto HwndSource come finestra del contenitore Win32 per gli oggetti visivi. Per impostare lo stile della finestra, la posizione e altri parametri per la finestra Win32, usare l'oggetto 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
Annotazioni
Il valore della proprietà ExtendedWindowStyle non può essere impostato su WS_EX_TRANSPARENT. Ciò significa che la finestra Win32 host non può essere trasparente. Per questo motivo, il colore di sfondo della finestra Win32 host viene impostato sullo stesso colore di sfondo della finestra padre.
Aggiunta di oggetti visivi alla finestra Host Win32
Dopo aver creato una finestra contenitore Win32 host per gli oggetti visivi, è possibile aggiungervi oggetti visivi. È necessario assicurarsi che qualsiasi trasformazione degli oggetti visivi, ad esempio le animazioni, non si estenda oltre i limiti del rettangolo di delimitazione della finestra Win32 host.
Nell'esempio seguente viene illustrato il codice per la creazione dell'oggetto HwndSource e l'aggiunta di oggetti visivi.
Annotazioni
La proprietà RootVisual dell'oggetto HwndSource viene impostata sul primo oggetto visivo aggiunto alla finestra Win32 host. L'oggetto visivo radice definisce il nodo più in alto della struttura ad albero degli oggetti visivi. Tutti gli oggetti visivi seguenti aggiunti alla finestra host di Win32 vengono aggiunti come oggetti figli.
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
Implementazione del filtro messaggi Win32
La finestra host Win32 per gli oggetti visivi richiede una procedura di filtro dei messaggi della finestra per gestire i messaggi inviati alla finestra dalla coda dell'applicazione. La procedura della finestra riceve messaggi dal sistema Win32. Possono trattarsi di messaggi di input o messaggi di gestione delle finestre. Facoltativamente, è possibile gestire un messaggio nella routine della finestra o passare il messaggio al sistema per l'elaborazione predefinita.
L'oggetto HwndSource che hai definito come padre per gli oggetti visivi deve fare riferimento alla procedura di filtro dei messaggi della finestra che fornisci. Quando si crea l'oggetto HwndSource, impostare la proprietà HwndSourceHook per fare riferimento alla routine della finestra.
parameters.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);
parameters.HwndSourceHook = New HwndSourceHook(AddressOf ApplicationMessageFilter)
Nell'esempio seguente viene illustrato il codice per la gestione dei messaggi di rilascio del pulsante sinistro e destro del mouse. Il valore della coordinata della posizione di clic del mouse è contenuto nel valore del parametro lParam
.
// 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
Elaborazione dei messaggi Win32
Il codice nell'esempio seguente mostra come viene eseguito un hit test sulla gerarchia degli oggetti visivi contenuti nella finestra Win32 dell'host. È possibile identificare se un punto si trova all'interno della geometria di un oggetto visivo usando il metodo HitTest per specificare l'oggetto visivo radice e il valore della coordinata su cui eseguire il hit test. In questo caso, l'oggetto visivo radice è il valore della proprietà RootVisual dell'oggetto HwndSource.
// 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
Per altre informazioni sull'hit testing sugli oggetti visivi, vedere Hit Testing in Visual Layer.
Vedere anche
.NET Desktop feedback