HwndHost for Windows Form - Win32 / WinForm Interoperability HwndHost for Windows Form - Win32 / WinForm Interoperability wpf wpf

HwndHost for Windows Form - Win32 / WinForm Interoperability


What you had to do in WPF to create a valid D2D1 target window is not necessary in Winforms. It was necessary in WPF because controls are not windows themselves and don't have a Handle property, the one that CreateHwndRenderTarget() needs.

In Winforms the Panel class is already a perfectly good render target, you can use its Handle property to tell D2D1 where to render. You just need to tell it to stop painting itself. Add a new class to your project and paste this code:

using System;using System.Windows.Forms;class D2D1RenderTarget : Control {    protected override void OnHandleCreated(EventArgs e) {        base.OnHandleCreated(e);        if (!this.DesignMode) {            this.SetStyle(ControlStyles.UserPaint, false);            // Initialize D2D1 here, use this.Handle            //...        }    }}

Compile. Drop the new control onto your form, replacing the existing panel.


Sounds like an MDI application. Something like this?

[DllImport("user32.dll")]private static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);[DllImport("user32.dll")]internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);Form f = new Form();Button b1 = new Button { Text = "Notepad" };b1.Click += delegate {    using (var p = Process.Start("notepad.exe")) {        p.WaitForInputIdle();        SetParent(p.MainWindowHandle, f.Handle);        MoveWindow(p.MainWindowHandle, 50, 50, 300, 300, true);    }};f.Controls.Add(b1);Application.Run(f);