can anyone help me with this simple problem.. I want to embed program into the my vb form..
is it possible?
its kinda like in the picture.
can anyone help me with this simple problem.. I want to embed program into the my vb form..
is it possible?
its kinda like in the picture.
Is this a separate application or just another form in your program? If it's the latter then you can do what you want with an MDI setup. If it's the former then I'm not going to say you can't do it, but the concept is like saying "I want to subvert the design of Windows and do something completely different using the system's API", which is likely to be either not possible or wholely impractical.
I'll welcome any corrections, because that would be a nifty feature, but it strikes me as the wrong approach to whatever problem you have.
It can be done. However, the sucess of the implementation depends on how dependent the hosted program is on being parented to the Desktop Window and how good the developer is at developing workarounds for those dependencies. A program like Notepad is trival while hosting MS Word can make you want to cry out for your mamma.
That said, here is an example of my attempt at writing a generic Panel derived control for hosting an application.
Use this code at your own risk, Do not expect me to provide any support or explanation of its workings.
I have relegated further work on this type of endeavor to only be done when I have nothing better to do, like beat myself in the head with a lead pipe.
Start off with a new WinForm application. Add new class and replace its generated code with this.
Imports System.Runtime.InteropServices
Public Class HostApplicationPanel
Inherits Panel
Private Const WM_Close As Int32 = &H10
Private AppProcess As Process
Private AttachedToFormClosing As Boolean = False
Public Sub StartApplication()
If Not AttachedToFormClosing Then
AttachedToFormClosing = True
AddHandler Me.FindForm.FormClosing, AddressOf MyFormClosing
End If
If AppProcess IsNot Nothing AndAlso Not String.IsNullOrEmpty(AppProcess.MainModule.FileName) Then
Select Case MessageBox.Show("Terminate " & AppProcess.MainModule.FileName & " ?", "Panel Has Application", MessageBoxButtons.YesNoCancel)
Case DialogResult.Yes
CloseApplication()
AppProcess.Close()
Case DialogResult.No
Exit Sub
End Select
End If
ApplicationStartInfo.CreateNoWindow = False
ApplicationStartInfo.WindowStyle = ProcessWindowStyle.Maximized
Try
AppProcess = Process.Start(ApplicationStartInfo)
Catch ex As Exception
MsgBox(ex.Message)
Exit Sub
End Try
AppProcess.WaitForInputIdle(5000) 'Give application a max of 5 seconds to return InputIdle
'Debug.WriteLine(Me.Name.Trim & ", MainHwnd = " & AppProcess.MainWindowHandle.ToString)
If AppProcess.HasExited Then
Dim p() As Process = Process.GetProcesses
For i As Int32 = 0 To UBound(p)
Debug.WriteLine(i.ToString & " - " & p(i).ProcessName)
Next
Dim wd() As Process = Process.GetProcessesByName(ApplicationStartInfo.FileName)
'don't attach to a terminated process
Exit Sub
Else
Debug.WriteLine(Me.Name.Trim & ", MainHwnd = " & AppProcess.MainWindowHandle.ToString)
SetWindowForNoResize(AppProcess.MainWindowHandle)
Dim NewStyle As Int32
NewStyle = GetWindowLongPtr(AppProcess.MainWindowHandle, WindowLongFlags.GWL_STYLE).ToInt32
'Remove Caption, MaximizeBox, Minimize Box
'Caption is removed in some apps like Notepad, but not MSWord
'Removal of Minimize & Maximize is to prevent wierd behavior of
'Maximizing the form versus the application as Word does.
'This does not prevent the double clicking in the caption (if it persists) to
'perform the maximization/restore function
NewStyle = NewStyle And (Not WS_CAPTION) And (Not WS_MAXIMIZEBOX) And (Not WS_MINIMIZEBOX)
SetWindowLongPtr(AppProcess.MainWindowHandle, WindowLongFlags.GWL_STYLE, New IntPtr(NewStyle))
'Set App Parent Window to Me
Dim OldParent As IntPtr = SetParent(AppProcess.MainWindowHandle, Me.Handle)
ResizeAppToFitInMe()
End If
End Sub
Private _ApplicationStartInfo As New ProcessStartInfo With {.WindowStyle = ProcessWindowStyle.Minimized}
<MonitoringDescription("ProcessStartInfo"), System.ComponentModel.Browsable(True), _
System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Content)> _
Public Property ApplicationStartInfo() As ProcessStartInfo
Get
Return _ApplicationStartInfo
End Get
Set(ByVal value As ProcessStartInfo)
_ApplicationStartInfo = value
End Set
End Property 'ApplicationStartInfo
Private OriginalWindowStyle As Int32
Private _AllowResizingofPanel As Boolean = False
Public Property AllowResizingofPanel() As Boolean
Get
Return _AllowResizingofPanel
End Get
Set(ByVal value As Boolean)
_AllowResizingofPanel = value
If value Then
SetWindowForResize(Me.Handle, True, OriginalWindowStyle)
Else
SetWindowForResize(Me.Handle, False, OriginalWindowStyle)
End If
End Set
End Property 'AllowSizePanle
Friend Const SWP_NOSIZE As Int32 = &H1
Friend Const SWP_NOZORDER As Int32 = &H4
Friend Const SWP_NOMOVE As Int32 = &H2
Friend Const SWP_DRAWFRAME As Int32 = &H20
Friend Const SWP_FRAMECHANGED As Int32 = &H20
Friend Const SWP_NOOWNERZORDER As Int32 = &H200
Friend Sub SetWindowForResize(ByVal handle As IntPtr, ByVal allowresize As Boolean, ByRef OriginalStyleSetting As Int32)
Dim NewStyle As Int32 = GetWindowLong(handle, GWL_STYLE)
If allowresize Then
NewStyle = NewStyle Or WS_SIZEBOX
Else
NewStyle = OriginalStyleSetting
End If
OriginalStyleSetting = SetWindowLong(handle, GWL_STYLE, NewStyle)
SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, _
SWP_NOZORDER Or SWP_NOSIZE Or SWP_NOMOVE _
Or SWP_FRAMECHANGED Or SWP_NOOWNERZORDER)
End Sub
Friend Sub SetWindowForNoResize(ByVal handle As IntPtr)
Dim NewStyle As Int32 = GetWindowLongPtr(handle, WindowLongFlags.GWL_STYLE).ToInt32 And (Not WS_SIZEBOX)
SetWindowLongPtr(handle, WindowLongFlags.GWL_STYLE, New IntPtr(NewStyle))
SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, _
SWP_NOZORDER Or SWP_NOSIZE Or SWP_NOMOVE _
Or SWP_FRAMECHANGED Or SWP_NOOWNERZORDER)
End Sub
<DllImport("user32.dll", ExactSpelling:=True, CharSet:=CharSet.Auto)> _
Private Shared Sub SetWindowPos(ByVal hWnd As IntPtr, ByVal hWndInsertAfter As IntPtr, ByVal X As Int32, ByVal Y As Int32, ByVal CX As Int32, ByVal CY As Int32, ByVal wFlags As Int32)
End Sub
Private Const WS_MAXIMIZEBOX As Int32 = &H10000
Private Const WS_MINIMIZEBOX As Int32 = &H20000
Private Const GWL_STYLE As Int32 = (-16)
Private Const WS_CAPTION As Int32 = &HC00000
Private Const WS_SIZEBOX As Int32 = &H40000
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowLong(ByVal hWnd As IntPtr, _
<MarshalAs(UnmanagedType.I4)> ByVal nIndex As Int32) _
As Int32
End Function
<DllImport("user32.dll")> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, _
<MarshalAs(UnmanagedType.I4)> ByVal nIndex As Int32, _
ByVal dwNewLong As Int32) As Int32
End Function
Private Sub MyFormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
If AppProcess IsNot Nothing AndAlso Not AppProcess.HasExited Then
CloseApplication()
End If
End Sub
Private Sub CloseApplication()
SendMessage(AppProcess.MainWindowHandle, WM_Close, IntPtr.Zero, IntPtr.Zero)
End Sub
Protected Overrides Sub OnResize(ByVal eventargs As System.EventArgs)
MyBase.OnResize(eventargs)
If AppProcess IsNot Nothing Then ResizeAppToFitInMe()
End Sub
Sub ResizeAppToFitInMe()
MoveWindow(AppProcess.MainWindowHandle, 0, 0, Me.ClientSize.Width, Me.ClientSize.Height, True)
End Sub
<DllImport("user32.dll")> _
Public Shared Function MoveWindow(ByVal hWnd As IntPtr, ByVal x As Int32, ByVal y As Int32, ByVal nWidth As Int32, ByVal nHeight As Int32, ByVal bRepaint As Boolean) As Boolean
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage( _
<MarshalAs(UnmanagedType.SysUInt)> ByVal hWnd As IntPtr, _
<MarshalAs(UnmanagedType.U4)> ByVal Msg As Int32, _
<MarshalAs(UnmanagedType.SysUInt)> ByVal wParam As IntPtr, _
<MarshalAs(UnmanagedType.SysUInt)> ByVal lParam As IntPtr) As IntPtr
End Function
#Region "SetWindowLongPtr"
<System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetWindowLong")> _
Private Shared Function SetWindowLong32(ByVal hWnd As IntPtr, <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags, ByVal dwNewLong As Integer) As Integer
End Function
<System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetWindowLongPtr")> _
Private Shared Function SetWindowLongPtr64(ByVal hWnd As IntPtr, <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags, ByVal dwNewLong As IntPtr) As IntPtr
End Function
Private Shared Function SetWindowLongPtr(ByVal hWnd As IntPtr, ByVal nIndex As WindowLongFlags, ByVal dwNewLong As IntPtr) As IntPtr
If IntPtr.Size = 8 Then
Return SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
Else
Return New IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32))
End If
End Function
#End Region
#Region "GetWindowLongPtr"
<DllImport("user32.dll", EntryPoint:="GetWindowLong")> _
Private Shared Function GetWindowLong32(ByVal hWnd As IntPtr, <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags) As IntPtr
End Function
<DllImport("user32.dll", EntryPoint:="GetWindowLongPtr")> _
Private Shared Function GetWindowLongPtr64(ByVal hWnd As IntPtr, <MarshalAs(UnmanagedType.I4)> ByVal nIndex As WindowLongFlags) As IntPtr
End Function
Private Shared Function GetWindowLongPtr(ByVal hWnd As IntPtr, ByVal nIndex As WindowLongFlags) As IntPtr
If IntPtr.Size = 8 Then
Return GetWindowLongPtr64(hWnd, nIndex)
Else
Return GetWindowLong32(hWnd, nIndex)
End If
End Function
#End Region
Public Enum WindowLongFlags As Integer
GWL_EXSTYLE = -20
GWLP_HINSTANCE = -6
GWLP_HWNDPARENT = -8
GWL_ID = -12
GWL_STYLE = -16
GWL_USERDATA = -21
GWL_WNDPROC = -4
DWLP_USER = &H8
DWLP_MSGRESULT = &H0
DWLP_DLGPROC = &H4
End Enum
End Class
Build the project. Go back to Form1 and open the Toolbox; you should now see a "HostApplicationPanel" control neat the top of the Toolbox. Drag it to the Form like a normal Panel control. Double left-click on the form to bring up the Form's Load handler code and add the statements shown below to it.
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
With HostApplicationPanel1
.ApplicationStartInfo = New ProcessStartInfo("notepad.exe")
.AllowResizingofPanel = True ' Allows you use the resizing grips
.StartApplication()
End With
End Sub
End Class
Run the program and enjoy.
SetParent() is evil (at least the way most people try to use it). It's throwback support for a Windows 3.1 hack, and the behavior is especially wacky in WinForms. Strongly not recommended, which is why I didn't even mention it. ;)
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.