• 从tlb,ocx,dll类型库中提取com组件的CLSID


    最近在做项目的时候遇到了这个问题。

    项目需要动态根据添加com组件,获取组件的某个接口函数。

    一般情况下,我们创建com组件的方法是根据它的CLSID号,获得相应的interface,然后通过返回的指针调用相应的接口函数。如下:

    CoInitialize( NULL );
    IpTest* pMask = NULL;
    HRESULT hr = CoCreateInstance( CLSID_TEST, NULL, CLSCTX_INPROC, IID_ITEST, (LPVOID*)&IpTest );
    if( !SUCCEEDED(hr) )
    {
        AfxMessageBox( _T("com组件创建失败,请检查其是否安装并注册") );
        return 0;
    }
    IpTest->SomeFunc();//调用相应的接口函数
    IpTest->Release();
    CoUninitialize();

    现在项目要根据输入tlb文件获得对应com组件的CLSID,然后调用CoCreateInstance()函数,传给它刚刚读取的CLSID。

    百度,google了半天才找到了解决方案,特此记录下来。

    稍微简单封装成函数.

    #include <windows.h>
    #include <comdef.h>
    ITypeLib *pTypeLib = NULL;
    ITypeInfo *pTypeInfo = NULL;
    TYPEATTR *pTypeAttr = NULL;
    
    void Cleanup();
    GUID getCLSIDFromFile(const CString &strFileName)throw(std::runtime_error);
    
    //strFileName--输入tlb,ocx文件路径
    GUID getCLSIDFromFile(const CString &strFileName)throw(std::runtime_error)
    {
        _bstr_t str;
        HRESULT hr;
        TCHAR* pwszProgID = NULL;
        
        hr = LoadTypeLib(strFileName,&pTypeLib);//加载类型库信息
        if ( FAILED(hr)) 
        {
            Cleanup(); 
            return GUID();
        }
        UINT iCount = pTypeLib->GetTypeInfoCount(); //获取类型数量
        for (int i=0; i < iCount ; i++) 
        {
            if (FAILED(hr = (pTypeLib->GetTypeInfo(i, &pTypeInfo))))//获取类型说明信息
            {
                Cleanup();
                throw runtime_error("输入文件不包含相关com组件接口");
                return GUID();
            }
            if (FAILED(hr = (pTypeInfo->GetTypeAttr(&pTypeAttr))))//获取类型属性
            {
                Cleanup();
                throw runtime_error("输入文件不包含相关com组件接口");
                return GUID();
            }
            
            if (TKIND_COCLASS == pTypeAttr->typekind)//判断是否为组件接口
                return pTypeAttr->guid;
            pTypeInfo->ReleaseTypeAttr(pTypeAttr);
            pTypeInfo->Release();
    
        }
    
        pTypeLib->Release();
        pTypeLib = NULL;
        throw runtime_error("输入文件不包含相关com组件接口");
        return GUID();
    }
    
    void Cleanup()
    {
        if (pTypeAttr)
            pTypeInfo->ReleaseTypeAttr(pTypeAttr);
    
        if (pTypeInfo)
            pTypeInfo->Release();
        pTypeAttr = NULL;
        pTypeInfo = NULL;
    }

    使用的时候直接传入tlb,ocx,dll文件路径给getCLSIDFromFile()函数,函数返回值即对应com组件的CLSID;

    获得了组件的CLSID,就可以按照常规方法访问组件对应的接口了。

    当然如果知道了对应组件的ProgID,可以用

    HRESULT CLSIDFromProgID(
      LPCOLESTR lpszProgID,  //Pointer to the ProgID
      LPCLSID pclsid         //Pointer to the CLSID
    );
    传入对应ProgID字符串,返回相应CLSID;

    参考链接:http://support.microsoft.com/kb/286340/zh-cn

  • 相关阅读:
    tomcat log
    关于 终端 ls 命令 不能区分文件和目录的问题
    画幅
    透视
    焦距和等效焦距
    滚动条插件mCustomScrollbar
    网页优化总结
    CSS3中translate、transform和translation的区别和联系
    Less的学习和使用
    Koala工具的使用说明
  • 原文地址:https://www.cnblogs.com/sunbing/p/3880812.html
Copyright © 2020-2023  润新知