I'm trying to open both WordPad and Notepad from within my C# WPF application and then 'attach' them to my application (inside a WPF TabControl). Each application will exist in a different TabItem.
I have run into an issue where I can achieve this for 1 program only. So, if I try it with Notepad, it works as desired. If I try it with WordPad, it works as desired. If I try it with both, it only "docks" 1 of the applications into my project - the other application is still executed (it loads) but doesn't 'live' inside my WPF app.
I am at a total lost as to what I've done wrong. The only way I can share the code is to share all of it - I've tried to cut it down as much as possible.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using Size = System.Windows.Size;
namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private System.Windows.Forms.Panel _panel;
        private Process _process;
        public MainWindow()
        {
            InitializeComponent();
            _panel = new System.Windows.Forms.Panel();
            var list = new Dictionary<string, string>();//process and params
            list.Add("notepad.exe", null);
            list.Add(@"wordpad.exe", null);
            foreach (var path in list)
            {
                BeginThisThing(path.Key.ToString(), Convert.ToString(path.Value)); //I know the naming is poor, for now I'm only testing!!
                var host1 = new System.Windows.Forms.Integration.WindowsFormsHost();
                host1.Child = this._panel;
                try
                {
                    TabItem ti = new TabItem();
                    this.Tabby.Items.Add(ti);
                    ti.Header = path.Key.ToString();
                    ti.Content = host1;
                }
                catch (Exception ex)
                {
                    string s = ex.ToString();
                }
            }
        }
        [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;
        private void BeginThisThing(string path, string param)
        {
            ProcessStartInfo psi = null;
            psi = (String.IsNullOrEmpty(param)) ? new ProcessStartInfo(path) : new ProcessStartInfo(path, param);
            _process = Process.Start(psi);
            _process.WaitForInputIdle();
            Thread.Sleep(500);
            SetParent(_process.MainWindowHandle, _panel.Handle);
            // 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();
        }
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
            if (_process != null)
            {
                _process.Refresh();
                _process.Close();
            }
        }
        private void ResizeEmbeddedApp()
        {
            if (_process == null)
                return;
            SetWindowPos(_process.MainWindowHandle, IntPtr.Zero, 0, 0, (int)_panel.ClientSize.Width, (int)_panel.ClientSize.Height, SWP_NOZORDER | SWP_NOACTIVATE);
        }
        protected override Size MeasureOverride(Size availableSize)
        {
            Size size = base.MeasureOverride(availableSize);
            ResizeEmbeddedApp();
            return size;
        }
    }
}
XAML is simply
<Grid>
     <TabControl x:Name="Tabby"></TabControl>        
</Grid>
The panel you declared in the class as a field has to be unique for each host, but in you code it is shared between them, what causes the behaviour you see.
User contributions licensed under CC BY-SA 3.0