工作中写了一个MFC ActiveX,测试的时候,发现IE6和IE8修改了安全设置后能够正常运行,IE7和别的浏览器则始终无法正常运行,经过多方查找,发现缺少一些安全信息注册,添加下列代码后能够正常运行了。
首先定义三个函数:

HRESULT CreateComponentCategory(CATID catid, WCHAR *catDescription)

{

ICatRegister *pcr = NULL ;

HRESULT hr = S_OK ;

hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,

NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (
void**)&pcr);
if (FAILED(hr))
return hr;
// Make sure the HKCR/Component Categories/{..catid
}
// key is registered.

CATEGORYINFO catinfo;

catinfo.catid = catid;

catinfo.lcid = 0x0409 ;
// english

size_t len;
// Make sure the provided description is not too long.
// Only copy the first 127 characters if it is.
// The second parameter of StringCchLength is the maximum
// number of characters that may be read into catDescription.
// There must be room for a NULL-terminator. The third parameter
// contains the number of characters excluding the NULL-terminator.

hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
if (SUCCEEDED(hr))

{
if (len>127)

{

len = 127;

}

}
else 
{
// TODO: Write an error handler;

}
// The second parameter of StringCchCopy is 128 because you need
// room for a NULL-terminator.

hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
// Make sure the description is null terminated.

catinfo.szDescription[len + 1] = '/0';

hr = pcr->RegisterCategories(1, &catinfo);

pcr->Release();
return hr;

}



HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)

{
// Register your component categories information.

ICatRegister *pcr = NULL ;

HRESULT hr = S_OK ;

hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,

NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (
void**)&pcr);
if (SUCCEEDED(hr))

{
// Register this category as being "implemented" by the class.

CATID rgcatid[1] ;

rgcatid[0] = catid;

hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);

}
if (pcr != NULL)

pcr->Release();
return hr;

}

HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)

{

ICatRegister *pcr = NULL ;

HRESULT hr = S_OK ;

hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,

NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (
void**)&pcr);
if (SUCCEEDED(hr))

{
// Unregister this category as being "implemented" by the class.

CATID rgcatid[1] ;

rgcatid[0] = catid;

hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);

}
if (pcr != NULL)

pcr->Release();
return hr;

}
然后在STDAPI DllRegisterServer(void)和STDAPI DllUnregisterServer(void)中添加下列代码:
STDAPI DllRegisterServer(void)中:

HRESULT hr;

hr = CreateComponentCategory(CATID_SafeForInitializing,

L"Controls safely initializable from persistent data!");
if (FAILED(hr))
return hr;

hr = RegisterCLSIDInCategory(CLSID_SafeItem,

CATID_SafeForInitializing);
if (FAILED(hr))
return hr;
// Mark the control as safe for scripting.

hr = CreateComponentCategory(CATID_SafeForScripting,

L"Controls safely scriptable!");
if (FAILED(hr))
return hr;

hr = RegisterCLSIDInCategory(CLSID_SafeItem,

CATID_SafeForScripting);
if (FAILED(hr))
return hr;
STDAPI DllUnregisterServer(void)中:

HRESULT hr;

hr=UnRegisterCLSIDInCategory(CLSID_SafeItem,

CATID_SafeForInitializing);
if (FAILED(hr))
return hr;

hr=UnRegisterCLSIDInCategory(CLSID_SafeItem,

CATID_SafeForScripting);
if (FAILED(hr))
return hr;
其中CLSID_SafeItem就是就是浏览器中使用的clsid。