1. 程式人生 > >ActiveX控制元件實現安全的初始化和指令碼

ActiveX控制元件實現安全的初始化和指令碼

要想建立一個能夠在IE中成功載入而沒有“不安全”的警告或者錯誤提示資訊的ActiveX控制元件,我們必須實現安全的初始化和指令碼。基本上,所有要做的工作都是在DllRegisterServer 和DllUnregisterServer這兩個函式中完成的。下面,我們就來一步步地將我們的ActiveX控制元件變成一個“安全的”控制元件。

       1. 編輯XXX(此處為控制元件的工程名).cpp並新增如下的程式碼。其中,CLSID_SafeItem的值應該跟XXXCtrl.cpp中的IMPLEMENT_OLECREATE_EX一致,這就等同於你的ActiveX控制元件。同樣,它也應該跟你的HTML頁面中的OBJECT

ID標籤中的CLSID一致。

       以下是我工程中為實現安全的初始化和指令碼新增的程式碼,可以與原先IDE自動生成的部分做對比檢視那些部分是新增的,哪些部分是在建立ActiveX控制元件時自動生成的代碼:

[cpp] view plain copy  print?
  1. // CCEA.cpp : CCCEAApp 和 DLL 註冊的實現。
  2. #include "stdafx.h"
  3. #include "CCEA.h"
  4. #include "ComCat.h"
  5. #include "strsafe.h"
  6. #include "ObjSafe.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #endif
  10. CCCEAApp theApp;  
  11. /*const GUID CDECL BASED_CODE _tlid = 
  12.         { 0x5E5EBDFC, 0x6D73, 0x4652, { 0x85, 0x3, 0x3F, 0xBF, 0x94, 0x7A, 0xCA, 0xD5 } };*/
  13. const GUID CDECL BASED_CODE _tlid =  
  14.         { 0x1f7c5839, 0x4814, 0x4f2b, { 0xbd, 0x9e, 0x81, 0xd6, 0x2b, 0x59, 0x96, 0xaf } };  
  15. const
     GUID CDECL CLSID_SafeItem =  
  16.         { 0x6f82c754, 0x6c31, 0x43ea, { 0x98, 0x18, 0xe9, 0x5a, 0xd4, 0xe8, 0x72, 0xfc } };  
  17. constWORD _wVerMajor = 1;  
  18. constWORD _wVerMinor = 0;  
  19. // CCCEAApp::InitInstance - DLL 初始化
  20. BOOL CCCEAApp::InitInstance()  
  21. {  
  22.     BOOL bInit = COleControlModule::InitInstance();  
  23.     if (bInit)  
  24.     {  
  25.         // TODO: 在此新增您自己的模組初始化程式碼。
  26.     }  
  27.     return bInit;  
  28. }  
  29. // CCCEAApp::ExitInstance - DLL 終止
  30. int CCCEAApp::ExitInstance()  
  31. {  
  32.     // TODO: 在此新增您自己的模組終止程式碼。
  33.     return COleControlModule::ExitInstance();  
  34. }  
  35. //建立Component Categories中的初始化安全和指令碼安全項
  36. HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription)  
  37. {  
  38.     ICatRegister *pcr = NULL ;  
  39.     HRESULT hr = S_OK ;  
  40.     hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,   
  41.             NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);  
  42.     if (FAILED(hr))  
  43.         return hr;  
  44.     // 確認HKCR\Component Categories\{..catid...}鍵值被註冊
  45.     CATEGORYINFO catinfo;  
  46.     catinfo.catid = catid;  
  47.     catinfo.lcid = 0x0409; // english
  48.     //size_t len;
  49.     // 確認描述不是太長。
  50.     // 只複製開始的127個字元。
  51.     // StringCchLength的第二個引數表示被讀入catDescription的最大字元數。
  52.     // 第三個引數表示字串的長度
  53.     //hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
  54.     int len = wcslen(catDescription);  
  55.     if (SUCCEEDED(hr))  
  56.     {  
  57.         if (len>127)  
  58.         {  
  59.             len = 127;  
  60.         }  
  61.     }     
  62.     else
  63.     {  
  64.         // TODO: Write an error handler;
  65.     }  
  66.     wcsncpy(catinfo.szDescription, catDescription, len);  
  67.     //hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
  68.     // 新增字串結束符.
  69.     //catinfo.szDescription[len + 1] = '\0';
  70.     catinfo.szDescription[len] = '/0';  
  71.     hr = pcr->RegisterCategories(1, &catinfo);  
  72.     pcr->Release();  
  73.     return hr;  
  74. }  


       2. 然後需要添加註冊元件分類資訊

       同樣是在XXX(此處為控制元件的工程名).cpp並新增如下的程式碼:

[cpp] view plain copy  print?
  1. //在CLSID中建立與Component Categories中初始化安全和指令碼安全項中相對應的implemented Categories項
  2. HRESULT RegisterCLSIDInCategory(REFCLSID clsid, CATID catid)  
  3. {  
  4.     // 註冊元件分類資訊
  5.     ICatRegister *pcr = NULL ;  
  6.     HRESULT hr = S_OK ;  
  7.     hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,   
  8.                 NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);  
  9.     if (SUCCEEDED(hr))  
  10.     {  
  11.        CATID rgcatid[1] ;  
  12.        rgcatid[0] = catid;  
  13.        hr = pcr->RegisterClassImplCategories(clsid, 1, rgcatid);  
  14.     }  
  15.     if (pcr != NULL)  
  16.         pcr->Release();  
  17.     return hr;  
  18. }  
  19. //登出與CLSID中的相應implemented Categories項,一般用不到,因為其它程式可能也會用到這此項
  20. HRESULT UnRegisterCLSIDInCategory(REFCLSID clsid, CATID catid)  
  21. {  
  22.     ICatRegister *pcr = NULL ;  
  23.     HRESULT hr = S_OK ;  
  24.     hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr,   
  25.             NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister, (void**)&pcr);  
  26.     if (SUCCEEDED(hr))  
  27.     {  
  28.        CATID rgcatid[1] ;  
  29.        rgcatid[0] = catid;  
  30.        hr = pcr->UnRegisterClassImplCategories(clsid, 1, rgcatid);  
  31.     }  
  32.     if (pcr != NULL)  
  33.         pcr->Release();  
  34.     return hr;  
  35. }  


       這兩個方法是全新的必須新增。

       3. 需要修改DllRegisterServer函式如下,可以與原先IDE自動生成的部分做對比檢視需要增加的部分:

[cpp] view plain copy  print?