views:

466

answers:

3

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

+1  A: 

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.

amr osama
A: 

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:

  • We created an extended Form class that exposed some specific functionality, such as an interface for extracting user commands that would invoke the UI.
  • The main application would scan the dll's in the application directory and inspect them (using Reflection) to find any classes based on our special Form class, and extract information out of them to build menu structures that would invoke the commands.
  • When a user invoked a command that would lead to a form being displayed, it was created (using 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.

Fredrik Mörk
Thanks, I suspect that I'd have to do something like this. I'll have a play.
Tim
A: 

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);
Sergio Tapia
This dosn't appear to work. The notepad window is created but it isn't connected to the mdi application.
Tim