MSDN Documentation

Microsoft Developer Network

WPF Interoperability with Win32

This document explores various techniques and considerations for integrating Windows Presentation Foundation (WPF) with existing Win32 applications and components. Achieving seamless interoperability can be crucial for modernizing legacy applications, leveraging existing Win32 libraries within WPF applications, or embedding WPF content into Win32 environments.

Why Interop?

Key Interoperability Scenarios

1. Hosting Win32 Controls in WPF

The primary mechanism for hosting Win32 controls within a WPF application is the WindowsFormsHost element. This control acts as a bridge, allowing you to embed Windows Forms controls (which in turn can host Win32 controls) directly into your WPF layout.

Steps:

  1. Add a reference to the System.Windows.Forms assembly in your WPF project.
  2. Use the WindowsFormsHost element in your XAML.
  3. Create an instance of the desired Windows Forms control (or a Win32 control wrapped by a Windows Forms control) in your code-behind.
  4. Assign this control instance to the Child property of the WindowsFormsHost.
// C# Code-behind
using System.Windows.Forms.Integration;
// ...

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Assuming you have a WinForms control named MyWin32Control
        // This might be a custom wrapper around a native Win32 control
        var winFormsControl = new System.Windows.Forms.Panel(); // Example placeholder

        // You'd typically initialize and configure your Win32/WinForms control here
        // For demonstration, we'll use a simple Panel.
        winFormsControl.BackColor = System.Drawing.Color.LightBlue;
        winFormsControl.Width = 200;
        winFormsControl.Height = 100;

        var host = new WindowsFormsHost();
        host.Child = winFormsControl;

        MyGrid.Children.Add(host); // Assuming 'MyGrid' is a Grid in your XAML
    }
}
<!-- XAML -->
<Grid x:Name="MyGrid">
    <!-- WindowsFormsHost will be populated by code-behind -->
</Grid>
Note: Direct hosting of native Win32 controls without a Windows Forms wrapper is more complex and usually involves P/Invoke or custom interoperability layers. The WindowsFormsHost is the recommended and most straightforward approach for most Win32 control embedding.

2. Hosting WPF Content in Win32 Applications

To display WPF content within a Win32 application, you typically leverage the HwndSource class. This class allows you to create an HwndSource (which represents a window handle) and host a WPF visual tree within it.

Key steps:

  1. Include necessary WPF assemblies in your Win32 project.
  2. Create a window handle (HWND) in your Win32 application.
  3. Instantiate an HwndSource, associating it with the HWND.
  4. Create your WPF content (e.g., a UserControl or Window).
  5. Set the RootVisual property of the HwndSource to your WPF content.
// C++ Win32 with C++/CLI wrapper or P/Invoke for WPF
// This is a conceptual example. Actual implementation might vary based on language.

// Assuming you have a C++/CLI project that hosts WPF
// In your Win32 application, you'd call into this C++/CLI code.

#include <windows.h>
#include <wpf/PresentationFramework.h> // Example header

// Function called from Win32 app to initialize WPF hosting
void HostWpfContent(HWND parentHwnd)
{
    // Create a WPF visual (e.g., a UserControl)
    MyWpfUserControl^ wpfControl = gcnew MyWpfUserControl();

    // Create an HwndSource
    System::Windows::Interop::HwndSourceParameters^ sourceParams =
        gcnew System::Windows::Interop::HwndSourceParameters(L"WPF Host");
    sourceParams->ParentWindow = IntPtr(parentHwnd);
    // ... configure other parameters like size, position ...

    System::Windows::Interop::HwndSource^ hwndSource =
        System::Windows::Interop::HwndSource::CreateFromHandle(sourceParams);

    // Set the WPF content as the root visual
    hwndSource->RootVisual = wpfControl;

    // Store the HwndSource handle for later use (e.g., resizing, disposal)
    // ...
}
Tip: For more complex scenarios, consider using the WPF's ElementHost control within a Windows Forms host that is itself hosted by your Win32 application. This offers a layered approach.

Challenges and Considerations

Advanced Interop Techniques

Tools and Resources

Tool/Resource Description
WindowsFormsHost WPF element to host Windows Forms controls.
System.Windows.Interop.HwndSource Enables hosting WPF content in a Win32 window.
ElementHost Windows Forms control to host WPF content.
P/Invoke Calling Win32 APIs directly from managed code.
Visual Studio Designer Helps in visualizing and designing UI layouts during development.
Warning: Interoperability can be complex. Thorough testing, profiling, and understanding of both WPF and Win32 architectures are crucial for success.

Conclusion

WPF and Win32 interoperability opens up powerful possibilities for application development. By understanding the core mechanisms like WindowsFormsHost and HwndSource, developers can effectively bridge these two powerful UI frameworks. Always prioritize clarity, robustness, and performance in your interop implementations.