Hi I am trying to host an exe(notepad) in WPF app. Please find the code here:
public partial class MainWindow : Window
{
private Process _process;
private System.Windows.Forms.Panel _panel;
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32")]
private static extern IntPtr SetParent(IntPtr hWnd, IntPtr hWndParent);
[DllImport("user32")]
private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
private const int SWP_NOZORDER = 0x0004;
private const int SWP_NOACTIVATE = 0x0010;
private const int GWL_STYLE = -16;
private const int WS_CAPTION = 0x00C00000;
private const int WS_THICKFRAME = 0x00040000;
const string patran = "patran";
public MainWindow()
{
InitializeComponent();
_process = Process.Start("notepad.exe");
_panel = new System.Windows.Forms.Panel();
wfHost.Child = _panel;
var patranPanelHandle = _panel.Handle;
SetParent(_process.MainWindowHandle, patranPanelHandle);
// remove control box
int style = GetWindowLong(_process.MainWindowHandle, GWL_STYLE);
style = style & ~WS_CAPTION & ~WS_THICKFRAME;
SetWindowLong(_process.MainWindowHandle, GWL_STYLE, style);
// resize embedded application & refresh
ResizeEmbeddedApp();
}
private void ResizeEmbeddedApp()
{
if (_process == null)
return;
SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, (int)_panel.Width, (int)_panel.Height, SWP_NOZORDER | SWP_NOACTIVATE);
}
protected override Size MeasureOverride(Size availableSize)
{
Size size = base.MeasureOverride(availableSize);
ResizeEmbeddedApp();
return size;
}
}
Same code works perfectly fine for Winforms so i used WinformsHost and then added a winforms panel and as described above. But the results are not as expected. The notepad is coming outside of WPF application and the parent child is not working proper
No answer posted for this too
I think, you are invoking
SetParent
too soon. You need to doSetParent
once both Parent and Child windows are ready. So, what you could do is wait until the parent window isLoaded
and then launch Child Process. However, callWaitForInputIdle
on the Child Process before you invokeSetParent
.Below is the sample code I tried and it works:
For more information on WaitForInputIdle, please refer to this MSDN page.
UPDATE
Attaching the result image: