Quote Originally Posted by xiaoyao View Post
Code:
Public Function GETVBHeaderID() As Long                                      '取VB头,全新的取VB头方法,速度比OPEN文件快得多
    Dim lPtr          As Long, lRet              As Long, isvb              As String, ll                As Long, mdat(1033)        As Byte
    lPtr = VBGetModuleHandle(ByVal 0&)
    isvb = StrConv("VB5!", vbFromUnicode)
    Do
        If ReadProcessMemory(-1, ByVal lPtr, mdat(0), 1034, ll) = 0 Then Exit Function
        lRet = InStrB(mdat, isvb)
        If lRet <> 0 Then Exit Do
        lPtr = lPtr + 1024
    Loop
    GETVBHeaderID = lPtr + lRet - 1
    
End Function

SUB ThreadTest()
CreateIExprSrvObj 0, 4, 0
CoInitializeEx ByVal 0&, ByVal COINIT_APARTMENTTHREADED
Call VBDllGetClassObject(U1, U2, pVBHeader, pDummy, pIID, pDummy2)
msgbox "abc"
dim f as form2 'with usercontrol
set f=new form2
f.show 1
end sub

'in bas
public pVBHeader as long ,U1 as long 

'in main form
sub test()
pVBHeader=GETVBHeaderID
U1=app.hInstance

createthread *,addressof ThreadTest,*

end sub
i use simple thread method, don't use "HeapAlloc",how to change my code?

HOW TO ADD YOUR CODE TO My project ( for support usercontrol)?
my project only use three lines code for createthread.
not use HeapAlloc,not use tls,not same like you.
Dear xiaoyao,

With some guidance already I got from Trick I can tell you one thing that you use startup code(Here sub main) with code for avoiding re-entrancy in new thread since you are using the same vbheader in vbdllgetclassobject api in new thread.To solve this problem Trick modifies the existing vbheader and creates a new copy of this vbheader and in this new copy he is setting dwThreadFlags field to 1 as he explained.

May be as per Trick's quote

Seems it's the problem with the runtime. It registers the "Global Factory" thru CoRegisterClassObject from the main STA and when you create an usercontrol it calls CoGetClassObject. CoGetClassObject checks the registered Apartment ID i.e. you can't get this "Global Factory" from the different apartment. The same problem you'll see with ActiveX EXE project type. To avoid this you can for example use Load statement with a control array. Additionally you can set the Threading Model to Apartment (1) in VBHeader.dwThreadFlags when you create a VBHeader. In this case each thread (namely STA) will have its own HXMod internal object like in ActiveX DLL. Only in this case you need to performs additional cleaning like VBCanUnloadNow, etc.
Trick can tell if there is any other way like using Load statement with a control array without need for modifying VBHeader.dwThreadFlags to 1 so that using the same vbheader you can support usercontrol in form in a simple way by using submain containing code to avoid re-entrancy in new thread.

regards,
JSVenu