This is basically what we have done in our medical software. We still have a fair share of the medical software in a VFP EXE which is automatically launched and then seamlessly brought into the .NET MDI window. This is just the first step in our case because we also needed the .NET menu to launch programs within the VFP EXE. But that is for another post. Here is what you need to do. First launch the application:
Dim loStart As New System.Diagnostics.ProcessStartInfo("c:\yourapplication.exe")
Dim lnHandle As IntPtr
loStart.WindowStyle = Diagnostics.ProcessWindowStyle.Normal
loStart.WorkingDirectory = lcPath
System.Diagnostics.Process.Start(loStart)
Next you are going to want to obtain the window handle to your launched application
'-- Get the PS Window Handle
lnHandle = System.Diagnostics.Process.GetProcessesByName("yourapplication")(0).MainWindowHandle
'-- Stay here until we can get a handle on the application's main window
Do While lnHandle.ToInt32() = 0
lnHandle = System.Diagnostics.Process.GetProcessesByName("yourapplication")(0).MainWindowHandle
Loop
After a handle has been obtained, you will then need to force the main window handle of the application into the .NET MDI environment.
'-- Set the parent window to the MDI client
WinAPI.SetParent(lnHandle, _MDI.Handle)
'-- Set the window styles
WinAPI.SetWindowLong(lnHandle.ToInt32(), -16, WinAPI.WS_CLIPCHILDREN Or WinAPI.WS_CLIPSIBLINGS Or WinAPI.WS_MAXIMIZE Or WinAPI.WS_OVERLAPPED Or WinAPI.WS_SYSMENU Or WinAPI.WS_VISIBLE)
'-- Set the window position
WinAPI.SetWindowPos(lnHandle.ToInt32(), 0, 0, 0, _MDI.Width, _MDI.Height, &H20)
The WINAPI reference above is just a shared class I created within the application that calls the Windows API methods. It would look something like this:
Imports System.ComponentModel
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Public NotInheritable Class WinAPI
Public Shared Const WS_OVERLAPPED As Integer = &H0
Public Shared Const WS_POPUP As Integer = &H80000000
Public Shared Const WS_CHILD As Integer = &H40000000
Public Shared Const WS_MINIMIZE As Integer = &H20000000
Public Shared Const WS_VISIBLE As Integer = &H10000000
Public Shared Const WS_DISABLED As Integer = &H8000000
Public Shared Const WS_CLIPSIBLINGS As Integer = &H4000000
Public Shared Const WS_CLIPCHILDREN As Integer = &H2000000
Public Shared Const WS_MAXIMIZE As Integer = &H1000000
Public Shared Const WS_CAPTION As Integer = &HC00000
Public Shared Const WS_BORDER As Integer = &H800000
Public Shared Const WS_DLGFRAME As Integer = &H400000
Public Shared Const WS_VSCROLL As Integer = &H200000
Public Shared Const WS_HSCROLL As Integer = &H100000
Public Shared Const WS_SYSMENU As Integer = &H80000
Public Shared Const WS_THICKFRAME As Integer = &H40000
Public Shared Const WS_GROUP As Integer = &H20000
Public Shared Const WS_TABSTOP As Integer = &H10000
Public Shared Const WS_EX_LAYERED As Integer = &H80000
<DllImport("user32.dll")> _
Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function SetWindowLong(ByVal WindowHandle As Integer, ByVal Index As Integer, ByVal Settings As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Public Shared Function SetWindowPos(ByVal hWnd As Integer, ByVal hWndInsertAfter As Integer, ByVal X As Integer, ByVal Y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal uFlags As Integer) As Boolean
End Function
End Class
You may not need the SetWindowLong and the SetWindowPos statements. The SetParent is the API call that moves the parent window from being it's own main window handle into the .NET MDI. The reference above to _MDI is an actual MDIClient control that is added to the main form rather than just setting the MDIContainer property. This way you can change the backcolor of the control etc. If you are just going to use the MDIContainer property, the you will just use the Handle property of the main form.