1.
ProgID是程序员给某个CLSID指定一个易记的名字。
组成:<program>.<component>.<version>
在HKey_Classes_Root下,有版本号的ProgID和无版本号的ProgID都有列出,一般无版本号的除了有CLSID子键外会还有CurVer子键来标明版本
2.
12.1.2 CLSID和ProgID相互转换
1.问题阐述
每一个COM组件都需要指定一个 CLSID,并且不能重名,CLSID表示使用一个具有16个字节的数字,每个CLSID都在系统的注册表中被注册,它表示组件的实际路径,保证了组件路径的透明性。在Localserver32中保存了组件的路径,如图12-1所示。
图12-1 组件的路径
如果使用ATL或者其他开发环境,会自动产生一个CLSID,用以标识组件,同时,组件的标识还支持字符串方式,就是ProgID。二者都可以用来标识,只是采用了不同的表示形式。
2.实现技巧
通过上面的分析,两者之间的转换,可以通过查询注册表达得到,还可以通过函数CLSIDFromProgID和ProgIDFromCLSID完成转换,函数原型如下:
HRESULT CLSIDFromProgID(
LPCOLESTR lpszProgID, // 指向ProgID的指针
LPCLSID pclsid // 指向CLSID的指针
);
WINOLEAPI ProgIDFromCLSID(
REFCLSID clsid, // CLSID 的值,已知
LPOLESTR * lplpszProgID // 指向接收ProgID的缓冲区
);
3.实例代码
本实例演示了CLSID和ProgID之间的相互转换。首先创建一个简单的组件,然后利用一个调用者程序进行二者之间的转换。
(1)建立一个ATL工程Object,选择DLL方式,如图12-2所示。
Allow merging of proxy/stub code、Support MFC和Support MTS为默认即可。
(2)添加ATL类对象Cfun,设置其类对象的属性如图12-3所示。
图12-2 组件创建
图12-3 组件创建
从图12-3可以知道ProgID = OBJECT.Fun,默认为工程名+ShortName,单击Attributes选项卡,如图12-4所示。
图12-4 组件属性配置
这样,一个简单的COM组件就做好了,这个组件,没有任何功能实现。从这个COM组件中找出它的 CLSID,查看idl文件。其中86A70E6F-3F1C-46B5-86F9-C21DAD69C756为CLSID。
下面写一个函数,完成CLSID和ProgID的转换。
CLSID clsid = {0x86A70E6F,0x3F1C,0x46B5,{0x86,0xF9,0xC2,0x1D,
0xAD,0x69,0xC7,0x56}};
CString strClsID;
strClsID.Format("%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x",clsid.Data1,
clsid.Data2,clsid.Data3,clsid.Data4[0],clsid.Data4[1],clsid.Data4[2],
clsid.Data4[3],clsid.Data4[4],clsid.Data4[5],clsid.Data4[6],
clsid.Data4[7]);
SetDlgItemText(IDC_CLSID_ED,strClsID);
HRESULT hr;
LPOLESTR lpwProgID = NULL;
hr = ::ProgIDFromCLSID( clsid, &lpwProgID );
if ( SUCCEEDED(hr) )
{
//::MessageBoxW( NULL, lpwProgID, L"ProgID", MB_OK );
USES_CONVERSION;
LPCTSTR lpstr = OLE2CT( lpwProgID );
SetDlgItemText(IDC_PROGID_ED,lpstr);
IMalloc * pMalloc = NULL;
hr = ::CoGetMalloc( 1, &pMalloc ); // 取得 IMalloc
if ( SUCCEEDED(hr) )
{
pMalloc->Free( lpwProgID ); // 释放ProgID内存
pMalloc->Release(); // 释放IMalloc
}
}
其中OLE2CT完成了LPCOLESTR到LPCTSTR的转换,运行结果如图12-5所示。
图12-5 CLSID 转换为ProgID