I wrote a "XIncludeFile" generator in PureBasic, that generates an IncludeFile with all the CLSID, IID and VTable and Dispatch Interfaces for a selected control.  After starting the program, it shows all the registered controls. By clicking a control, it fills a listview with the enums, constants, interfaces, dispinterfaces and so on for that control. By clicking a (disp)interface it fills the bottom listview with the details. That will be a custom Vtable interface, a Dispatch Interface or a Enumeration (for building your clientsite eventsink) depending on the radio buttons. You will find the Code below.
 
Code: Select all
;-Init Includes
XIncludeFile "Controls_Constants.pb"
XIncludeFile "Controls_Windows.pb"
Enumeration
  #INVOKE_FUNC             = 1
  #INVOKE_PROPERTYGET      = 2
  #INVOKE_PROPERTYPUT      = 4
  #INVOKE_PROPERTYPUTREF   = 8
EndEnumeration 
Enumeration 
  #USERCLASSTYPE_FULL       = 1 
  #USERCLASSTYPE_SHORT  
  #USERCLASSTYPE_APPNAME 
EndEnumeration 
Enumeration
  #TKIND_ENUM  
  #TKIND_RECORD 
  #TKIND_MODULE 
  #TKIND_INTERFACE 
  #TKIND_DISPATCH
  #TKIND_COCLASS
  #TKIND_ALIAS
  #TKIND_UNION
  #TKIND_MAX  
EndEnumeration 
Enumeration
  #FUNC_VIRTUAL    = 0
  #FUNC_PUREVIRTUAL= #FUNC_VIRTUAL + 1
  #FUNC_NONVIRTUAL = #FUNC_PUREVIRTUAL + 1
  #FUNC_STATIC     = #FUNC_NONVIRTUAL + 1
  #FUNC_DISPATCH   = #FUNC_STATIC + 1
EndEnumeration 
Enumeration
  #VAR_PERINSTANCE = 0
  #VAR_STATIC      = #VAR_PERINSTANCE + 1
  #VAR_CONST       = #VAR_STATIC + 1
  #VAR_DISPATCH    = #VAR_CONST + 1
EndEnumeration  
Enumeration
  #VT_EMPTY
  #VT_NULL
  #VT_I2
  #VT_I4
  #VT_R4
  #VT_R8
  #VT_CY
  #VT_DATE
  #VT_BSTR
  #VT_DISPATCH
  #VT_ERROR
  #VT_BOOL
  #VT_VARIANT
  #VT_UNKNOWN
  #VT_DECIMAL
  #VT_I1           = 16
  #VT_UI1
  #VT_UI2
  #VT_UI4
  #VT_I8
  #VT_UI8
  #VT_INT
  #VT_UINT
  #VT_VOID
  #VT_HRESULT
  #VT_PTR
  #VT_SAFEARRAY
  #VT_CARRAY
  #VT_USERDEFINED
  #VT_LPSTR 
  #VT_LPWSTR 
  #VT_RECORD       = 36
  #VT_FILETIME     = 64
  #VT_BLOB         = 65
  #VT_STREAM       = 66
  #VT_STORAGE      = 67 
  #VT_STREAMED_OBJECT      = 68
  #VT_STORED_OBJECT        = 69
  #VT_BLOB_OBJECT  = 70
  #VT_CF           = 71
  #VT_CLSID        = 72
  #VT_BSTR_BLOB    = $fff
  #VT_VECTOR       = $1000
  #VT_ARRAY        = $2000
  #VT_BYREF        = $4000
  #VT_RESERVED     = $8000
  #VT_ILLEGAL      = $ffff
  #VT_ILLEGALMASKED= $fff
  #VT_TYPEMASK     = $fff
EndEnumeration                
Enumeration
  #PARAMFLAG_NONE = $00
  #PARAMFLAG_FIN = $01
  #PARAMFLAG_FOUT = $02
  #PARAMFLAG_FLCID = $04
  #PARAMFLAG_FRETVAL = $08
  #PARAMFLAG_FOPT = $10
  #PARAMFLAG_FHASDEFAULT = $20
  #PARAMFLAG_FHASCUSTDATA = $40
EndEnumeration                
Structure VARIANTARG
  vt.w
  dummy1.w
  dummy2.w
  dummy3.w
  union.l
EndStructure
Structure PARAMDESC
  pparamdescex.l
  wParamFlags.w
EndStructure  
Structure PARAMDESCEX
  cBytes.l
  dummy.l   ; Deze dummy begrijp ik niet
  varDefaultValue.VARIANTARG
EndStructure
Structure TYPEDESC
  union.l
  vt.w
EndStructure
Structure ELEMDESC 
  tdesc.TYPEDESC
  dummy.w
  paramdesc.PARAMDESC
  dummy.w
EndStructure
Structure FUNCDESC
  memid.l
  scode.l
  *lprgelemdescParam.ELEMDESC
  funckind.l
  invokekind.l
  callconv.l
  cParams.w 
  cParamsOpt.w 
  oVft.w 
  cScodes.w 
  *elemdescFunc.ELEMDESC
  wFuncFlags.w
EndStructure
Structure TYPEATTR
  guid.GUID
  lcid.l
  dwReserved.l
  memidConstructor.l
  memidDestructor.l
  lpstrSchema.l
  cbSizeInstance.l
  typekind.l
  cFuncs.w
  cVars.w
  cImplTypes.w
  cbSizeVft.w
  cbAlignment.w
  wTypeFlags.w
  wMajorVerNum.w
  wMinorVerNum.w
  tdescAlias.l
  idldescType.l
EndStructure
Structure VARDESC
  memid.l
  lpstrSchema.l
  union.l
  *elemdescVar.ELEMDESC
  wVarFlags.w
  varkind.w
EndStructure  
Procedure.s HexString(Source.l, l.l) 
    result.s
    
    result.s = ""
    For i = 0 To l
        result = result + Right("00" + Hex(PeekB(PeekL(Source)+i)), 2) + " "
    Next i
    
    ProcedureReturn result
