Proper way of hosting an external window inside WPF using HwndHost Proper way of hosting an external window inside WPF using HwndHost wpf wpf

Proper way of hosting an external window inside WPF using HwndHost


Right before calling 'SetParent' do this:

public const int GWL_STYLE = (-16);public const int WS_CHILD = 0x40000000;SetWindowLong(this.ChildHandle, GWL_STYLE, WS_CHILD);


Looking at the docs:

  1. You need a Win32 control compiled for CLI
  2. You must create the control inside your WPF app.

It seems not possibile to "attach" an already running Window from another process inside a WPF app.

How do you get the handle you pass to your HwndHostEx constructor?


To add clarification, here's the final code for hosting a process in a WPF app, taken from Jose's answer:

    class HwndHostEx : HwndHost    {        [DllImport("user32.dll")]        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);        [DllImport("user32.dll")]        static extern int SetWindowLong(IntPtr hWnd, int nIndex, UInt32 dwNewLong);        private IntPtr ChildHandle = IntPtr.Zero;        public HwndHostEx(IntPtr handle)        {            this.ChildHandle = handle;        }        protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent)        {            HandleRef href = new HandleRef();            if (ChildHandle != IntPtr.Zero)            {                const int GWL_STYLE = (-16);                const int WS_CHILD = 0x40000000;                SetWindowLong(this.ChildHandle, GWL_STYLE, WS_CHILD);                SetParent(this.ChildHandle, hwndParent.Handle);                href = new HandleRef(this, this.ChildHandle);            }            return href;        }        protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd)        {        }    }// to create an instance:var processName = "Whatever.exe";var process = System.Diagnostics.Process.GetProcesses() .FirstOrDefault(item => item.ProcessName.ToLowerInvariant() == processName && item.MainWindowHandle != IntPtr.Zero);var handle = process?.MainWindowHandle;if(handle != null){    var host = new HwndHostEx(handle.Value);    YourControl.Grid.Children.Add(host);}