Reputation: 1015
I want to open an application in my window. my code is working fine in windows form but in wpf it doesn't work. here is the code with description
private Process pDocked;
private IntPtr hWndOriginalParent;
private IntPtr hWndDocked;
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
private void panel1_Resize(object sender, EventArgs e)
{
//Change the docked windows size to match its parent's size.
MoveWindow(hWndDocked, 0, 0, panel1.Width, panel1.Height, true);
}
private void dockIt(string utility)
{
if (hWndDocked != IntPtr.Zero) //don't do anything if there's already a window docked.
return;
//hWndParent = IntPtr.Zero;
pDocked = Process.Start(utility);
while (hWndDocked == IntPtr.Zero)
{
pDocked.WaitForInputIdle(1000); //wait for the window to be ready for input;
pDocked.Refresh(); //update process info
if (pDocked.HasExited)
{
return; //abort if the process finished before we got a handle.
}
hWndDocked = pDocked.MainWindowHandle; //cache the window handle
}
//Windows API call to change the parent of the target window.
//It returns the hWnd of the window's parent prior to this call.
hWndOriginalParent = SetParent(hWndDocked, panel1.Handle);
//Wire up the event to keep the window sized to match the control
panel1.SizeChanged += new EventHandler(panel1_Resize);
//Perform an initial call to set the size.
panel1_Resize(new Object(), new EventArgs());
}
And on the button click i am passing the notepad in dockit but it doesn't work, how do i make it work in wpf, any panel(dockpanel, stackpanel) but they doesn't support resizing the window
Upvotes: 3
Views: 4254
Reputation: 1995
You can host the notepad in your WPF window like this: add a WindowsFormsHost to your window, set System.Windows.Forms.Panel as it's child and use panel's handle.
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
private Process pDocked;
private IntPtr hWndOriginalParent;
private IntPtr hWndDocked;
public System.Windows.Forms.Panel pannel;
public MainWindow()
{
InitializeComponent();
pannel = new System.Windows.Forms.Panel();
host.Child = pannel;
dockIt("notepad.exe");
}
private void dockIt(string utility)
{
if (hWndDocked != IntPtr.Zero) //don't do anything if there's already a window docked.
return;
pDocked = Process.Start(utility);
while (hWndDocked == IntPtr.Zero)
{
pDocked.WaitForInputIdle(1000); //wait for the window to be ready for input;
pDocked.Refresh(); //update process info
if (pDocked.HasExited)
{
return; //abort if the process finished before we got a handle.
}
hWndDocked = pDocked.MainWindowHandle; //cache the window handle
}
//Windows API call to change the parent of the target window.
//It returns the hWnd of the window's parent prior to this call.
hWndOriginalParent = SetParent(hWndDocked, pannel.Handle);
//Wire up the event to keep the window sized to match the control
SizeChanged += window_SizeChanged;
//Perform an initial call to set the size.
AlignToPannel();
}
private void AlignToPannel()
{
MoveWindow(hWndDocked, 0, 0, pannel.Width, pannel.Height, true);
}
void window_SizeChanged(object sender, SizeChangedEventArgs e)
{
AlignToPannel();
}
}
window xaml:
<TabControl>
<TabItem Header="Notepad">
<WindowsFormsHost x:Name="host" />
</TabItem>
</TabControl>
But once you will put your WindowsFormsHost in a tab there will be plenty of WinForms/WPF integration issues. The best source of knowledge on this topic I've found in this article "Mitigating Airspace Issues In WPF Applications". Good luck.
Upvotes: 4