BeginnerVB_Net
asked on
open external application inside picture box
hi ,
iam trying to open an external software like MATLAB inside one of my form and i want to open the software inside a frame or picture box and get it fixed to the picture box or frame.
this is my second question regarding this issue please help me out
ricky
iam trying to open an external software like MATLAB inside one of my form and i want to open the software inside a frame or picture box and get it fixed to the picture box or frame.
this is my second question regarding this issue please help me out
ricky
ASKER
hey thanks for the reply , can u please mail the sample code to do that , its real urgent for me .
thank you
ricky
Heres the code:
Example: (Code Below)
Private m_objProcess As ExtProcess
m_objProcess = New ExtProcess(FileName)
m_objProcess.Start(Process WindowStyl e.Hidden)
m_objProcess.PromptToSaveO nExit = False
m_objProcess.HideApplicati on()
m_objProcess.SetParent(Me. Handle.ToI nt32)
m_objProcess.MoveWindow(0, 0, Me.ClientSize.Width, Me.ClientSize.Height)
m_objProcess.ShowApplicati on()
NOTE: You should also call MoveWindow when you resize the form....
Hope this helps
Curtis
************************** ********** ********** *
Imports System.Runtime.InteropServ ices
Public Class ExtProcess
Inherits System.Diagnostics.Process
<DllImport("user32.dll")> _
Private Shared Function GetClassName(ByVal hwnd As Integer, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function IsWindowVisible(ByVal hwnd As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hwnd As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function ShowWindow(ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowThreadProcessId(B yVal hwnd As Integer, ByRef lpdwProcessId As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindow(ByVal hwnd As Integer, ByVal wFlag As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetParent(ByVal hWndChild As Integer, ByVal hWndNewParent As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowLong(ByVal hwnd As Integer, ByVal nIndex As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetWindowLong(ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function MoveWindow(ByVal hwnd As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function PostMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
Private Const GWL_STYLE = (-16)
Private Const WS_DLGFRAME = &H400000
Private Const WS_CHILD = &H40000000
Private Const WS_CHILDWINDOW = (WS_CHILD)
Private Const WS_VSCROLL = &H200000
Private Const WS_CAPTION = &HC00000
Private Const WS_BORDER = &H800000
Private Const WS_THICKFRAME = &H40000
Private Const WS_SIZEBOX = WS_THICKFRAME
Private Const GW_HWNDNEXT = 2
Private Const SW_HIDE = 0
Private Const SW_RESTORE = 9
Private Const WM_CLOSE = &H10
Private m_lngWindowStyle As System.Diagnostics.Process WindowStyl e
Private m_lngHandle As Integer
Private m_blnPromptSave As Boolean
Public Property PromptToSaveOnExit() As Boolean
Get
Return m_blnPromptSave
End Get
Set(ByVal Value As Boolean)
m_blnPromptSave = Value
End Set
End Property
Public ReadOnly Property AppHandle() As Integer
Get
Return m_lngHandle
End Get
End Property
Public Sub New(ByVal FileName As String)
Me.StartInfo.FileName = FileName
End Sub
Public Sub New(ByVal FileName As String, ByVal Style As System.Diagnostics.Process WindowStyl e)
Me.StartInfo.FileName = FileName
Me.StartInfo.WindowStyle = Style
Call StartApplication(Style)
End Sub
Public Overloads Sub Start(ByVal Style As System.Diagnostics.Process WindowStyl e)
Call StartApplication(Style)
End Sub
Public Overloads Sub Start(ByVal FileName As String, ByVal Style As System.Diagnostics.Process WindowStyl e)
Me.StartInfo.FileName = FileName
Me.StartInfo.WindowStyle = Style
Call StartApplication(Style)
End Sub
Public Sub ShowApplication()
On Error Resume Next
If Not IsWindowVisible(Me.AppHand le) Then
ShowWindow(Me.AppHandle, SW_RESTORE)
End If
SetForegroundWindow(Me.App Handle)
End Sub
Public Sub HideApplication()
On Error Resume Next
If IsWindowVisible(Me.AppHand le) Then
ShowWindow(Me.AppHandle, SW_HIDE)
End If
End Sub
Private Sub StartApplication(ByVal Style As System.Diagnostics.Process WindowStyl e)
On Error Resume Next
Me.StartInfo.WindowStyle = ProcessWindowStyle.Minimiz ed
Me.StartInfo.CreateNoWindo w = True
Me.StartInfo.UseShellExecu te = True
Me.Start()
Me.WaitForInputIdle()
m_lngHandle = GetAppHandle(Me)
If Style = ProcessWindowStyle.Hidden Then
Me.HideApplication()
Else
Me.HideApplication()
Me.ShowApplication()
End If
End Sub
Private Function GetAppHandle(ByRef Process As Process) As Integer
Dim lngHandle As Integer
lngHandle = -1
Do Until lngHandle <> -1
lngHandle = FindWindow(Process)
If lngHandle <> -1 Then
Exit Do
End If
Application.DoEvents()
Loop
GetAppHandle = lngHandle
End Function
Private Function FindWindow(ByRef Process As Process, Optional ByVal Loading As Boolean = True) As Integer
Dim hWndNext As Integer
Dim hWnd As Integer
Dim lngAssocProcessID As Integer
Dim lngReply As Integer
Dim strClassName As String
FindWindow = -1
If Loading Then If Not WaitForProcess(Process) Then Exit Function
hWndNext = FindWindow(vbNullString, vbNullString)
Do
lngReply = GetWindowThreadProcessId(h WndNext, lngAssocProcessID)
If lngAssocProcessID = Process.Id Then
strClassName = GetClassName(hWndNext)
hWnd = FindWindow(strClassName, Process.MainWindowTitle)
If hWnd <> 0 Then
FindWindow = hWnd
Exit Function
End If
End If
hWndNext = GetWindow(hWndNext, GW_HWNDNEXT)
Loop Until hWndNext = 0
End Function
Private Function GetClassName(ByVal hWnd As Integer) As String
Dim strBuffer As New System.Text.StringBuilder( 256)
GetClassName(hWnd, strBuffer, 256)
GetClassName = strBuffer.ToString
End Function
Private Function WaitForProcess(ByRef Process As Process) As Boolean
Dim lngTimeout As Long
lngTimeout = CLng(Now.Ticks / System.TimeSpan.TicksPerSe cond) + 30
Do Until Process.MainWindowTitle <> ""
Application.DoEvents()
If CLng(Now.Ticks / System.TimeSpan.TicksPerSe cond) > lngTimeout Then Exit Function
Loop
WaitForProcess = True
End Function
Public Sub SetParent(ByVal NewParentHandle As Integer)
Dim lngStyle As Integer
On Error Resume Next
SetParent(Me.AppHandle, NewParentHandle)
lngStyle = GetWindowLong(Me.AppHandle , GWL_STYLE)
lngStyle = lngStyle Xor WS_CAPTION
lngStyle = lngStyle Xor WS_SIZEBOX
SetWindowLong(Me.AppHandle , GWL_STYLE, lngStyle)
End Sub
Public Sub MoveWindow(ByVal Left As Integer, ByVal Top As Integer, ByVal Width As Integer, ByVal Height As Integer)
On Error Resume Next
Call MoveWindow(Me.AppHandle, Left, Top, Width, Height, 1)
End Sub
Public Sub StopProcess()
On Error Resume Next
PostMessage(m_lngHandle, WM_CLOSE, IIf(m_blnPromptSave, 1, 0), 0)
m_lngHandle = FindWindow(Me, False)
If m_lngHandle <> -1 Then
Me.Kill()
End If
m_lngHandle = 0
End Sub
Protected Overrides Sub Finalize()
Call StopProcess()
MyBase.Finalize()
End Sub
End Class
Example: (Code Below)
Private m_objProcess As ExtProcess
m_objProcess = New ExtProcess(FileName)
m_objProcess.Start(Process
m_objProcess.PromptToSaveO
m_objProcess.HideApplicati
m_objProcess.SetParent(Me.
m_objProcess.MoveWindow(0,
m_objProcess.ShowApplicati
NOTE: You should also call MoveWindow when you resize the form....
Hope this helps
Curtis
**************************
Imports System.Runtime.InteropServ
Public Class ExtProcess
Inherits System.Diagnostics.Process
<DllImport("user32.dll")> _
Private Shared Function GetClassName(ByVal hwnd As Integer, ByVal lpClassName As System.Text.StringBuilder,
End Function
<DllImport("user32.dll")> _
Private Shared Function IsWindowVisible(ByVal hwnd As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetForegroundWindow(ByVal hwnd As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function ShowWindow(ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowThreadProcessId(B
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindow(ByVal hwnd As Integer, ByVal wFlag As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetParent(ByVal hWndChild As Integer, ByVal hWndNewParent As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowLong(ByVal hwnd As Integer, ByVal nIndex As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetWindowLong(ByVal hwnd As Integer, ByVal nIndex As Integer, ByVal dwNewLong As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function MoveWindow(ByVal hwnd As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal bRepaint As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function PostMessage(ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
End Function
Private Const GWL_STYLE = (-16)
Private Const WS_DLGFRAME = &H400000
Private Const WS_CHILD = &H40000000
Private Const WS_CHILDWINDOW = (WS_CHILD)
Private Const WS_VSCROLL = &H200000
Private Const WS_CAPTION = &HC00000
Private Const WS_BORDER = &H800000
Private Const WS_THICKFRAME = &H40000
Private Const WS_SIZEBOX = WS_THICKFRAME
Private Const GW_HWNDNEXT = 2
Private Const SW_HIDE = 0
Private Const SW_RESTORE = 9
Private Const WM_CLOSE = &H10
Private m_lngWindowStyle As System.Diagnostics.Process
Private m_lngHandle As Integer
Private m_blnPromptSave As Boolean
Public Property PromptToSaveOnExit() As Boolean
Get
Return m_blnPromptSave
End Get
Set(ByVal Value As Boolean)
m_blnPromptSave = Value
End Set
End Property
Public ReadOnly Property AppHandle() As Integer
Get
Return m_lngHandle
End Get
End Property
Public Sub New(ByVal FileName As String)
Me.StartInfo.FileName = FileName
End Sub
Public Sub New(ByVal FileName As String, ByVal Style As System.Diagnostics.Process
Me.StartInfo.FileName = FileName
Me.StartInfo.WindowStyle = Style
Call StartApplication(Style)
End Sub
Public Overloads Sub Start(ByVal Style As System.Diagnostics.Process
Call StartApplication(Style)
End Sub
Public Overloads Sub Start(ByVal FileName As String, ByVal Style As System.Diagnostics.Process
Me.StartInfo.FileName = FileName
Me.StartInfo.WindowStyle = Style
Call StartApplication(Style)
End Sub
Public Sub ShowApplication()
On Error Resume Next
If Not IsWindowVisible(Me.AppHand
ShowWindow(Me.AppHandle, SW_RESTORE)
End If
SetForegroundWindow(Me.App
End Sub
Public Sub HideApplication()
On Error Resume Next
If IsWindowVisible(Me.AppHand
ShowWindow(Me.AppHandle, SW_HIDE)
End If
End Sub
Private Sub StartApplication(ByVal Style As System.Diagnostics.Process
On Error Resume Next
Me.StartInfo.WindowStyle = ProcessWindowStyle.Minimiz
Me.StartInfo.CreateNoWindo
Me.StartInfo.UseShellExecu
Me.Start()
Me.WaitForInputIdle()
m_lngHandle = GetAppHandle(Me)
If Style = ProcessWindowStyle.Hidden Then
Me.HideApplication()
Else
Me.HideApplication()
Me.ShowApplication()
End If
End Sub
Private Function GetAppHandle(ByRef Process As Process) As Integer
Dim lngHandle As Integer
lngHandle = -1
Do Until lngHandle <> -1
lngHandle = FindWindow(Process)
If lngHandle <> -1 Then
Exit Do
End If
Application.DoEvents()
Loop
GetAppHandle = lngHandle
End Function
Private Function FindWindow(ByRef Process As Process, Optional ByVal Loading As Boolean = True) As Integer
Dim hWndNext As Integer
Dim hWnd As Integer
Dim lngAssocProcessID As Integer
Dim lngReply As Integer
Dim strClassName As String
FindWindow = -1
If Loading Then If Not WaitForProcess(Process) Then Exit Function
hWndNext = FindWindow(vbNullString, vbNullString)
Do
lngReply = GetWindowThreadProcessId(h
If lngAssocProcessID = Process.Id Then
strClassName = GetClassName(hWndNext)
hWnd = FindWindow(strClassName, Process.MainWindowTitle)
If hWnd <> 0 Then
FindWindow = hWnd
Exit Function
End If
End If
hWndNext = GetWindow(hWndNext, GW_HWNDNEXT)
Loop Until hWndNext = 0
End Function
Private Function GetClassName(ByVal hWnd As Integer) As String
Dim strBuffer As New System.Text.StringBuilder(
GetClassName(hWnd, strBuffer, 256)
GetClassName = strBuffer.ToString
End Function
Private Function WaitForProcess(ByRef Process As Process) As Boolean
Dim lngTimeout As Long
lngTimeout = CLng(Now.Ticks / System.TimeSpan.TicksPerSe
Do Until Process.MainWindowTitle <> ""
Application.DoEvents()
If CLng(Now.Ticks / System.TimeSpan.TicksPerSe
Loop
WaitForProcess = True
End Function
Public Sub SetParent(ByVal NewParentHandle As Integer)
Dim lngStyle As Integer
On Error Resume Next
SetParent(Me.AppHandle, NewParentHandle)
lngStyle = GetWindowLong(Me.AppHandle
lngStyle = lngStyle Xor WS_CAPTION
lngStyle = lngStyle Xor WS_SIZEBOX
SetWindowLong(Me.AppHandle
End Sub
Public Sub MoveWindow(ByVal Left As Integer, ByVal Top As Integer, ByVal Width As Integer, ByVal Height As Integer)
On Error Resume Next
Call MoveWindow(Me.AppHandle, Left, Top, Width, Height, 1)
End Sub
Public Sub StopProcess()
On Error Resume Next
PostMessage(m_lngHandle, WM_CLOSE, IIf(m_blnPromptSave, 1, 0), 0)
m_lngHandle = FindWindow(Me, False)
If m_lngHandle <> -1 Then
Me.Kill()
End If
m_lngHandle = 0
End Sub
Protected Overrides Sub Finalize()
Call StopProcess()
MyBase.Finalize()
End Sub
End Class
ASKER
thanks for the code ill try it out and let u know
ricky
ASKER
hello curtis ,
The code works perfectly i just need to know how to do little change in it , i am trying to open an external software (PSPICE)
inside the picture box, so i created a picture box and changed the code replacing "me" "with picturebox1" in the intial code.
The problem i face now is that the application does not fit exactly to the size of the picture box and it opens in some other location inside the picture box so i need to open the application window to the size of the picture box.
one more thing i want to do is to show the title bar to the user with a new caption , hiding all the min,max and close button.
ricky
Ricky,
Ill make the changes and send you the new code.
Curtis
Ill make the changes and send you the new code.
Curtis
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
hi curtis thanks for the new code it works perfectly , the window resizes exactly to the size of the picture box,
but i have the same problem now which i had in the beginnning when i first put the query in this forum .
The application which opens in the picture box is not embedded or fixed to the form , the application is such that it can be movable by the user by dragging the application using the title bar inside the picture box itself.
The application just moves inside the picture box .
One more thing is when the form is run , iam able to see the application opening in the taskbar and then it gets hidden
can it be opened in the invisible mode itself.
thank u
ricky
Ricky,
I am trying to see if i can open invisible without seeing it in the taskbar...i will let you know asap....for the other problem, im not getting what you would like it to do...do you want the program to move inside the form like a mdi form of just be fixed..
Let me know,
Curtis
I am trying to see if i can open invisible without seeing it in the taskbar...i will let you know asap....for the other problem, im not getting what you would like it to do...do you want the program to move inside the form like a mdi form of just be fixed..
Let me know,
Curtis
ASKER
hi curtis,
yes i want the program which opens in the picture box to be fixed and should not move inside the mdi form
ricky
ASKER
hello curtis ,
did u find the code , let me know
ricky
You need to use the API SetParent to change the program parent handle to your form or picture handle....
The trick is getting the right handle for the program....I found that if you start the application using the Process class and get the title and process ID you can get the proper handle for the program.....once thats done you can set the parent....also if you dont want the caption bar at the top you can change the window style to remove it...Ill try to find my code for it...
Hope this helps
Curtis