Show / Hide Table of Contents

Учебник. Размещение визуальных объектов в приложении Win32

Windows Presentation Foundation (WPF) предоставляет среду с широкими возможностями для создания приложений. Тем не менее, если имеются существенные преимущества в Win32 код, он может быть более эффективно добавить WPF функциональные возможности приложения, а не переписывать код. Чтобы обеспечить поддержку Win32 и WPF графических подсистем, одновременно используемых в приложении, WPF предоставляет механизм для размещения объектов в Win32 окна.

Этом руководстве описывается создание примера приложения, проверка нажатия с помощью примера взаимодействия Win32, в котором узлы WPF визуальные объекты в Win32 окна.

Требования

В этом учебнике предполагается, что вы знакомы с основами программирования в WPF и Win32. Основные сведения о WPF программирования, см. в разделе Пошаговое руководство: Создание первого классического приложения WPF. Общие сведения о Win32 программирования, см. в разделе любой из многочисленных книг по этой теме, в частности программирования Windows Чарльза Петцольда.

Note

Этот учебник включает ряд примеров кода из связанного образца приложения. Однако для удобства чтения он не содержит полный пример кода. Полный образец кода, см. в разделе проверка нажатия с помощью примера взаимодействия Win32.

Создание окна размещения Win32

Ключом к размещению WPF объекты в Win32 окно HwndSource класса. Этот класс заключает WPF объекты в Win32 окна, позволяя им должна быть включена в ваш UI как дочернего окна.

В примере показан код для создания HwndSource объекта в виде Win32 окна контейнера для визуальных объектов. Чтобы задать стиль окна, положение и другие параметры для Win32 окно, используйте 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;
}
Note

Значение ExtendedWindowStyle свойство нельзя установить значение WS_EX_TRANSPARENT. Это означает, что узел Win32 окно не может быть прозрачным. По этой причине цвет фона узла Win32 окно присваивается один и тот же цвет фона родительского окна.

Добавление визуальных объектов в окно размещения Win32

После создания узла Win32 окна контейнера для визуальных объектов, к нему можно добавить визуальные объекты. Необходимо убедиться, что любые преобразования визуальных объектов, такие как анимация, не выходят за пределы узла Win32 ограничивающего прямоугольника окна.

В примере показан код для создания HwndSource объекта и добавления в него визуальных объектов.

Note

RootVisual Свойство HwndSource присваивается первый визуальный объект, добавленный к узлу Win32 окна. Корневой визуальный объект определяет верхний узел дерева визуальных объектов. Все последующие визуальные объекты, добавленные в главное Win32 окна добавляются как дочерние объекты.

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);
    }
}

Реализация фильтра сообщений Win32

Узел Win32 окно для визуальных объектов требуется процедура фильтра сообщений окна для обработки сообщений, отправленных в окно из очереди приложения. Процедура окна получает сообщения от Win32 системы. Это могут быть входные сообщения или сообщения управления окнами. Сообщение можно обработать в процедуре окна или передать системе для обработки по умолчанию.

HwndSource Объект, который вы определили в качестве родительского для визуальных объектов необходимо обращаться вами процедуру фильтра сообщений окна. При создании HwndSource установите HwndSourceHook свойство для ссылки на процедуру окна.

parameters.HwndSourceHook = new HwndSourceHook(ApplicationMessageFilter);

В следующем примере показан код для обработки сообщений при отпускании левой и правой кнопок мыши. Значение координаты мыши была нажата содержится в значении параметра 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;
}

Обработка сообщений Win32

Код в следующем примере показано, как выполняется нажатия иерархии визуальных объектов, содержащихся в окне размещения Win32 окна. Можно определить, находится ли точка в пределах визуального объекта, с помощью HitTest метод, чтобы задать корневой визуальный объект и значение координаты для проверки нажатия. В этом случае корневой визуальный объект является значение RootVisual свойство 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();
    }
}

Дополнительные сведения о проверке нажатия для визуальных объектов, см. в разделе проверка нажатия на визуальном уровне.

См. также

  • HwndSource
  • Попадания с помощью примера взаимодействия Win32
  • Проверка попадания на визуальном уровне
Back to top Неофициальная документация по .NET на русском языке. Лицензия: CC-BY 4.0. Основано на документации по .NET с Microsoft Docs
Generated by DocFX