开发基于网页的ActiveX控制


开发基于网页的ActiveX控制

以前工作的时候写过一个ActiveX控件,一直想将其用在网页上,但始终没有成功,今天无意中在MSDN上看到了《Using ActiveX Controls to Automate Your Web Pages》-http://msdn.microsoft.com/library/default.asp?url=/workshop/components/activex/tutorial.asp,似乎与之相关。此文中设计了一个基于Timer的时钟ActiveX控件并将其嵌入到web页面上。当然,本文的重点是在强调基于web页面的ActiveX控件的安全性问题。要使得安全的ActiveX控件在web页面上也安全的话,必须确保调用它的页面脚本(Script)也是安全的,即safe for initialization and/or scripting。要做到这后一点,有两种方法:

  1. 用Component Categories Manager 在系统的注册表中添加适当的entry,这样IE在加载ActiveX控件前就会先检查注册表上的Entry;
  2. 在控件中实现IObjectSafety接口,如果IE检测到ActiveX控件支持IObjectSafety接口,就会调用IObjectSafety::SetInterfaceSafetyOptions方法以判定该控件是否安全;

在第一种方法中,Component Categories Manager会在注册表中为每个组件包含一个Component Categories key ,并且每个key都有两个subkey,一个是CATID_SafeForScripting ,另一个是CATID_SafeForInitializing。创建subkey的方法是:

  1. Create an instance of the Component Categories Manager and retrieve the address of the ICatRegister interface.
  2. Set the appropriate members of a CATEGORYINFO structure.
  3. Call the ICatRegister::RegisterCategories method, passing the address of the initialized CATEGORYINFO structure.

将以下步骤写成一个函数CreateComponentCategory 如下:

#include "comcat.h"
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;
}
在创建了subkey以后,控件必须注册成为该类别(category),要做到这一点,必须:
  1. Create an instance of the Component Categories Manager and retrieve the address of  the ICatRegister interface.
  2. Call the ICatRegister::RegisterClassImplCategories method, passing the control's class identifier (CLSID) and the requisite category ID as arguments.

以上步骤写成以下函数(RegisterCLSIDInCategory ):

#include "comcat.h"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;

}

DllRegisterServer函数被调用时,控件应该调用以上两个函数,以实现safe for initilization
以及safe for scripting,示例如下:
STDAPI DllRegisterServer(void){    HRESULT  hr;    // return for safety functions    AFX_MANAGE_STATE(_afxModuleAddrThis);    if (!AfxOleRegisterTypeLib(AfxGetInstanceHandle(), _tlid))         return ResultFromScode(SELFREG_E_TYPELIB);    if (!COleObjectFactoryEx::UpdateRegistryAll(TRUE))        return ResultFromScode(SELFREG_E_CLASS);    // Mark the control as safe for initializing.    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;    return NOERROR;}
同上一样,也必须对类别进行unregister,相应的函数为:
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;}
在对应的DllUnRegisterServer中,也应该调用上面函数:
STDAPI DllUnregisterServer(void){    HRESULT hr;    // HResult used by Safety Functions    AFX_MANAGE_STATE(_afxModuleAddrThis);    if (!AfxOleUnregisterTypeLib(_tlid))         return ResultFromScode(SELFREG_E_TYPELIB);    if (!COleObjectFactoryEx::UpdateRegistryAll(FALSE))        return ResultFromScode(SELFREG_E_CLASS);    // Remove entries from the registry.    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForInitializing);    if (FAILED(hr))        return hr;    hr=UnRegisterCLSIDInCategory(CLSID_SafeItem, CATID_SafeForScripting);    if (FAILED(hr))        return hr;    return NOERROR;}
以上调用可以改为以下:
BOOL CONotesCtlCtrl::CONotesCtlCtrlFactory::UpdateRegistry(BOOL bRegister)
{
 // TODO: Verify that your control follows apartment-model threading rules.
 // Refer to MFC TechNote 64 for more information.
 // If your control does not conform to the apartment-model rules, then
 // you must modify the code below, changing the 6th parameter from
 // afxRegInsertable | afxRegApartmentThreading to afxRegInsertable.
 HRESULT hr;
 if (bRegister)
 {
        if(!AfxOleRegisterControlClass(
  AfxGetInstanceHandle(),
  m_clsid,
  m_lpszProgID,
  IDS_ONOTESCTL,
  IDB_ONOTESCTL,
  afxRegInsertable | afxRegApartmentThreading,
  _dwONotesCtlOleMisc,
  _tlid,
  _wVerMajor,
  _wVerMinor)) return FALSE;
   hr = CreateComponentCategory(CATID_SafeForScripting,L"Controls that are safely scriptable") ;
   hr = CreateComponentCategory (CATID_SafeForInitializing,L"Controls safely initializable from persistent data");
   
   hr = RegisterCLSIDInCategory (m_clsid, CATID_SafeForScripting) ;
   hr = RegisterCLSIDInCategory (m_clsid,CATID_SafeForInitializing);
   return TRUE;
 }
 else
 {
  if(!AfxOleUnregisterClass(m_clsid, m_lpszProgID))
   return FALSE;
  hr = UnRegisterCLSIDInCategory (m_clsid,CATID_SafeForScripting);
  hr = UnRegisterCLSIDInCategory (m_clsid,CATID_SafeForInitializing) ;
  return TRUE;
 }
}
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告