在FORM中有一控件myButton的一个实例,可以得到hwnd,如何得到它的CLSID或PROGID呢?myButton控件可能是任何控件,有可能是第三方开发的,如何得到它的CLSID或PROGID,以便动态创建此控件的实例?得到CLSID后可以通过API ProgIDFromCLSID得到它的PROGID。用 TLI 类库可以用ClassInfoFromObject得到GUID(也主是CLSID),但在运行时发生类不支持自动化的错误。

解决方案 »

  1.   

    用hwnd得到class windowproc, 然后看windowproc的地址属于哪个模块, 可知道ocx的名字.
    然后根据ocx的名字从注册表中查.或者
    ITypeLib * pTypeLib; 
    if(SUCCESS(LoadTypeLib(T2OLE("FileName.ocx"),&pTypeLib)) 

    TLIBATTR tlibAttr; 
    pTypeLib->GetLibAttr(&tlibAttr); 
    // tlibAttr.guid 就是你要的CLSID 
    pTypeLib->Release(); 
    }
      

  2.   

    To: pigsanddogs因为你跟我一样,所以长不胖(开个玩笑,先)你的方法行得通,但是需要用C++,而且要用到ITypeLib ,我不希望用到多余的库,另外是需要自己写一个C++的DLL给VB调用,这也不是不太完美。能用VB实现吗? 实在不行,那可不可以不用ITypeLib。
    另外我在MSDN中查到
    mk:@MSITStore:C:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\COM.chm::/devdoc/live/com/if_p2q_1yn8.htmIPersist::GetClassID,它可以实现这个功能,但不是API,而是包含在objidl.h中的。请问有没有其它API可以从实例得到CLSID。tks!
      

  3.   

    c可以转成vb的哦
    可能有点难度吧. 你直接call那个虚表的函数就好了.查注册表可以得到, 不过估计慢一些我com学的不好. 只能给你这个建议.
      

  4.   

    IOleObject::GetClassID
    need to get the IUnknown interface of the control. The control is not likely be exposed by its container.
      

  5.   

    To:pigsanddogs
       很难。不过还是tks.To:jiangsheng
       is not likely be exposed 也就  is likely be exposed 我再看看有什么办法没有。
      

  6.   

    //用hwnd得到class windowproc, 然后看windowproc的地址属于哪个模块, 可知道ocx的名字.
    然后根据ocx的名字从注册表中查.此方法不行。因为得到OCX的文件名也没用,因为OCX中不止一个控件,那如何得到一个特定控件的CLSID呢??
      

  7.   

    参考:http://www.chenoe.com/blog/article.asp?id=2039
      

  8.   

    考虑是不是可以根据控件的类名称(例如myOcx.MyControl)来得到它的CLSID。
      

  9.   

    To:TechnoFantasy类名? 你是指用GetClassName?  它得到的不是PROGID或CLSID,不行如果你是指PROGID,那我就不用这么费劲了
      

  10.   

    To:Modest(塞北雪貂)·你给的贴子上的方法我早已经查过了。不过我的问题是从实例,也就是只有HWND来获得CLSID,而不是从文件载入。
      

  11.   

    Public Function ProgIDToCLSID(ByVal ProgID As String) As String
        Dim GUID As GUID
        Dim CLSID As Long
        Dim StrOut As String * 255    CLSIDFromProgID StrPtr(ProgID), GUID
        StringFromCLSID GUID, CLSID
        If CLSID <> 0 Then
            StrFromPtrW CLSID, StrOut
            ProgIDToCLSID = Left(StrOut, InStr(StrOut, vbNullChar) - 1)
        End If
    End FunctionPrivate Sub StrFromPtrW(pOLESTR As Long, StrOut As String)
        Dim ByteArray(255) As Byte, i As Integer
        Dim intTemp As Integer, intCount As Integer
        
        intTemp = 1
        While intTemp <> 0
            CopyMemory intTemp, ByVal pOLESTR + i, 2
            ByteArray(intCount) = intTemp
            intCount = intCount + 1
            i = i + 2
        Wend
        CopyMemory ByVal StrOut, ByteArray(0), intCount
    End Sub
      

  12.   

    To:Modest(塞北雪貂)·(偶最欣赏楼主的分)谢谢您的热心肠。   一鞠躬~
      

  13.   

    楼主大人,我更关心另外一个问题,得到它的CLSID或PROGID后,如何动态创建它的实例呢?告诉我我会开贴给分!