Hi
Is there a way to use a program as a MDI child window. I am thinking of having one main MDI parent window which can have multipe child windows, some of which will be programs(.exe files) in there own right.
Tim
Hi
Is there a way to use a program as a MDI child window. I am thinking of having one main MDI parent window which can have multipe child windows, some of which will be programs(.exe files) in there own right.
Tim
I don't belive that this idea could be implemented by .net MDI child support ,so you gona need to implement it yourself :)
go for it.
I have implemented a similar thing a few years ago (.NET Framework 1.1 based, if I recall correctly). Key elements of that implementation were:
Form
class that exposed some specific functionality, such as an interface for extracting user commands that would invoke the UI.Activator.CreateInstance
), stripped from form borders and embedded into a container (in our case a TabPage
in a TabControl
, in your case most likely an "empty" MDI Child form in your application). This all worked out fairly well I think (I actually think that the framework is still being maintained and used within the company it was created for).
You may want to keep an eye at memory management. For instance, since an assembly cannot be unloaded, if that is a requirement you will need to load external assemblies into separate AppDomains. Also pay attention to any event handlers that are attached dynamically when child window UI's are loaded, so that they are properly detached when the UI's are unloaded.
There is actually a pretty easy way to do this.
First, you need to add a panel to your form. This panel will be used to "host" the application.
Next, you need to the "System.Runtime.InteropServices" and the "System.Diagnostics" namespace to your namespaces: csharp
using System.Diagnostics;
using System.Runtime.InteropServices;
Now, we need setup our WinAPI functions:
[DllImport("user32.dll")]
static extern IntPtr SetParent(IntPtr hwndChild, IntPtr hwndNewParent);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, Int32 Msg, Int32 wParam, Int32 lParam);
Now, inside a button click event, start the process, and set it's parent to the panel. In this example, I will be using notepad:
// Create a new process
Process proc;
// Start the process
proc = Process.Start("notepad.exe");
proc.WaitForInputIdle();
// Set the panel control as the application's parent
SetParent(proc.MainWindowHandle, this.panel1.Handle);
// Maximize application
SendMessage(proc.MainWindowHandle, 274, 61488, 0);