Hello,
I need to embed and run an EXE compiled from a VB6 project into a Picturebox of another VB6 project.
I try to use the code which works perfectly with Notepad.exe, but with the "VB6" EXE the program is launched NOT in the Picturebox.
This is the code:
Code:
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Sub Command1_Click()
Dim lHwnd As Long
Call Shell("notepad.exe", vbHide)
lHwnd = FindWindow("notepad", vbNullString)
Call SetParent(lHwnd, Picture1.hwnd)
Call ShowWindow(lHwnd, 3)
End Sub
Private Sub Command2_Click()
Dim lHwnd As Long
Dim sTitle$
Call Shell("notepad.exe", vbHide)
sTitle = "Senza nome - Blocco note"
lHwnd = FindWindow(vbNullString, sTitle)
Call SetParent(lHwnd, Picture1.hwnd)
Call ShowWindow(lHwnd, 3)
End Sub
Private Sub Command3_Click()
Dim lHwnd As Long
Call Shell("provexe.exe", vbHide)
lHwnd = FindWindow("provexe", vbNullString)
Call SetParent(lHwnd, Picture1.hwnd)
Call ShowWindow(lHwnd, 3)
End Sub
Private Sub Command4_Click()
Dim lHwnd As Long
Dim sTitle$
Call Shell("provexe.exe", vbHide)
sTitle = "Form1"
lHwnd = FindWindow(vbNullString, sTitle)
Call SetParent(lHwnd, Picture1.hwnd)
Call ShowWindow(lHwnd, 3)
End Sub
Clicking Command 1 and 2 everything is OK.
Clicking Command 3 and 4 the EXE is launched outside the Form.
The attached files show everything.
How can I solve this problem?
Many thanks in advance for your help
Dario
Last edited by Shaggy Hiker; Oct 5th, 2024 at 02:44 PM.
What possible purpose besides hiding malware does this have?
My shell browser control uses a technique to store arbitrary binary data in a PictureBox but that's image files, so there's button and menu icons without having to keep a bunch of .ico/.png.
Option Explicit
Private Const NO_HANDLE As Long = -1
Private Const SW_SHOWMAXIMIZED As Long = 3
Private Declare Function EnumWindows Lib "User32.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "User32.dll" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function SetParent Lib "User32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function ShowWindow Lib "User32.dll" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private FoundWindowH As Long
Private Function ScanMainWindows(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim ProcessID As Long
If Not GetWindowThreadProcessId(hwnd, ProcessID) = 0 Then
If ProcessID = lParam Then
FoundWindowH = hwnd
ScanMainWindows = CLng(False)
Exit Function
End If
End If
ScanMainWindows = CLng(True)
End Function
Public Sub StartProgramInsideWindow(PathV As String, ContainerWindowH As Long)
Dim ProcessID As Long
ProcessID = Shell(PathV, vbHide)
FoundWindowH = NO_HANDLE
EnumWindows AddressOf ScanMainWindows, ProcessID
If Not FoundWindowH = NO_HANDLE Then
SetParent FoundWindowH, ContainerWindowH
ShowWindow FoundWindowH, SW_SHOWMAXIMIZED
End If
End Sub
(If it it doesn't work from inside vb6, try compiling it and running the exe.)
What possible purpose besides hiding malware does this have?
My shell browser control uses a technique to store arbitrary binary data in a PictureBox but that's image files, so there's button and menu icons without having to keep a bunch of .ico/.png.
Using it for an exe sounds sketchy as hell.
I must explain.
The examples I attached are very simple, just to show the problem.
Indeed the project which should contain the EXE is very complex (FFT of incoming audio signals) and the embedded EXE is quite complex itself (sound generation). Merging the codes would be very, very hard. That's why I prefer to embed one into the other.
I must explain.
The examples I attached are very simple, just to show the problem.
Indeed the project which should contain the EXE is very complex (FFT of incoming audio signals) and the embedded EXE is quite complex itself (sound generation). Merging the codes would be very, very hard. That's why I prefer to embed one into the other.
To me, that sounds like a perfect reason to learn how to compile VB6 ActiveX DLLs. When I have near-independent programs that need to work together, these DLLs are certainly my "go to".
And done that way, it'll be MUCH easier to pass data between the two components (i.e., the main EXE and the DLL).
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Hello,
many thanks for your reply. I guess I must call the Sub StartProgramInsideWindow. Then:
- PathV is the path of the EXE to be embedded? (i.e. for example "e:\program.exe") and and
- ContainerWindowH is the hwnd of the target PictureBox ?
I tried this way your routines and I receive an error "Enum windows Invalid use of Address of operator"
If I try to compile the Exe I get the same error.
Yes, you are correct. What are you doing when you get the invalid use of AddressOf error message? There's no reason to modify the code I provided. Please post the code causing the error. And remember to use code tags (the "#" button in the toolbar above the message you're about to post).
Option Explicit
Private Declare Function EnumWindows Lib "User32.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "User32.dll" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function SetParent Lib "User32.dll" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long
Private Declare Function ShowWindow Lib "User32.dll" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Private Const NO_HANDLE As Long = -1
Private Const SW_SHOWMAXIMIZED As Long = 3
Private FoundWindowH As Long
Dim pathv As String
Private Function ScanMainWindows(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim ProcessID As Long
If Not GetWindowThreadProcessId(hwnd, ProcessID) = 0 Then
If ProcessID = lParam Then
FoundWindowH = hwnd
ScanMainWindows = CLng(False)
Exit Function
End If
End If
ScanMainWindows = CLng(True)
End Function
Private Sub StartProgramInsideWindow(pathv As String, ContainerWindowH As Long)
Dim ProcessID As Long
ProcessID = Shell(pathv, vbHide)
FoundWindowH = NO_HANDLE
EnumWindows AddressOf ScanMainWindows, ProcessID
If Not FoundWindowH = NO_HANDLE Then
SetParent FoundWindowH, ContainerWindowH
ShowWindow FoundWindowH, SW_SHOWMAXIMIZED
End If
End Sub
Private Sub Command1_Click()
StartProgramInsideWindow pathv, Picture1.hwnd
Stop
End Sub
Private Sub Form_Load()
pathv = "e:\onda.exe"
End Sub
the code causing the error is:
Code:
EnumWindows AddressOf ScanMainWindows, ProcessID
Last edited by Shaggy Hiker; Oct 5th, 2024 at 02:43 PM.