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:
- You need a Win32 control compiled for CLI
- 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);}