Blog Stats
  • Posts - 99
  • Articles - 5
  • Comments - 43
  • Trackbacks - 108

 

Hosting another process in your GUI

 

Someone asked about this today on MS newsgroups so I figured I would blog the answer as others may find this to be useful functionality .. I know I have!

I need to display two VB6 applications side by side within a single
'windows manager'

My thought is that I could use a split screen form, using the 2.0
framework and visual studio 2005, that display the UI of each of the
VB6 apps within some control or container on the windows form.

The obvious solution is to rebuild the VB6 apps as com objects and
place the com objects on the form. Is there a solution that doesn't
require me to rebuild the VB6 apps?

The code that solves this problem ...

    public class Native {
        [DllImport("user32.dll", SetLastError = true)]
        private static extern uint SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
        public static void LoadProcessInControl(string _Process, Control _Control)
        {
            System.Diagnostics.Process p = System.Diagnostics.Process.Start(_Process);
            p.WaitForInputIdle();
            Native.SetParent(p.MainWindowHandle, _Control.Handle);
        }
    }

Now lets create a quick app to show the functionality (2.0)

Put a splitter on the form (default names or change in code).

    public partial class Form1 : Form {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            LoadProcessInControl("notepad.exe", this.splitContainer1.Panel1);
            LoadProcessInControl("notepad.exe", this.splitContainer1.Panel2);
        }
    }

When run this it will produce the following output ...

 

You can also maximize the processes and they will fill the container area... add the following code to the native class

        [DllImport("user32.dll")]
        private static extern
        bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

        private const int SW_HIDE = 0;
        private const int SW_SHOWNORMAL = 1;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_SHOWNOACTIVATE = 4;
        private const int SW_RESTORE = 9;
        private const int SW_SHOWDEFAULT = 10;
        private static bool ShowWindow(Process _Process, int nCmdShow)
        {
            return ShowWindowAsync(_Process.MainWindowHandle, nCmdShow);
        }

now add the following line to the end of LoadProcessInControl

ShowWindow(p, SW_SHOWMAXIMIZED);

Now when we run our app we see the following.

 

You can also do this with MDI apps ...

Remove the splitter control and make the form a MDI container ...

Now change form load to ..

        private void Form1_Load(object sender, EventArgs e)
        {
            Native.LoadProcessInControl("notepad.exe", this);
            Native.LoadProcessInControl("notepad.exe", this);
        }

The output when run will look like this ...

Note that the notepad windows have become MDI children of the application.

 

 

 


Feedback

# re: Hosting another process in your GUI

Gravatar This works great with Notepad and Iexplore etc but doesn't work with vb6 applications. the MainWindowHandle doesn't seem to return the correct handle and therefore doesn't pull in the form. 11/8/2006 5:22 AM | Shane

# re: Hosting another process in your GUI

Gravatar I tried this with a tabControl1 and when the main form is re-sized the Notepad does not re-size. How can Notepad be re-sized when the main form is re-sized 7/11/2008 2:40 PM | Marty Skitch

Post a comment





 

Please add 5 and 4 and type the answer here:

 

 

Copyright © Greg Young