開篇語:最近在弄ocx控件發佈到asp.net網站上使用,就是用戶在使用過程當中,自動下載安裝ocx控件。(此文章也是總結了網上好多人寫的文章,我只是彙總一下,加上部分本身的東西,在這裏感謝全部在網上發表相關內容的朋友們。)html
ActiveX控件用於Web的過程是將控件嵌入主頁中,用戶經過瀏覽器訪問該主頁時,將主頁中的控件下載,並在用戶機器上註冊,之後就可在用戶的瀏覽器上運行。控件下載一次後就駐留在用戶本地機器上,下次再訪問相同的主頁時,可再也不下載該控件,而是直接運行用戶本地的控件。這裏控件容器就是瀏覽器,用戶不須要經過瀏覽器調用控件的屬性或方法。所以,開發面向Web的ActiveX控件比開發桌面的控件還要簡單些,所複雜的是如何將該控件很好地嵌入主頁,使用戶能正常瀏覽。下面介紹這個問題。 web
一. 建立MFC ActiveX項目算法
1. 打開VS2005新建MFC項目。這裏咱們取名爲「ActiveXDemo」。編程
2. 輸入項目名稱爲「ActiveXDemo」和項目位置。點擊「肯定」按鈕,打開向導對話框。windows
WoSign 免費提供的時間戳服務URL: http://timestamp.wosign.com/timestamp 後端
時間戳服務很是重要,添加時間戳後,即便您的代碼簽名證書已通過期,但因爲您的代碼是在證書有效期內簽名的,則時間戳服務保證了此代碼仍然可信,最終用戶仍然能夠放心下載,使得即便代碼簽名證書已通過期,您也無需重籤和從新發布已經簽名的代碼。瀏覽器
3. 選擇「控件設置」選項卡,具體設置可參考上圖。其它選項卡爲默認設置。最後點擊「完成」按鈕保存設置。安全
二. 添加控件方法服務器
VC2005會爲咱們自動建立好MFC ActiveX程序框架,咱們只要給該ActiveX控件添加方法便可。如今咱們給控件添加一個「AddFun」方法,這個方法是將兩個數相加並返回結果。app
1. 點擊「視圖」,打開「類視圖」窗口。
2. 展開「ActiveXDemoLib」項,選中「_DActiveXDemo」項。點擊鼠標右鍵,選擇「添加」下的「添加方法」。
3. 打開添加方法嚮導窗口。由於咱們是添加一個加法方法,因此咱們設置的返回類型爲LONG型,方法名設爲AddFun,添加兩個LONG類型參數Add1,Add2。
4. 其它爲默認設置,點擊「完成」按鈕完成添加方法。接下來咱們打開「解決方案資源管理器」打開「ActiveXDemoCtrl.cpp」文件。
5. 打開代碼視圖,咱們會發現VC2005已經爲咱們添加了一個「AddFun」方法,咱們在方法內添加「return Add1 + Add2;」語句。
3、MFC Activex 安全問題:
一、在默認環境下,編譯的MFC Activex控件,只能在本地代碼中運行,即在http://localhost/xxx/xxx.htm中執行,而在http://127.0.0.1/xxx/xxx.htm中提示無相關屬性,須要設置其初始化和腳本運行的安全性
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實現文件中包括兩個文件:
在ActivexDemo.cpp 文件中實現如下方法
代碼
#include "stdafx.h"
#include "ActivexDemo.h"
#include <comcat.h>
#include <objsafe.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
CActivexDemoApp theApp;
const GUID CDECL BASED_CODE _tlid =
{ 0x344B8576, 0xAB2C, 0x4D38, { 0xAE, 0x7, 0x73, 0x74, 0x22, 0x89, 0x72, 0xEA } };
const WORD _wVerMajor = 1;
const WORD _wVerMinor = 0;
// CActivexDemoApp::InitInstance - DLL 初始化
BOOL CActivexDemoApp::InitInstance()
{
BOOL bInit = COleControlModule::InitInstance();
if (bInit)
{
// TODO: 在此添加您本身的模塊初始化代碼。
}
return bInit;
}
// CActivexDemoApp::ExitInstance - DLL 終止
int CActivexDemoApp::ExitInstance()
{
// TODO: 在此添加您本身的模塊終止代碼。
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);