Geeks With Blogs
Greg Young Greg.ToString()

 

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.

 

 

 

Posted on Wednesday, April 26, 2006 11:06 PM Tips and Tricks | Back to top


Comments on this post: Hosting another process in your GUI

# re: Hosting another process in your GUI
Requesting 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.
Left by Shane on Nov 08, 2006 5:22 AM

# re: Hosting another process in your GUI
Requesting 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
Left by Marty Skitch on Jul 11, 2008 2:40 PM

# re: Hosting another process in your GUI
Requesting Gravatar...
I just see your example .i have some question .Is it possible to use in a same winform 4 panel with notepad that open in each one and inside the panel .can we use notepad with all the function open file etc...can we do the same with paint and every application exe .I use sharpdevelop and have no idea how to insert the code as your example .The result of your example is interesting .Thanks
Left by NC on Oct 22, 2008 10:53 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
Like an interface running with different application
Left by NC on Oct 22, 2008 10:57 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
hi bro,
The code you posted on your blog doesn't exactly solve the problem . But the output of that program is very interesting.

thnx a lots 4 sharing...

Nifty Tips || Sure Shot Tips

Left by Nifty Tips on Sep 17, 2010 12:57 AM

# Mr
Requesting Gravatar...
Interesting articles you place here.
It would be useful to read anything more concerning this topic.
Thnx for tell that information.
With best regards Angela!

Sureshot Commodity Tips
Left by commodity tips mcx on Oct 20, 2010 2:35 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
Hi,

here some more tips concerning this topic (re-parenting).:

get Handles:
If you are starting an app you should get the handle in most cases from the process by MainWindowHandle. BUT, some apps dont create their window handles directly at start or are running in 'iconified' state e.g. the office communicator. In this case you have to use the 'FindWindow' function.

Sometimes you will have the problem that your re-parented window wil not accept text input, then you should try to use SetFocus() before the SetParent().

Appearence of the re-parented apps:
If you want to manipulate the window styles, e.g. remove the titlebar, you can use SetWindowLong in kombination with SetWindowPos and its flags ( for example: SWP_FRAMECHANGED | SWP_NOMOVE) (this will activate the style settings!!!).

Sometimes it will be tricky to get it working properly, then you will have to try out a different order of the commands. In my (little) experience the probably best order is:
1) set styles including the child flag
2) set focus to the app you want to reparent
3) call SetParent()
4) call SetWindowPos() ; call refresh() on the form or panel

best regards
Ralf
Left by Ralf Z on Jan 11, 2011 6:17 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
Can I have you code please ?
Left by Gunawan on Feb 09, 2011 8:13 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
You should call AttachThreadInput() in order to prevent losing focus of main window (Form1)
Left by Torvin on May 22, 2011 1:00 PM

# re: Hosting another process in your GUI
Requesting Gravatar...
So would this be how explorer.exe works?
Left by Cole on Nov 06, 2011 9:23 PM

# re: Hosting another process in your GUI
Requesting Gravatar...
Sir,

Thank you, Your code is working well but I have one more query "When I am click on parent form my child form goes back to the parent form. How can I maintain in front of parent form
Left by Jack on May 01, 2015 2:56 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
Excelente aporte, estube intentando aplicarlo, pero no me funcionaba, el problema era que el exe tardaba en levantarse y no se reconocia el manejador de ventana, la solucion fue, esperar a que el exe se levantara , para luego obtener el manejador ...
gracias me sirvio de mucho ..
Left by Jose Menjivar on Jun 25, 2015 10:53 AM

# re: Hosting another process in your GUI
Requesting Gravatar...
It works fine with notepad. But I can't get it to work when trying to open another application designed in .net.
Left by Shayne on Dec 22, 2015 1:36 PM

Your comment:
 (will show your gravatar)


Copyright © Greg Young | Powered by: GeeksWithBlogs.net