EndProcedure
Procedure.s ByteStr(pointer.l) 
  strlen.w = WideCharToMultiByte_(#CP_ACP, 0, pointer, -1, 0, 0 , 0, 0) 
  string.s = Space(strlen) 
  If strlen <> 0 
    newlen.w = WideCharToMultiByte_(#CP_ACP, 0, pointer, -1, @string, strlen , 0, 0) 
  EndIf 
  ProcedureReturn string 
EndProcedure
Procedure.l WideStr(pointer.l, mem.l) 
  widelen.w = 2*Len(PeekS(pointer))+2 
  widebuf.l = AllocateMemory(mem, widelen) 
  longlen.w = MultiByteToWideChar_(#CP_ACP,0,pointer,-1,widebuf,widelen) 
  ProcedureReturn widebuf 
EndProcedure 
Procedure CheckFatalError(Err.l, ErrTxt.s)
  If Err <> 0
    MessageRequester("Fatal Error",ErrTxt+", Error : "+Hex(Err) ,0)
    End
  EndIf
EndProcedure
  
Procedure.l CheckError(Err.l, ErrTxt.s)
  If Err <> 0
    MessageRequester("Information",ErrTxt+", Error : "+Hex(Err) ,0)
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure  
Procedure.s stringCustomType(RefType.l, pTypeInfo.l)
  *TypeInfo.ITypeInfo=pTypeInfo
  
  If *TypeInfo\GetRefTypeInfo(RefType, @CustTypeInfo.ITypeInfo)=0
    If CustTypeInfo\GetDocumentation(-1, @bstrType, 0, 0, 0)=0
      ProcedureReturn ByteStr(bstrType)
    Else
      ProcedureReturn "UnknownCustomType"
    EndIf
  Else
    ProcedureReturn "UnknownCustomType"
  EndIf  
  ProcedureReturn "UnknownCustomType"
EndProcedure
Procedure.s stringTypeDesc(pTypeDesc.l, pTypeInfo.l)
  *TypeDesc.TYPEDESC=pTypeDesc
  *TypeInfo.ITypeInfo=pTypeInfo
  If *TypeDesc\vt = #VT_PTR
    ProcedureReturn stringTypeDesc(*TypeDesc\union, pTypeInfo)+"*"
  EndIf  
  If *TypeDesc\vt = #VT_SAFEARRAY
    ProcedureReturn "SAFEARRAY("+stringTypeDesc(*TypeDesc\union, pTypeInfo)+")"
  EndIf  
;  If pTypeDesc\vt = #VT_CARRAY
;    CArray.s=stringTypeDesc(@*TypeDesc\lpadesc\tdescElem, @*TypeInfo)
;  EndIf  
;  If pTypeDesc\vt = #VT_USERDEFINED
;    CArray.s=stringTypeDesc(@*TypeDesc\lpadesc\tdescElem, @*TypeInfo)
;  EndIf  
;    If(typeDesc->vt == VT_CARRAY) {
;        oss<< stringifyTypeDesc(&typeDesc->lpadesc->tdescElem, pTypeInfo);
;        for(int dim(0); typeDesc->lpadesc->cDims; ++dim) 
;            oss<< '['<< typeDesc->lpadesc->rgbounds[dim].lLbound<< "..."
;                << (typeDesc->lpadesc->rgbounds[dim].cElements + 
;                typeDesc->lpadesc->rgbounds[dim].lLbound - 1)<< ']';
;        return oss.str();
;    }
  If *TypeDesc\vt = #VT_USERDEFINED
    ProcedureReturn stringCustomType(*TypeDesc\union, pTypeInfo)
  EndIf
  Vt.l=*TypeDesc\vt
  Select Vt.l
    Case #VT_I2: ProcedureReturn "short";
    Case #VT_I4: ProcedureReturn "long";
    Case #VT_R4: ProcedureReturn "float";
    Case #VT_R8: ProcedureReturn "double";
    Case #VT_CY: ProcedureReturn "CY";
    Case #VT_DATE: ProcedureReturn "DATE";
    Case #VT_BSTR: ProcedureReturn "BSTR";
    Case #VT_DISPATCH: ProcedureReturn "IDispatch*";
    Case #VT_ERROR: ProcedureReturn "SCODE";
    Case #VT_BOOL: ProcedureReturn "VARIANT_BOOL";
    Case #VT_VARIANT: ProcedureReturn "VARIANT";
    Case #VT_UNKNOWN: ProcedureReturn "IUnknown*";
    Case #VT_UI1: ProcedureReturn "BYTE";
    Case #VT_DECIMAL: ProcedureReturn "DECIMAL";
    Case #VT_I1: ProcedureReturn "char";
    Case #VT_UI2: ProcedureReturn "USHORT";
    Case #VT_UI4: ProcedureReturn "ULONG";
    Case #VT_I8: ProcedureReturn "__int64";
    Case #VT_UI8: ProcedureReturn "unsigned __int64";
    Case #VT_INT: ProcedureReturn "int";
    Case #VT_UINT: ProcedureReturn "UINT";
    Case #VT_HRESULT: ProcedureReturn "HRESULT";
    Case #VT_VOID: ProcedureReturn "void"
    Case #VT_LPSTR: ProcedureReturn "char*";
    Case #VT_LPWSTR: ProcedureReturn "wchar_t*";
  EndSelect
  ProcedureReturn "BIG ERROR!";
EndProcedure
Procedure.s stringVarDesc(pVarDesc.l, pTypeInfo.l)
  *VarDesc.VARDESC=pVarDesc
  *TypeInfo.ITYPEINFO=pTypeInfo
  bstrName.s
  If *VarDesc\varkind = #VAR_CONST
    RetStr.s="const "+stringTypeDesc(@*VarDesc\elemdescVar\tdesc, @*TypeInfo)
    If *TypeInfo\GetDocumentation(*VarDesc\memid, @bstrName ,0, 0, 0)
      RetStr=RetStr+" "+ByteStr(@bstrName)+" = "
      If VariantChangeType_( @Variant, *VarDesc\union,0,#VT_BSTR)
        RetStr=RetStr+"???"
      Else
        RetStr=RetStr+ByteStr(@Variant)
      EndIf   
    Else
      RetStr="UnknownName"
    EndIf
  EndIf
  ProcedureReturn RetStr    
EndProcedure
Procedure.s stringParameterAttributes(pParamDesc.l) 
  *ParamDesc.PARAMDESC=pParamDesc
  paramFlags.w = *ParamDesc\wParamFlags
  
  numFlags.l=0
  bit.l=1
  While bit < #PARAMFLAG_FHASDEFAULT
    If paramFlags & bit
      numFlags=numFlags+1
    EndIf
    bit=bit*2
  Wend
  If numFlags=0
    ProcedureReturn ""
  EndIf
  RetStr.s="["
  If paramFlags & #PARAMFLAG_FIN
    RetStr=RetStr+"in, "
  EndIf 
  If paramFlags & #PARAMFLAG_FOUT
    RetStr=RetStr+"out, "
  EndIf 
  If paramFlags & #PARAMFLAG_FLCID
    RetStr=RetStr+"lcid, "
  EndIf 
  If paramFlags & #PARAMFLAG_FRETVAL
    RetStr=RetStr+"retval, "
  EndIf 
  If paramFlags & #PARAMFLAG_FOPT
    RetStr=RetStr+"optional, "
  EndIf 
  If paramFlags & #PARAMFLAG_FHASDEFAULT
    RetStr=RetStr+"defaultvalue="
    If *ParamDesc\pparamdescex
      *ParamDescEx.PARAMDESCEX=*ParamDesc\pparamdescex
      *varDefaultValue.VARIANTARG=*ParamDescEx\varDefaultValue
      
      If VariantChangeType_(@Variant.VARIANTARG,*varDefaultValue,0,#VT_BSTR)=0
        If *varDefaultValue\vt = #VT_BSTR
          RetStr=RetStr+Chr(34)
        EndIf
        RetStr=RetStr+ByteStr(Variant\union)
        If *varDefaultValue\vt = #VT_BSTR
          RetStr=RetStr+Chr(34)
        EndIf  
      Else
        RetStr=RetStr+"???"
      EndIf
    EndIf
  EndIf 
    If Right(RetStr,2)=", "
      RetStr=Left(RetStr, Len(RetStr)-2)
    EndIf
    RetStr=RetStr+"]"
  ProcedureReturn RetStr
EndProcedure  
Procedure.s stringFunctionArgument(pElemDesc.l, pTypeInfo.l)
    *ElemDesc.ELEMDESC=pElemDesc
    *TypeInfo.ITypeInfo=pTypeInfo
    pParamDesc.l=@*ElemDesc\paramdesc
    RetStr.s=stringParameterAttributes(pParamDesc)
    If Len(RetStr)>0
      RetStr=RetStr+" "      
    EndIf
    pTypeDesc.l=@*ElemDesc\tdesc
    RetStr=RetStr+stringTypeDesc(pTypeDesc.l, pTypeInfo)
  ProcedureReturn RetStr
EndProcedure  
Procedure.s stringCOMMethod(pFuncDesc.l, pTypeInfo.l)
  *FuncDesc.FUNCDESC=pFuncDesc
  *TypeInfo.ITypeInfo=pTypeInfo  
  If *FuncDesc\funckind = #FUNC_DISPATCH    
    RetStr.s="[id($"+Hex(*FuncDesc\memid)+")"
  Else 
    RetStr.s="[VOffset($"+Hex(*FuncDesc\oVft)+")"
  EndIf  
  Select *FuncDesc\invokekind
    Case #INVOKE_PROPERTYGET
      RetStr=RetStr+", propget] "
    Case #INVOKE_PROPERTYPUT
      RetStr=RetStr+", propput] "
    Case #INVOKE_PROPERTYPUTREF
      RetStr=RetStr+", propputref] "
    Case #INVOKE_FUNC
      RetStr=RetStr+"] "
  EndSelect
  RetStr=RetStr+stringTypeDesc(@*FuncDesc\elemdescFunc, pTypeInfo)
  MemberID.l=*FuncDesc\memid
  Err.l=*TypeInfo\GetDocumentation(MemberID, @bstrName, NULL, NULL, NULL)
  RetStr=RetStr+" "+ByteStr(bstrName)+"("
  RetNr.l
  ParNames.s=Space(1000)
  Nr.l=*FuncDesc\cParams
  Err.l=*TypeInfo\GetNames(MemberID,@ParNames,Nr.l+1, @RetNr)
  If *FuncDesc\cParams > 0
    pTemp.l=*FuncDesc\lprgelemdescParam
  EndIf  
  pElemDescParam.l=pTemp
  For i=0 To *FuncDesc\cParams-1
    If i>0
      RetStr=RetStr+", "
    EndIf
    RetStr=RetStr+stringFunctionArgument(pElemDescParam, pTypeInfo)
    RetStr=RetStr+" "+ByteStr(PeekL(@ParNames+((i+1)*4)))
    pElemDescParam=pElemDescParam+SizeOf(ELEMDESC)
  Next
  RetStr=RetStr+")"
  ProcedureReturn RetStr
EndProcedure  
  
DataSection 
  CATID_Control:  ;  CATID_Control, 0x40fc6ed4, 0x2438, 0x11cf, 0xa3, 0xdb, 0x08, 0x00, 0x36, 0xf1, 0x25, 0x02)
    Data.l $40FC6ED4 
    Data.w $2438,$11CF 
    Data.b $A3, $DB, $08,$00,$36,$F1,$25,$02
  CLSID_StdComponentCategoriesMgr:  ;  {0002E005-0000-0000-C000-000000000046}
    Data.l $0002E005 
    Data.w $0000,$0000 
    Data.b $C0, $00, $00,$00,$00,$00,$00,$46
  IID_ICatInformation:  ;  {0002E013-0000-0000-C000-000000000046}
    Data.l $0002E013 
    Data.w $0000,$0000 
    Data.b $C0, $00, $00,$00,$00,$00,$00,$46
    
  IID_Custom:   ; {0F21F359-AB84-41E8-9A78-36D110E6D2F9}  
    Data.l $0F21F359 
    Data.w $AB84,$41E8 
    Data.b $9A, $78, $36,$D1,$10,$E6,$D2,$F9
EndDataSection
;-Main Loop
If Window_Form1()
  SetGadgetState(#Gadget_Form1_opVtable,1)
  
  CoInitialize_(NULL)
  Err.l = CoCreateInstance_(?CLSID_StdComponentCategoriesMgr,0,1,?IID_ICatInformation,@oCatInfo.ICatInformation) 
  CheckFatalError(Err,"Can't Create Component Categories Manager")
  Err.l=oCatInfo\AddRef()
  Err.l=oCatInfo\EnumClassesOfCategories(1,?CATID_Control,0,@CatIdReg,@oEnumGUID.IEnumGUID);
  CheckFatalError(Err,"Can't Enumerate Classes of Categories")
  Clsid.GUID
  While  oEnumGUID\Next( 1, @Clsid, NULL )=0
    OleRegGetUserType_(@Clsid,#USERCLASSTYPE_FULL,@ClassName)
    StringFromClsid_(@Clsid,@ClsidWStr)
    SendMessage_( GadgetID(#Gadget_Form1_lbClassName), #LB_ADDSTRING, 0, ByteStr(ClassName)+Space(80)+ByteStr(ClsidWStr))
  Wend
  RemoveGadgetItem(#Gadget_Form1_lbClassName,0)
  Err.l=oCatInfo\Release()
  CoUninitialize_()
  quitForm1=0
  Repeat
    EventID=WaitWindowEvent()
    Select EventID
      Case #PB_Event_CloseWindow
        If EventWindowID()=#Window_Form1
          quitForm1=1
        EndIf
      Case #PB_Event_Gadget
        Select EventGadgetID()
          Case #Gadget_Form1_btSaveFile
            StandardFile$ = "C:\Programmeren\PureBasic\temp.pb"   ; set initial file+path to display 
            Pattern$ = "PureBasic (*.pb)|*.pb|All files (*.*)|*.*" 
            Pattern = 0    ; use the first of the three possible patterns as standard 
            File$ = SaveFileRequester("Please choose file to save", StandardFile$, Pattern$, Pattern) 
            If File$
              If Pattern=0 And FindString(File$,".",1) = 0
                File$=File$+".pb"
              EndIf
              If OpenFile(#1,File$)
                For I=1 To CountGadgetItems(#Gadget_Form1_lbIncludeFile)
                  WriteStringN(GetGadgetItemText(#Gadget_Form1_lbIncludeFile, I-1,0))            
                Next
                CloseFile(1)
              EndIf  
            Else 
              MessageRequester("Information", "The requester was canceled.", 0) 
            EndIf 
          Case #Gadget_Form1_lbClassName
            Select EventType()
              Case #PB_EventType_LeftDoubleClick
              Default
                ClearGadgetItemList(#Gadget_Form1_lbInterfaces)
                ClearGadgetItemList(#Gadget_Form1_lbIncludeFile)
                Err.l=SendMessage_( GadgetID(#Gadget_Form1_lbIncludeFile), #LB_SETHORIZONTALEXTENT, 0, 0)
                ClsidStr.s = GetGadgetText(#Gadget_Form1_lbClassName)
                Pos.l = FindString(ClsidStr,"{",1)
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"DataSection")
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  CLSID_"+StringField(Left(ClsidStr,Pos-1),1," ")+":")
                CtrlStr.s="ProgID_"+StringField(Left(ClsidStr,Pos-1),1," ")+".s="
                ClsidStr=Mid(ClsidStr,Pos,100)
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  Data.l $"+Mid(ClsidStr,2,8))
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  Data.w $"+Mid(ClsidStr,11,4)+",$"+Mid(ClsidStr,16,4))
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  Data.b $"+Mid(ClsidStr,21,2)+",$"+Mid(ClsidStr,23,2)+",$"+Mid(ClsidStr,26,2)+",$"+Mid(ClsidStr,28,2)+",$"+Mid(ClsidStr,30,2)+",$"+Mid(ClsidStr,32,2)+",$"+Mid(ClsidStr,34,2)+",$"+Mid(ClsidStr,36,2))
                
                                
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"EndDataSection")                
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"")
                Err.l=CLSIDFromString_(WideStr(@ClsidStr,1),@Clsid.GUID)
                ProgID.l 
                Err.l=ProgIDFromCLSID_(@Clsid,@ProgID)
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,CtrlStr+Chr(34)+ByteStr(ProgID)+Chr(34)) 
                AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"") 
                               
                
                Err.l = RegOpenKeyEx_(#HKEY_CLASSES_ROOT,"CLSID\"+ClsidStr+"\TypeLib",0,#KEY_READ,@hTypeLib.l)
                If CheckError(Err,"Control doesn't have a Typelib")
                  Continue
                EndIf
                TLBClsidStr.s=Space(100)
                dwSizeOfDataBlock.l=100
                RegQueryValue_(hTypeLib,NULL,@TLBClsidStr,@dwSizeOfDataBlock)
                
                tchVersionInformation.s=Space(100)
                Err.l=RegOpenKeyEx_(#HKEY_CLASSES_ROOT,"TypeLib\"+TLBClsidStr,0,KEY_READ, @hKeyClassTLB.l)
                If CheckError(Err,"Typelib not registererd")
                  Continue
                EndIf
                dwCLSIDSubKeyIndex.l = 0
                While RegEnumKey_(hKeyClassTLB,dwCLSIDSubKeyIndex ,@tchVersionInformation,20) =0
                  If RegOpenKeyEx_(hKeyClassTLB,@tchVersionInformation,0,KEY_READ,@hKeyVersion.l) =0    
                  EndIf
                  dwCLSIDSubKeyIndex=dwCLSIDSubKeyIndex+1
                Wend
                clsidTypeLib.GUID
                A$ = Space((Len(TLBClsidStr)+1)*2)
                MultiByteToWideChar_(#CP_ACP,0,TLBClsidStr,-1,@A$,Len(A$))
                Err.l = CLSIDFromString_(A$,clsidTypeLib)
                CheckFatalError(Err,"Not a valid ClassId")
                Major.l=Val(tchVersionInformation)
                Pos.l = FindString(tchVersionInformation,".",1)
                tchVersionInformation.s=Mid(tchVersionInformation,Pos+1,100)
                Minor.l=Val(tchVersionInformation)
                
                Err.l = LoadRegTypeLib_(clsidTypeLib,Major,Minor,0, @oTypeLib.ITypeLib)
                CheckFatalError(Err,"Can't load TypeLib")
                Nr.l = oTypeLib\GetTypeInfoCount();
                For I = 0 To Nr-1
                  Err.l = oTypeLib\GetDocumentation(I, @bstrName, @bstrDocString, NULL, NULL)
                  CheckFatalError(Err,"Can't extract Interface from TypeLib")
                  AddGadgetItem(#Gadget_Form1_lbInterfaces,-1,ByteStr(PeekL(@bstrName)))                
                Next               
                
            EndSelect
          Case #Gadget_Form1_lbInterfaces
            Select EventType()
              Case #PB_EventType_LeftDoubleClick
              Default
                Params.s=" a.l,b.l,c.l,d.l,e.l,f.l,g.l,h.l,i.l,j.l,k.l,l.l,m.l,n.l,o.l,p.l,q.l,r.l,s.l,t.l,u.l,v.l,w.l,x.l,y.l,z.l"
                Index.l = GetGadgetState(#Gadget_Form1_lbInterfaces)
                Err.l = oTypeLib\GetTypeInfo(Index, @oCurrentTypeInfo.ITypeInfo);
                CheckFatalError(Err,"Can't get TypeInfo from TypeLib")
                aTypeAttributes.l
                Err.l = oCurrentTypeInfo\GetTypeAttr(@aTypeAttributes)
                CheckFatalError(Err,"Can't get TypeAttributes from TypeInfo")
                *oTypeAttributes.TYPEATTR=aTypeAttributes
                If *oTypeAttributes\typekind=#TKIND_DISPATCH Or *oTypeAttributes\typekind=#TKIND_INTERFACE
                  Err.l = StringFromClsid_(*oTypeAttributes\guid,@IIDwStr)
                  CheckFatalError(Err,"Not a valid IDD")
                  IIDbStr.s=ByteStr(IIDwStr)
                
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"DataSection")
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  IID_"+GetGadgetText(#Gadget_Form1_lbInterfaces)+":")
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  Data.l $"+Mid(IIDbStr,2,8))
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  Data.w $"+Mid(IIDbStr,11,4)+",$"+Mid(IIDbStr,16,4))
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  Data.b $"+Mid(IIDbStr,21,2)+",$"+Mid(IIDbStr,23,2)+",$"+Mid(IIDbStr,26,2)+",$"+Mid(IIDbStr,28,2)+",$"+Mid(IIDbStr,30,2)+",$"+Mid(IIDbStr,32,2)+",$"+Mid(IIDbStr,34,2)+",$"+Mid(IIDbStr,36,2))
                
                                
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"EndDataSection")                
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"")                
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"IID_"+GetGadgetText(#Gadget_Form1_lbInterfaces)+"Str.s="+Chr(34)+IIDbStr+Chr(34))
                  AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"")                
                
                  Nr.l=*oTypeAttributes\cFuncs
                  If GetGadgetState(#Gadget_Form1_opVtable)=1
                    hRefType.l
                    Err.l=oCurrentTypeInfo\GetRefTypeOfImplType(-1,@hRefType)
                    If CheckError(Err,"No custom Vtable interface, choose dispinterface")
                      Continue
                    EndIf  
                    Err.l=oCurrentTypeInfo\GetRefTypeInfo(hRefType,@oCurrentTypeInfo.ITypeInfo)
                    If CheckError(Err,"No custom Vtable interface, choose dispinterface")
                      Continue
                    EndIf  
                    Nr=Nr-7
                    Extends.s=" Extends IDispatch"
                  Else
                    Extends.s=""    
                  EndIf
                  
                  If Nr>0
                    If GetGadgetState(#Gadget_Form1_opEnumEvents)=1
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"Enumeration")                
                    Else
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"Interface "+GetGadgetText(#Gadget_Form1_lbInterfaces)+Extends)                
                    EndIf
                  EndIf
                  For I = 0 To Nr-1
                    Err.l = oCurrentTypeInfo\GetFuncDesc(I, @aFuncDesc.l)
                    CheckFatalError(Err,"Can't Function Descriprion from TypeInfo")
                    *oFuncDesc.FUNCDESC=aFuncDesc
                    MemberID=*oFuncDesc\memid
                    NrOfParams.l=*oFuncDesc\cParams
                    NrOfParamsOpt.l=*oFuncDesc\cParamsOpt
                    InvokeKind.l=*oFuncDesc\invokekind
                    Err.l = oCurrentTypeInfo\GetDocumentation(memberID, @bstrMethod, NULL, NULL, NULL)
                    pTypeInfo.l=oCurrentTypeInfo
                    
                    STRCOMMethod.s=stringCOMMethod(*oFuncDesc, pTypeInfo)
                    
                    PreFix.s=""
                    Select InvokeKind
                      Case #INVOKE_PROPERTYGET
                        PreFix.s="Get_"
                      Case #INVOKE_PROPERTYPUT
                        PreFix.s="Put_"
                      Case #INVOKE_PROPERTYPUTREF
                        PreFix.s="Put_"
                    EndSelect
                    If GetGadgetState(#Gadget_Form1_opEnumEvents)=1
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  #On_"+ByteStr(bstrMethod)+" = "+Str(MemberID)+"   ; "+STRCOMMethod) 
                    Else
                      Err.l = oCurrentTypeInfo\GetDocumentation(memberID, @bstrMethod, NULL, NULL, NULL)
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"  "+Prefix+ByteStr(bstrMethod)+"("+Mid(Left(Params,NrOfParams*4),2,100)+")"+"   ; "+STRCOMMethod) 
                    EndIf                 
                  Next
                  If Nr>0
                    If GetGadgetState(#Gadget_Form1_opEnumEvents)=1
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"EndEnumeration")                
                    Else  
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"EndInterface")                
                      AddGadgetItem(#Gadget_Form1_lbIncludeFile,-1,"")                
                    EndIf  
                  EndIf
                  CharLen.l=0
                  For i=0 To CountGadgetItems(#Gadget_Form1_lbIncludeFile)-1
                    TmpCharLen.l=Len(GetGadgetItemText(#Gadget_Form1_lbIncludeFile, i,0))
                    If TmpCharLen > CharLen
                      CharLen=TmpCharLen
                    EndIf
                  Next
                  Err.l=GetTextMetrics_(GetDC_(GadgetID(#Gadget_Form1_lbIncludeFile)),@tm.TEXTMETRIC)
                  PixLen.l=CharLen*tm\tmAveCharWidth
                  Err.l=SendMessage_( GadgetID(#Gadget_Form1_lbIncludeFile), #LB_SETHORIZONTALEXTENT, PixLen, 0)
                Else
                  MessageRequester("Information","Only (Dispatch)-Interfaces contribute to the Include File",0)
                EndIf  
            EndSelect
           Case #Gadget_Form1_lbIncludeFile
            Select EventType()
              Case #PB_EventType_LeftDoubleClick
              Default
            EndSelect
        EndSelect
    EndSelect
  Until quitForm1
  CloseWindow(#Window_Form1)
EndIf
End
The 2 include file for this program
Code: Select all
;-Window Constants
Enumeration
  #Window_Form1
EndEnumeration
#WindowIndex=#PB_Compiler_EnumerationValue
;-Gadget Constants
Enumeration
  ;Window_Form1
  #Gadget_Form1_lbClassName
  #Gadget_Form1_lbInterfaces
  #Gadget_Form1_lbIncludeFile
  #Gadget_Form1_btSaveFile
  #Gadget_Form1_txControls
  #Gadget_Form1_txInterfaces
  #Gadget_Form1_txInckudeFile
  #Gadget_Form1_opVtable
  #Gadget_Form1_opDispatch
  #Gadget_Form1_opEnumEvents
EndEnumeration
#GadgetIndex=#PB_Compiler_EnumerationValue
;-Load Images
and
Code: Select all
XIncludeFile "Controls_Constants.pb"
Procedure.l Window_Form1()
  If OpenWindow(#Window_Form1,95,349,603,484,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_Invisible," OLE/COM Include File Generator")
    If CreateGadgetList(WindowID(#Window_Form1))
      ListViewGadget(#Gadget_Form1_lbClassName,10,30,260,200,#LBS_SORT)
      ListViewGadget(#Gadget_Form1_lbInterfaces,290,30,300,200)
      ListViewGadget(#Gadget_Form1_lbIncludeFile,10,270,460,200,#WS_HSCROLL)
      ButtonGadget(#Gadget_Form1_btSaveFile,490,270,100,20,"Save XIncludeFile")
      TextGadget(#Gadget_Form1_txControls,10,10,95,15,"OLE/COM Controls")
      TextGadget(#Gadget_Form1_txInterfaces,305,10,50,15,"Interfaces")
      TextGadget(#Gadget_Form1_txInckudeFile,10,250,110,15,"PureBasic Include File")
      OptionGadget(#Gadget_Form1_opVtable,355,10,55,15,"VTable")
      OptionGadget(#Gadget_Form1_opDispatch,415,10,85,15,"DispInterface")
      OptionGadget(#Gadget_Form1_opEnumEvents,500,10,85,15,"Enum-Events")
      HideWindow(#Window_Form1,0)
      ProcedureReturn WindowID()
    EndIf
  EndIf
EndProcedure
I made an example how to use the generator with the MS Calendar Control
The main PB file
Code: Select all
;-Init Includes
XIncludeFile "Calendar_Constants.pb"
XIncludeFile "Calendar_Windows.pb"
XIncludeFile "Calendar.inc"
XIncludeFile "OleCom.inc"
Procedure CheckError(Err.l, ErrTxt.s)
  If Err <> 0
    MessageRequester("Fatal Error",ErrTxt+", Error : "+Hex(Err) ,0)
    End
  EndIf
EndProcedure  
Procedure Dummy(a.l)
  ProcedureReturn 0
EndProcedure
Procedure QueryInterface(this.l, a.l, b.l)
  ProcedureReturn @Event
EndProcedure
Procedure Invoke(this.l, dispid.l, b.l, c.l, d.l, pDispParam.l,f.l,g.l,h.l)
  Select dispid
    Case #On_DblClick
      MessageRequester("Dubble click", "Happy 2004",0)
    Case #On_KeyPress
      *DispParams.DISPPARAMS=pDispParam
      *Variant.VARIANTARG=*DispParams\rgvarg
      MessageRequester("Key Pressed",Hex(*Variant\vt)+" "+Chr(PeekW(*Variant\union)),0)
    Case #On_NewMonth
      MessageRequester("Change Month", "Happy 2004",0)
    Case #On_NewYear
      MessageRequester("Change Year", "Happy 2004",0)
    Default  
  EndSelect    
  ProcedureReturn 0
EndProcedure
Procedure CreateMyClass() 
  Shared x 
  Dim CreateMyClass_Interface.l(7) 
  CreateMyClass_Interface(0) = @QueryInterface() 
  CreateMyClass_Interface(1) = @Dummy() 
  CreateMyClass_Interface(2) = @Dummy() 
  CreateMyClass_Interface(3) = @Dummy() 
  CreateMyClass_Interface(4) = @Dummy() 
  CreateMyClass_Interface(5) = @Dummy() 
  CreateMyClass_Interface(6) = @Invoke() 
  x = @CreateMyClass_Interface() 
  ProcedureReturn @x 
EndProcedure 
Event.IDispatch=CreateMyClass()
;-Main Loop
If Window_Form1()
  *oCal.ICalendar = ActiveXContainer(WindowID(),20,20,290,200,ProgID_Calendar,IID_ICalendarStr)
  Err.l=*oCal\QueryInterface(?IConnectionPointContainer,@oCPC.ICPC)
  CheckError(Err,"Couldn't init ConnectionPointContainer")
  Err.l=oCPC\AddRef()
  Err.l=oCPC\FindConnectionPoint(?IID_DCalendarEvents,@oCP.ICP)
  CheckError(Err,"Couldn't find ConnectionPoint")
  Err.l=oCP\AddRef()
  Err.l=oCP\Advise(Event,@Cookie)
  CheckError(Err,"Couldn't advise Event")
  Err.l=oCPC\Release()
  Err.l=oCP\Release()
  quitForm1=0
  Repeat
    EventID=WaitWindowEvent()
    Select EventID
      Case #PB_Event_CloseWindow
        If EventWindowID()=#Window_Form1
          quitForm1=1
        EndIf
      Case #PB_Event_Gadget
        Select EventGadgetID()
          Case #Gadget_Form1_String2
          Case #Gadget_Form1_Button3
            Maand.l
            Dag.l
            Jaar.l
            Err.l=*oCal\Get_Month(@Maand)
            Err.l=*oCal\Get_Day(@Dag)
            Err.l=*oCal\Get_Year(@Jaar)
            SetGadgetText(#Gadget_Form1_String2,Str(Dag)+"/"+Str(Maand)+"/"+Str(Jaar))
        EndSelect
    EndSelect
  Until quitForm1
  Delete(*oCal)
  CloseWindow(#Window_Form1)
EndIf
End
The generated XIncludeFile : Calendar.inc
Code: Select all
DataSection
  CLSID_Calendar:
  Data.l $8E27C92B
  Data.w $1264,$101C
  Data.b $8A,$2F,$04,$02,$24,$00,$9C,$02
EndDataSection
ProgID_Calendar.s="MSCAL.Calendar.7"
DataSection
  IID_ICalendar:
  Data.l $8E27C92C
  Data.w $1264,$101C
  Data.b $8A,$2F,$04,$02,$24,$00,$9C,$02
EndDataSection
IID_ICalendarStr.s="{8E27C92C-1264-101C-8A2F-040224009C02}"
Interface ICalendar Extends IDispatch
  Get_BackColor(a.l)   ; [VOffset($1C), propget] HRESULT BackColor([out, retval] OLE_COLOR* pclrBackColor)
  Put_BackColor(a.l)   ; [VOffset($20), propput] HRESULT BackColor([in] OLE_COLOR pclrBackColor)
  Get_Day(a.l)   ; [VOffset($24), propget] HRESULT Day([out, retval] short* pnDay)
  Put_Day(a.l)   ; [VOffset($28), propput] HRESULT Day([in] short pnDay)
  Get_DayFont(a.l)   ; [VOffset($2C), propget] HRESULT DayFont([out, retval] IFontDisp** ppfontDayFont)
  Put_DayFont(a.l)   ; [VOffset($30), propput] HRESULT DayFont([in] IFontDisp* ppfontDayFont)
  Get_DayFontColor(a.l)   ; [VOffset($34), propget] HRESULT DayFontColor([out, retval] OLE_COLOR* pclrDayFontColor)
  Put_DayFontColor(a.l)   ; [VOffset($38), propput] HRESULT DayFontColor([in] OLE_COLOR pclrDayFontColor)
  Get_DayLength(a.l)   ; [VOffset($3C), propget] HRESULT DayLength([out, retval] short* pnDayLength)
  Put_DayLength(a.l)   ; [VOffset($40), propput] HRESULT DayLength([in] short pnDayLength)
  Get_FirstDay(a.l)   ; [VOffset($44), propget] HRESULT FirstDay([out, retval] short* pnFirstDay)
  Put_FirstDay(a.l)   ; [VOffset($48), propput] HRESULT FirstDay([in] short pnFirstDay)
  Get_GridCellEffect(a.l)   ; [VOffset($4C), propget] HRESULT GridCellEffect([out, retval] long* plGridCellEffect)
  Put_GridCellEffect(a.l)   ; [VOffset($50), propput] HRESULT GridCellEffect([in] long plGridCellEffect)
  Get_GridFont(a.l)   ; [VOffset($54), propget] HRESULT GridFont([out, retval] IFontDisp** ppfontGridFont)
  Put_GridFont(a.l)   ; [VOffset($58), propput] HRESULT GridFont([in] IFontDisp* ppfontGridFont)
  Get_GridFontColor(a.l)   ; [VOffset($5C), propget] HRESULT GridFontColor([out, retval] OLE_COLOR* pclrGridFontColor)
  Put_GridFontColor(a.l)   ; [VOffset($60), propput] HRESULT GridFontColor([in] OLE_COLOR pclrGridFontColor)
  Get_GridLinesColor(a.l)   ; [VOffset($64), propget] HRESULT GridLinesColor([out, retval] OLE_COLOR* pclrGridLinesColor)
  Put_GridLinesColor(a.l)   ; [VOffset($68), propput] HRESULT GridLinesColor([in] OLE_COLOR pclrGridLinesColor)
  Get_Month(a.l)   ; [VOffset($6C), propget] HRESULT Month([out, retval] short* pnMonth)
  Put_Month(a.l)   ; [VOffset($70), propput] HRESULT Month([in] short pnMonth)
  Get_MonthLength(a.l)   ; [VOffset($74), propget] HRESULT MonthLength([out, retval] short* pnMonthLength)
  Put_MonthLength(a.l)   ; [VOffset($78), propput] HRESULT MonthLength([in] short pnMonthLength)
  Get_ShowDateSelectors(a.l)   ; [VOffset($7C), propget] HRESULT ShowDateSelectors([out, retval] VARIANT_BOOL* pfShowDateSelectors)
  Put_ShowDateSelectors(a.l)   ; [VOffset($80), propput] HRESULT ShowDateSelectors([in] VARIANT_BOOL pfShowDateSelectors)
  Get_ShowDays(a.l)   ; [VOffset($84), propget] HRESULT ShowDays([out, retval] VARIANT_BOOL* pfShowDays)
  Put_ShowDays(a.l)   ; [VOffset($88), propput] HRESULT ShowDays([in] VARIANT_BOOL pfShowDays)
  Get_ShowHorizontalGrid(a.l)   ; [VOffset($8C), propget] HRESULT ShowHorizontalGrid([out, retval] VARIANT_BOOL* pfShowHorizontalGrid)
  Put_ShowHorizontalGrid(a.l)   ; [VOffset($90), propput] HRESULT ShowHorizontalGrid([in] VARIANT_BOOL pfShowHorizontalGrid)
  Get_ShowTitle(a.l)   ; [VOffset($94), propget] HRESULT ShowTitle([out, retval] VARIANT_BOOL* pfShowTitle)
  Put_ShowTitle(a.l)   ; [VOffset($98), propput] HRESULT ShowTitle([in] VARIANT_BOOL pfShowTitle)
  Get_ShowVerticalGrid(a.l)   ; [VOffset($9C), propget] HRESULT ShowVerticalGrid([out, retval] VARIANT_BOOL* pfShowVerticalGrid)
  Put_ShowVerticalGrid(a.l)   ; [VOffset($A0), propput] HRESULT ShowVerticalGrid([in] VARIANT_BOOL pfShowVerticalGrid)
  Get_TitleFont(a.l)   ; [VOffset($A4), propget] HRESULT TitleFont([out, retval] IFontDisp** ppfontTitleFont)
  Put_TitleFont(a.l)   ; [VOffset($A8), propput] HRESULT TitleFont([in] IFontDisp* ppfontTitleFont)
  Get_TitleFontColor(a.l)   ; [VOffset($AC), propget] HRESULT TitleFontColor([out, retval] OLE_COLOR* pclrTitleFontColor)
  Put_TitleFontColor(a.l)   ; [VOffset($B0), propput] HRESULT TitleFontColor([in] OLE_COLOR pclrTitleFontColor)
  Get_Value(a.l)   ; [VOffset($B4), propget] HRESULT Value([out, retval] VARIANT* pvarValue)
  Put_Value(a.l)   ; [VOffset($B8), propput] HRESULT Value([in] VARIANT pvarValue)
  Get__Value(a.l)   ; [VOffset($BC), propget] HRESULT _Value([out, retval] VARIANT* pvarValue)
  Put__Value(a.l)   ; [VOffset($C0), propput] HRESULT _Value([in] VARIANT pvarValue)
  Get_ValueIsNull(a.l)   ; [VOffset($C4), propget] HRESULT ValueIsNull([out, retval] VARIANT_BOOL* pfValueIsNull)
  Put_ValueIsNull(a.l)   ; [VOffset($C8), propput] HRESULT ValueIsNull([in] VARIANT_BOOL pfValueIsNull)
  Get_Year(a.l)   ; [VOffset($CC), propget] HRESULT Year([out, retval] short* pnYear)
  Put_Year(a.l)   ; [VOffset($D0), propput] HRESULT Year([in] short pnYear)
  NextDay()   ; [VOffset($D4)] HRESULT NextDay()
  NextMonth()   ; [VOffset($D8)] HRESULT NextMonth()
  NextWeek()   ; [VOffset($DC)] HRESULT NextWeek()
  NextYear()   ; [VOffset($E0)] HRESULT NextYear()
  PreviousDay()   ; [VOffset($E4)] HRESULT PreviousDay()
  PreviousMonth()   ; [VOffset($E8)] HRESULT PreviousMonth()
  PreviousWeek()   ; [VOffset($EC)] HRESULT PreviousWeek()
  PreviousYear()   ; [VOffset($F0)] HRESULT PreviousYear()
  Refresh()   ; [VOffset($F4)] HRESULT Refresh()
  Today()   ; [VOffset($F8)] HRESULT Today()
  AboutBox()   ; [VOffset($FC)] HRESULT AboutBox()
EndInterface
DataSection
  IID_DCalendarEvents:
  Data.l $8E27C92D
  Data.w $1264,$101C
  Data.b $8A,$2F,$04,$02,$24,$00,$9C,$02
EndDataSection
IID_DCalendarEventsStr.s="{8E27C92D-1264-101C-8A2F-040224009C02}"
Enumeration
  #On_Click = -600   ; [id($FFFFFDA8)] void Click()
  #On_DblClick = -601   ; [id($FFFFFDA7)] void DblClick()
  #On_KeyDown = -602   ; [id($FFFFFDA6)] void KeyDown(short* KeyCode, short Shift)
  #On_KeyPress = -603   ; [id($FFFFFDA5)] void KeyPress(short* KeyAscii)
  #On_KeyUp = -604   ; [id($FFFFFDA4)] void KeyUp(short* KeyCode, short Shift)
  #On_BeforeUpdate = 2   ; [id($2)] void BeforeUpdate(short* Cancel)
  #On_AfterUpdate = 1   ; [id($1)] void AfterUpdate()
  #On_NewMonth = 3   ; [id($3)] void NewMonth()
  #On_NewYear = 4   ; [id($4)] void NewYear()
EndEnumeration
A standard OLECOM.inc file :
Code: Select all
;  Enumerations
Enumeration  
  #DVASPECT_CONTENT    = 1 
  #DVASPECT_THUMBNAIL  = 2 
  #DVASPECT_ICON       = 4 
  #DVASPECT_DOCPRINT   = 8 
EndEnumeration 
;  Structures
Structure DISPPARAMS
  rgvarg.l
  rgdispidNamedArgs.l
  cArgs.w
  cNamedArgs.w
EndStructure
Structure VARIANTARG
  vt.w
  dummy1.w
  dummy2.w
  dummy3.w
  union.l
EndStructure
Interface ICP Extends IUnknown
  GetConnectionInterface(a.l)
  GetConnectionPointContainer(a.l)
  Advise(a.l, b.l)
  Unadvise(a.l)
  EnumConnections(a.l)
EndInterface
;  Interfaces
Interface ICPC Extends IUnknown
  EnumConnectionPoints (a.l)
  FindConnectionPoint (a.l, b.l)
EndInterface
Interface IOleWindow Extends IUnknown
  GetWindow()
  ContextSensitiveHelp()
EndInterface
Interface IOleInPlaceObject Extends IOleWindow
  InPlaceDeactivate()
  UIDeactivate()
  SetObjectRects(a.l, b.l)
  ReactivateAndUndo()
EndInterface
Interface IOleObject Extends IUnknown
  SetClientSite(a.l)
  GetClientSite(a.l)
  SetHostNames()
  Close()
  SetMoniker()
  GetMoniker()
  InitFromData()
  GetClipboardData()
  DoVerb(a.l, b.l, c.l, d.l, e.l, f.l)
  EnumVerbs()
  Update()
  IsUpToDate()
  GetUserClassID()
  GetUserType()
  SetExtent(a.l,b.l)
  GetExtent(a.l,b.l)
  Advise()
  UnAdvise()
  EnumAdvise()
  GetMiscStatus()
  SetColorScheme()
EndInterface
Interface IViewObject Extends IUnknown
  Draw(a.l, b.l, c.l, d.l, e.l, f.l, g.l, h.l, i.l, j.l)
  GetColorSet()
  Freeze()
  UnFreeze()
  SetAdvise()
  GetAdvise()
EndInterface
Interface IViewObject2 Extends IViewObject
  GetExtent(a.l)
EndInterface
; Data Section
DataSection 
  IConnectionPointContainer:  ;  {B196B284-BAB4-101A-B69C-00AA00341D07}
    Data.l $B196B284 
    Data.w $BAB4,$101A 
    Data.b $B6, $9C, $00,$AA,$00,$34,$1D,$07 
    
  IOleObject:   ;  {00000112-0000-0000-C000-000000000046}  
    Data.l $00000112 
    Data.w $0000,$0000 
    Data.b $C0, $00, $00,$00,$00,$00,$00,$46
    
  IOleInPlaceObject:  ;  {00000113-0000-0000-C000-000000000046}    
    Data.l $00000113 
    Data.w $0000,$0000 
    Data.b $C0, $00, $00,$00,$00,$00,$00,$46
    
  IViewObject:  ; {0000010D-0000-0000-C000-000000000046}  
    Data.l $0000010D 
    Data.w $0000,$0000 
    Data.b $C0, $00, $00,$00,$00,$00,$00,$46
EndDataSection 
;  Procedures
Procedure RegisterDLL(DLL$)
  CoInitialize_(0)
  If OpenLibrary(1,DLL$)
    If CallFunction(1,"DllRegisterServer") = #S_OK
      RegisterDLL = #TRUE
    EndIf
    CloseLibrary(1)
  EndIf
  ProcedureReturn RegisterDLL
EndProcedure
Procedure UnRegisterDLL(DLL$)
  CoUninitialize_()
  If OpenLibrary(1,DLL$)
    If CallFunction(1,"DllUnregisterServer") = #S_OK
      UnRegisterDLL = #TRUE
    EndIf
    CloseLibrary(1)
  EndIf
  ProcedureReturn UnRegisterDLL
EndProcedure
Procedure Delete(*obj.IUnknown)
  Err.l=*obj\Release()
EndProcedure
Procedure EndAtlAx()
  CallFunction(2,"AtlAxWinTerm")
EndProcedure
Procedure ActiveXContainer(hParent,x,y,w,h,Control$,IID$)
  Shared CreateActiveXControl_init
  If CreateActiveXControl_init=0
    If OpenLibrary(2,"ATL.DLL")
      CallFunction(2,"AtlAxWinInit")
      CreateActiveXControl_init=1
    Else
      MessageRequester("","Geen ATL",0)
      ProcedureReturn 0
    EndIf
  Else  
      MessageRequester("","Geen ATL",0)
  EndIf
  ;  MessageRequester("","", 0)
  hWnd = CreateWindowEx_(0,"AtlAxWin",Control$,#WS_CHILD|#WS_VISIBLE,x,y,w,h,hParent,0,GetModuleHandle_(0),0)
  If hWnd
    CallFunction(2,"AtlAxGetControl",hWnd,@obj2.IUnknown)
    A$ = Space((Len(IID$)+1)*2)
    MultiByteToWideChar_(#CP_ACP,0,IID$,-1,@A$,Len(A$))
    If CLSIDFromString_(A$,IID.GUID) = #NOERROR
      obj2\QueryInterface(IID,@final)
    EndIf
    If final
      CreateActiveXControl = final
    Else
      MessageRequester("Fatal Error","Could not create ActiveX instance",0)
      DestroyWindow_(hWnd)
      End
    EndIf
    
  EndIf
  ProcedureReturn CreateActiveXControl
EndProcedure
And the two PureVision includes files :
Code: Select all
;-Window Constants
Enumeration
  #Window_Form1
EndEnumeration
#WindowIndex=#PB_Compiler_EnumerationValue
;-Gadget Constants
Enumeration
  ;Window_Form1
  #Gadget_Form1_String2
  #Gadget_Form1_Button3
EndEnumeration
#GadgetIndex=#PB_Compiler_EnumerationValue
;-Load Images
And
Code: Select all
XIncludeFile "Calendar_Constants.pb"
Procedure.l Window_Form1()
  If OpenWindow(#Window_Form1,276,5,347,300,#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget|#PB_Window_Invisible,"MS Calendar ActiveX Sample")
    If CreateGadgetList(WindowID(#Window_Form1))
      StringGadget(#Gadget_Form1_String2,95,260,80,20,"")
      ButtonGadget(#Gadget_Form1_Button3,20,260,70,20,"Show Datum")
      HideWindow(#Window_Form1,0)
      ProcedureReturn WindowID()
    EndIf
  EndIf
EndProcedure
A lot of code, I hope you can use it.