@F3B14N si seria lo correcto, pero la verdad no le tengo mucha fe a vb con el uso de threads seria un gran dolor de cabeza.
Option Explicit
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Declare Function VirtualProtect Lib "KERNEL32" (lpAddress As Any, ByVal dwSize As Long, ByVal flNewProtect As Long, lpflOldProtect As Long) As Long
Private Declare Function CreateThread Lib "KERNEL32" (ByVal lpSecurityAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadId As Long) As Long
Private Declare Function ReadProcessMemory Lib "KERNEL32" (ByVal hProcess As Long, ByRef lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Function VBDllGetClassObject Lib "MSVBVM60" (g1 As Long, g2 As Long, ByVal g3_vbHeader As Long, REFCLSID As Long, REFIID As GUID, ppv As Long) As Long
Private Declare Function CreateIExprSrvObj Lib "MSVBVM60" (ByVal p1_0 As Long, ByVal p2_4 As Long, ByVal p3_0 As Long) As Long
Private Declare Function CoInitialize Lib "OLE32" (ByVal pvReserved As Long) As Long
Private Declare Sub CoUninitialize Lib "OLE32" ()
Private VBHeaderAddress As Long
Private MainAddress As Long
Public Sub CreateNewThread(ByVal lAddress As Long, ByVal lVal As Long, Optional ByRef lHandle As Long, Optional ByRef lThread As Long)
If VBHeaderAddress = 0 Then
Call GetFakeHeader: Call GetMainAddress
Call VirtualProtect(ByVal MainAddress, 1, &H40, 0&)
End If
lHandle = CreateThread(ByVal 0&, ByVal 0&, lAddress, ByVal lVal, 0, lThread)
End Sub
Public Sub InitCurrentThread()
Call CreateIExprSrvObj(0, 4, 0)
Call CoInitialize(0)
Call InitDLL
End Sub
Public Sub TerminateCurrentThread()
Call CoUninitialize
End Sub
Public Sub GetFakeHeader()
Dim lPtr As Long
Dim lProc As Long
Dim bData(1024) As Byte
Dim sData As String
Dim lRet As Long
lPtr = App.hInstance
Do While lRet = 0
Call ReadProcessMemory(-1, ByVal lPtr, bData(0), 1024, 0&)
sData = StrConv(bData, vbUnicode)
lRet = InStr(1, sData, "VB5!", vbBinaryCompare)
lPtr = lPtr + 1024
Loop
VBHeaderAddress = lPtr + lRet - 1024 - 1
End Sub
Private Sub GetMainAddress()
Call ReadProcessMemory(-1, ByVal VBHeaderAddress + &H2C, MainAddress, 4, 0&)
'If MainAddress = 0 Then
' 'MainAddress = AddressOf Private Sub Form_Initialize()
'End If
End Sub
Private Sub InitDLL()
Dim pIID As GUID
With pIID
.Data1 = 1
.Data4(0) = &HC0
.Data4(7) = &H46
End With
Call ReadProcessMemory(-1, &HC3, ByVal MainAddress, 4, 0&)
Call VBDllGetClassObject(0, 0, VBHeaderAddress, 0, pIID, 0)
Call ReadProcessMemory(-1, &H8B, ByVal MainAddress, 4, 0&)
End Sub
Private Sub Main()
CLIENT_Main.Show
End Sub
Funciona sin problemas, simplemente pon Sub Main como objeto inicial y desde ahi inicia el/los forms normalmente. Recorda llamar InitCurrentThread en cada nuevo thread también.