ActiveX控件在IE中不能显示的解决方案

Q:

 

VC6生成MFC ActiveX,使用htm调用,

CLASSID="CLSID:12342234-3234-4234-5234-623472348234"

CODEBASE="testocx.cab#version=1,0,0,1"

在WinXPSp1上,http://www.smth.org/,ok

在WinXPSp2/2k3SP1/Vista上,http://www.smth.org/,红X

在WinXPSp2/2k3SP1/Vista上,file:///C:/ActiveX.htm,ok

A:

ActiveX在远程IE页面上执行,需要实现安全接口。

在ATL写的ActiveX中,用IObjectSafety。

http://support.microsoft.com/kb/168371/en-us

在MFC写的ActiveX中,直接修改注册表。

http://support.microsoft.com/kb/161873/en-us

mfc实现的ocx,要在app实现文件中包括两个文件:

#include <comcat.h> 
#include <objsafe.h> 
// 本控件的CLSID,注册表用 
const GUID CDECL CLSID_SafeItem ={ 0x12342234, 0x3234, 0x4234, 
                      { 0x52,0x34,0x62,0x34,0x72,0x34,0x82,0x34 } }; 
// 版本控制 
const WORD _wVerMajor = 1; 
// 次版本号 
const WORD _wVerMinor = 0; 
实现 
// CTestApp::InitInstance - DLL initialization 
BOOL CTestApp::InitInstance() { 
    return COleControlModule::InitInstance(); 
} 
// CTestApp::ExitInstance - DLL termination 
int CTestApp::ExitInstance() { 
    return COleControlModule::ExitInstance(); 
} 
// 创建组件种类 
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 
    // Make sure the provided description is not too long. 
    // Only copy the first 127 characters if it is. 
    int len = wcslen(catDescription); 
    if (len>127) len = 127; 
    wcsncpy(catinfo.szDescription, catDescription, len); 
    // Make sure the description is null terminated. 
    catinfo.szDescription[len] = ’\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; 
} 
// DllRegisterServer - Adds entries to the system registry 
STDAPI DllRegisterServer(void) { 
    HRESULT hr; 
    AFX_MANAGE_STATE(_afxModuleAddrThis); 
    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid)) 
        return ResultFromScode(SELFREG_E_TYPELIB); 
    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE)) 
        return ResultFromScode(SELFREG_E_CLASS); 
    // 标记控件初始化安全. 
    // 创建初始化安全组件种类 
    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; 
    // 标记控件脚本安全 
    // 创建脚本安全组件种类 
    hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!"); 
    if (FAILED(hr)) return hr; 
    // 注册脚本安全组件种类 
    hr = RegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); 
    if (FAILED(hr)) return hr; 
    return NOERROR; 
} 
// DllUnregisterServer - Removes entries from the system registry 
STDAPI DllUnregisterServer(void) { 
    HRESULT hr; 
    AFX_MANAGE_STATE(_afxModuleAddrThis); 
    if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor)) 
        return ResultFromScode(SELFREG_E_TYPELIB); 
    if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE)) 
        return ResultFromScode(SELFREG_E_CLASS); 
    // 删除控件初始化安全入口. 
    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing); 
    if (FAILED(hr)) return hr; 
    // 删除控件脚本安全入口 
    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting); 
    if (FAILED(hr)) return hr; 
    return NOERROR; 
} 

 

atl实现的ocx,在声明文件CTestCtl.h中:

class CTestCtl : 
    .... , 
    public IObjectSafetyImpl<CTestCtl, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA> 
{ 
... 
BEGIN_COM_MAP(CTestCtl) 
COM_INTERFACE_ENTRY(IObjectSafety) 
END_COM_MAP() 
... 
} 

 

或者:

BEGIN_CATEGORY_MAP(CTestCtl)    
IMPLEMENTED_CATEGORY(CATID_SafeForInitializing)    
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)    
END_CATEGORY_MAP()

 

你可能感兴趣的:(Microsoft,IE,脚本,mfc)