Introduction
This code shows how to host a third party application UI in your application's Window. In the sample application given below, NOTEPAD.EXE will be hosted in my process. The NOTEPAD application is also made to resize itself whenever our application is resized. Likewise any GUI application can be hosted in a separate process. For delayed GUI application, the hosting process has to wait till the MainWindow
of the hosted process is created, hence as an alternative, I have used Thread.Sleep
to wait for a second or two. The sample application can be downloaded from here.
Advantages
- The lifetime of the Hosted process can be managed within the hosting process.
- If the hosted process crashes, it can be handled appropriately.
- This kind of hosting and managing process can be very useful for watchdog kind of applications, wherein if the hosted process goes down or crashes, then it can be brought up again. Again all these are done within one Window.
- With some Window coordinate calculations, the hosted application can be tiled/cascaded, etc.
Examples
The famous Google Chrome, Internet Explorer 8, where-in each tab of the Internet Explorer/Chrome Window is a process. I have hosted GUIs in splitter window, whereas Internet Explorer 8/Chrome have them hosted in Tabs.
Using the Code
Two Win32 APIs are used to host a 3rd part application's Window in our process:
SetParent and SetWindowPos
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
int X, int Y, int cx, int cy, uint uFlags);
SetParent
API is used to set the parent of the 3rd party application's main Window handle. In this case, my application's window handle is the parent of the 3rd party application's (Notepad.exe) main window.
SetParent(p.MainWindowHandle, this.splitContainer2.Panel1.Handle);
SetWindowPos
API is used to resize the 3rd party application's Window whenever our application is resized.
SetWindowPos(p.MainWindowHandle, HWND_TOP,
this.splitContainer2.Panel1.ClientRectangle.Left,
this.splitContainer2.Panel1.ClientRectangle.Top,
this.splitContainer2.Panel1.ClientRectangle.Width,
this.splitContainer2.Panel1.ClientRectangle.Height, SWP_NOACTIVATE | SWP_SHOWWINDOW);
Points of Interest
Any GUI application can be hosted in a separate process. The advantage of this is, if the GUI application crashes, the application that is hosting it still remains, it can take appropriate action. I was not able to host some of the applications like Internet Explorer (Iexplore.exe), Microsoft Word (winword.exe) into my own application's Window. To host these processes, I had to wait for a second (call Thread.Sleep(1000))
after WaitForInputIdle
function is called. I really don't know the reason behind it. Please let me know if you know the reason.
History
- 16th August, 2010: Initial post