I'd like to host a window of an external process inside my WPF application. I'm deriving HwndHost
like this:
class HwndHostEx : HwndHost
{
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
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)
{
SetParent(this.ChildHandle, hwndParent.Handle);
href = new HandleRef(this, this.ChildHandle);
}
return href;
}
protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd)
{
}
}
and using it like this:
HwndHostEx host = new HwndHostEx(handle);
this.PART_Host.Child = host;
where handle
is a handle for an external window I'd like to host and PART_Host
is a border inside my WPF window:
<StackPanel UseLayoutRounding="True"
SnapsToDevicePixels="True"
Background="Transparent">
<Border Name="PART_Host" />
...
This gives me an exception:
Hosted HWND must be a child window.
Sorry for my lack of knowledge but what is the proper way of hosting an external window inside WPF application?
You will need to create an instance of a new window like so. var window2 = new Window2(); Once you have the instance you can use the Show() or ShowDialog() method depending on what you want to do. var result = window2.
Window is the root control that must be used to hold/host other controls (e.g. Button) as container. Page is a control which can be hosted in other container controls like NavigationWindow or Frame. Page control has its own goal to serve like other controls (e.g. Button). Page is to create browser like applications.
To open a new window and have it centred on the screen, set the WindowStartupLocation property to CenterScreen. You can do this using the XAML or in code before the window is displayed. Run the program and click the button to see the result.
WPF uses C# as backend language and XAML as the front-end language. Microsoft designed the WPF with loosely coupled presentation as well as business logic, which facilitates the use of design patterns like MVC or MVVM in the development.
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:
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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With