Didacticiel : hébergement d'objets visuels dans une application Win32
Mise à jour : novembre 2007
Windows Presentation Foundation (WPF) fournit un environnement riche pour créer des applications. Toutefois, lorsque vous avez écrit une bonne partie du Win32, il peut être plus efficace d'ajouter la fonctionnalité WPF à votre application plutôt que de réécrire le code. Pour fournir le support pour des sous-systèmes Win32 et WPF utilisés concurremment dans une application, WPF fournit un mécanisme pour héberger des objets dans une fenêtre Win32.
Ce didacticiel explique comment écrire un exemple d'application Test d'atteinte avec interopérabilité Win32, exemple qui héberge des objets visuels WPF dans une fenêtre Win32.
Cette rubrique comprend les sections suivantes.
- Configuration requise
- Création de la fenêtre Win32 hôte
- Ajout d'objets visuels à la fenêtre Win32 hôte
- Implémentation du filtre de messages Win32
- Traitement des messages Win32
- Rubriques connexes
Configuration requise
Ce didacticiel suppose que avez des connaissances de base en matière de programmation WPF et Win32. Pour une présentation générale de la programmation WPF, consultez Mise en route de Windows Presentation Foundation. Pour une présentation de la programmation Win32, consultez les divers manuels qui s'y rapportent, notamment à La programmation Windows de Charles Petzold.
Remarque : |
---|
Ce didacticiel inclut des exemples de code de l'exemple associé. Toutefois, il n'inclut pas l'exemple de code complet pour une meilleure lisibilité. Pour obtenir l'exemple de code complet, consultez Test d'atteinte avec interopérabilité Win32, exemple. |
Création de la fenêtre Win32 hôte
La clé d'hébergement d'objets WPF dans une fenêtre Win32 est la classe HwndSource. Cette classe encapsule les objets WPF dans une fenêtre Win32 en leur permettant d'être incorporés dans votre interface utilisateur (UI) sous la forme d'une fenêtre enfant.
L'exemple suivant montre le code permettant de créer l'objet HwndSource sous la forme d'une fenêtre de conteneur Win32 pour les objets visuels. Pour définir le style, la position et d'autres paramètres de la Win32, utilisez l'objet 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;
}
Remarque : |
---|
La valeur de la propriété ExtendedWindowStyle ne peut pas être WS_EX_TRANSPARENT. Cela signifie que la fenêtre Win32 hôte ne peut pas être transparente. Pour cette raison, la couleur d'arrière-plan de la fenêtre Win32 hôte a pour valeur la même couleur d'arrière-plan que sa fenêtre parente. |
Ajout d'objets visuels à la fenêtre Win32 hôte
Une fois que vous avez créé une fenêtre de conteneur Win32 hôte pour les objets visuels, vous pouvez y ajouter des objets visuels. L'objectif est de veiller à ce que les transformations des objets visuels, telles que les animations, ne s'étendent pas au delà des limites du rectangle englobant de la fenêtre Win32 hôte.
L'exemple suivant montre le code permettant de créer l'objet HwndSource et d'y ajouter des objets visuels.
Remarque : |
---|
La propriété RootVisual de l'objet HwndSource a pour valeur le premier objet visuel ajouté à la fenêtre Win32 hôte. L'objet visuel racine définit le premier nœud de l'arborescence d'objets visuels. Tous les objets visuels suivants ajoutés à la fenêtre Win32 hôte sont ajoutés comme objets enfants. |
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);
}
}
Implémentation du filtre de messages Win32
La fenêtre Win32 hôte des objets visuels nécessite une procédure de filtrage des messages de fenêtre pour gérer les messages envoyés à la fenêtre par la file d'attente d'application. La procédure de fenêtre reçoit des messages du système Win32. Il peut s'agir de messages d'entrée ou de messages de gestion de fenêtre. Vous pouvez gérer éventuellement un message dans votre procédure de fenêtre ou passer le message au système pour un traitement par défaut.
L'objet HwndSource que vous avez défini comme parent pour les objets visuels doit faire référence à la procédure de filtre de messages de fenêtre que vous fournissez. Lorsque vous créez l'objet HwndSource, définissez la propriété HwndSourceHook pour faire référence à la procédure de fenêtre.
parameters.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);
L'exemple suivant montre le code permettant de gérer les messages de relâchement du bouton gauche et du bouton droit de la souris. La valeur de coordonnée de la position de la souris se trouve dans la valeur du paramètre 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;
}
Traitement des messages Win32
Le code dans l'exemple suivant montre comment un test d'atteinte est effectué par rapport à la hiérarchie d'objets visuels contenue dans la fenêtre Win32 hôte. Vous pouvez déterminer si un point se trouve dans la géométrie d'un objet visuel en utilisant la méthode HitTest pour spécifier l'objet visuel racine et la valeur de coordonnée à utiliser pour le test d'atteinte. Dans ce cas, l'objet visuel racine est la valeur de la propriété RootVisual de l'objet 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();
}
}
Pour plus d'informations sur le test d'atteinte par rapport aux objets visuels, consultez Test d'atteinte dans la couche visuelle.
Voir aussi
Tâches
Test d'atteinte avec interopérabilité Win32, exemple
Concepts
Test d'atteinte dans la couche visuelle