VC2005從開發MFC ActiveX ocx控件到發佈到.net網站的所有過程

開篇語:最近在弄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 =
        { 0x344B85760xAB2C0x4D38, { 0xAE0x70x730x740x220x890x720xEA } };
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);    
    }    
    if (pcr != NULL) pcr->Release();    
    return hr;    
}    
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(BASED_CODE _tlid , CATID_SafeForInitializing);    
    if (FAILED(hr)) return hr;    
    // 標記控件腳本安全    
    // 建立腳本安全組件種類    
    hr = CreateComponentCategory(CATID_SafeForScripting, L"Controls safely scriptable!");    
    if (FAILED(hr)) return hr;    
    // 註冊腳本安全組件種類    
    hr = RegisterCLSIDInCategory(BASED_CODE _tlid , 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(BASED_CODE _tlid , CATID_SafeForInitializing);    
    if (FAILED(hr)) return hr;    
    // 刪除控件腳本安全入口    
    hr=UnRegisterCLSIDInCategory(BASED_CODE _tlid , CATID_SafeForScripting);    
    if (FAILED(hr)) return hr;    
    return NOERROR;    
}  

 

 

 

如今控件就能夠在自注冊時就註冊爲安全控件了。

 

二、設置項目屬性 將配置類型設置成靜態庫(.lib)

 

 

 

 

三、       最後生成項目,ocx控件就產生了。 

 

 

 

 ActiveX打包與發佈

 

在VS2005或VS2008安裝後發現路徑**VC7\Common7\Tools\Bin\下有許多小工具,我對帶有Cert的文件比較感興趣。通過研究,發現是有關證書和簽名的,固然,該證書未被證書認證機構承認。下面列出這些工具和個人使用心得。
1。Makecert.exe ---證書建立工具
2。Cert2Spc.exe ---發行者證書測試工具
3。Signcode.exe ---文件簽名工具(VS2008帶的是signtool)

 


1、ActiveX發佈步驟

 

在這裏簡單說明下,打包activeX須要製做證書,具體用到makecert 、cert2spc 、signtool 這三個VS提供的工具,工具在VS文件夾裏面,如下製做過程須要在工具所在的文件夾下完成!
一、單擊"開始"-->"運行(R)"-->輸入"cmd"-->回車-->進入到操做的控件所在的目錄(須要將上面所說的工具,和ocx控件放到一個文件夾下);
二、建立PVK文件(私人密匙文件),在命令行中輸入"makecert -sk demo demo.pvk -n CN=XXXXXXX公司",而後回車;

 

sk-表示主題的密鑰容器位置,ss-主題的證書存儲名稱, n-證書頒發對象,r-證書存儲位置;

 

三、建立CER文件(公司證書),在命令行中輸入"makecert -sk demo.pvk demo.cer",而後回車,如圖8所示,若出現"Successed"提示,則會在E:\ demo目錄下生成demo.cer文件;

 

sk-表示主題的密鑰容器位置,is-頒發者的證書存儲名稱, n-證書頒發對象,ic-頒發者的證書存儲位置,-$-受權範圍(用於代碼簽名);

 

四、建立SPC測試軟件出版商證實書,在命令行中輸入"cert2spc demo.cer demo.spc",而後回車;

 

五、建立INF文件,用記錄本編輯如下信息:

 

 

 

 

 

代碼
[version]    

signature="$CHICAGO$"

AdvancedINF=2.0

[Add.Code]

ActivexDemo.ocx=ActivexDemo.ocx

[ActivexDemo.ocx]

file-win32-x86=thiscab    
//告訴ie到哪裏去獲得這個dll,file一共包括三個部分,第一部分是file,這個永遠都是這樣的(至少目前來講);第二部分告訴聲明支持的OS,win32表示windows,mac就是蘋果MAC  OX了;第三部分是CPU類型,好比說x8六、  ppc  (Power  PC)、  mips或者alpha了   
//其中「thiscab」是一個關鍵字,表示 CAB 包含此 DLL,也可經過指定一條絕對或相對路徑,從一個 HTTP 位置下載所需的 DLL,   
例如:  file-win32-x86=http://www.mysite.com/mydir/NEEDED.DLL   
RegisterServer=yes    

clsid={468E4531-F890-47EC-8368-3BDA4448FF08}    
//「clsid」是將要安裝的控件的 CLSID  
DestDir=11    
//它的值是dll將要存到本地硬盤的位置,若是它的值是10,則將dll放到\Windows或者\WinNT下;若是是11,則放到\Windows\System或者\WinNT\System32下;若是未指定任何 DestDir(典型狀況),則代碼安裝在固定的 OCCACHE 目錄中。  
FileVersion=1,0,0,1
//說明了atl90.dll的版本號   

 

  

 

六、建立CAB文件,在命令行中輸入"cabarc -s 6144 n demo.cab atl90.dll Polygon.dll demo.inf",-s 選項表示在壓縮文件中保留用於代碼簽名的空間,n命令指定但願建立 CAB 文件,而後回車;

 

七、使用Code Signing Wizard簽署一個CAB文件,在控制檯輸入signtool signwizard 進入到signtool窗體中;

 

 

八、單擊"下一步(N)"按鈕,選擇要進行數字簽名的且已作成CAB包的文件Dome.cab文件;

 

 

九、選擇好CAB包後單擊"下一步(N)"按鈕,在選擇想要的簽名類型裏選擇"自定議(C)"並單擊"下一步(N)"按鈕;

 

 

十、接下來單擊"從文件選擇(F)"按鈕,選擇剛剛製做的demo.cer;

 

 

十一、在單擊"下一步(N)",而後選擇"CSP中的私鑰(K)";

 

 

十二、在單擊「下一步(

N)」按鈕,而後在散列算法中選擇「shal」,並單擊「下一步(

N)」按鈕。

 

 

1三、在"證書路徑中的證書"中選擇"證書路徑中的全部證書,包括根證書(C)",在"其它證書(可選)"中選擇"包括在如下PKCS #7 證書(.p7b)文件中的證書(P):",並單擊"瀏覽(R)..."按鈕選擇demo.spc文件,選擇完後單擊"下一步(N)"按鈕;

 

 

1四、接下來在彈出的"數據描述"窗口中輸入公司的名稱和網址並單擊"下一步(N)"按鈕;

 

 

1五、現大部份工做都已完成,在接下來的一步當中是可選的操做,其做用只是爲CAB加入時間戳,此步驟徹底能夠不作,VeriSign:  http://timestamp.verisign.com/scripts/timstamp.dll

 

 

1六、完成,單擊"下一步(N)"按鈕即可來到數字簽名嚮導的最後一步,即操做總覽,如圖26所示,單擊"完成"按鈕即可大功告成;

 

 

 

 

 

下面是微軟代碼簽名證書(.pvk/.spc)簽名指南的演示

 

 

 

 

 

本使用指南演示如何使用WoSign代碼簽名證書來給微軟代碼簽名,Thawte和VeriSign代碼簽名證書也是使用一樣方法,只是使用不一樣的時間戳URL。

 

     用戶在在線申請代碼簽名證書時會生成證書私鑰文件,如:myCert.pvk,而代碼簽名證書成功頒發後的證書文件爲公鑰文件,如:myCert.spc,又稱:軟件發行證書(Software Publishing Certificate) 。 代碼簽名證書通常都是採用公鑰和私鑰分離的兩個文件方式,適合於 DOS 命令行方式的代碼簽名。若是您您但願把代碼簽名證書導入到Windows證書存儲區中,從而簡化簽名操做,請參考:不一樣證書格式轉換指南

 

     WoSign代碼簽名證書的根證書鏈爲: UTN-USERFirst-Object - WoSign Code Signing Authority

 

    使用微軟的 SignCode.exe 就能夠對微軟的代碼進行簽名,若是您沒有此文件,點擊 這裏 下載。 Signcode.exe 可使用 DOS 命令行方式實現簽名,咱們推薦用戶使用數字簽名嚮導方式,簡單方便。請注意:若是您開發的ActiveX爲IE加載項,請先數字簽名每一個CAB文件中的.dll和.ocx等文件,再把這些文件打包成.cab文件後再數字簽名.cab文件,以確保全部IE加載項都被IE驗證和信任,不然會顯示「未驗證」而可能影響正常運行。

 

    具體簽名嚮導過程以下:

 

     (1) 運行 Signcode.exe , 要求您選擇須要簽名的文件,支持:可執行文件 (*.exe; *.dll; *.ocx) ; Cabinet 打包文件 (*.cab) 和目錄文件 (*.cat) ,以下圖 1 所示 ( 如: TestSign.cab) ,請注意:若是簽名的文件已經有數字簽名,則會被新的簽名覆蓋:

 

 

 

 

(2) 點擊「下一步」後,以下圖 2 所示,會要求您選擇「簽名類型」,缺省的「典型」簽名類型;請選擇「自定義」 簽名類型:

 

 

 

 

 (3) 以下圖 3 所示,點擊「從文件選擇」簽名證書 ( 公鑰文件 ),如: WotoneCS.spc :

 

 

 

 

   (4) 點擊「下一步」後,以下圖 4 所示,會要求您選擇私鑰文件,如: WotoneCS.pvk ,其餘參數不用動:

 

 

 

 

  (5) 點擊「下一步」後,以下圖 5 所示,會提示要求輸入私鑰密碼:

 

 

 

 

   (6) 點擊「下一步」後,以下圖 6 所示,會提示要求選擇散列算法 ( 摘要算法、縮微圖算法 ) ,缺省爲 sha1 ,也能夠選 md5 :

 

 

 

 

(7) 點擊「下一步」後,以下圖 7 所示,選擇哪些證書包括到數字簽名中,直接點擊「下一步」便可,即選擇缺省的包括根證書:

 

 

 

 

(8) 以下圖 8 所示,要求填寫該簽名代碼的功能描述,推薦必定要認真填寫,由於此信息將會在最終用戶下載此代碼時顯示,有助於最終用戶瞭解此代碼的功能以肯定是否下載安裝。第一行「描述」是指此代碼的功能文字描述,第二行「 Web 位置」則讓最終用戶點擊文字描述來詳細瞭解此代碼的功能和使用方法等,本演示中的「 Web 位置」爲WoTrust代碼簽名證書簡介頁面:

 

 

 

 

 (9) 點擊「下一步」後,以下圖 9 所示,選中「將時間戳添加到數據中」,請使用:

 

 

 

 

WoSign 免費提供的時間戳服務URL: http://timestamp.wosign.com/timestamp

 

     時間戳服務很是重要,添加時間戳後,即便您的代碼簽名證書已通過期,但因爲您的代碼是在證書有效期內簽名的,則時間戳服務保證了此代碼仍然可信,最終用戶仍然能夠放心下載,使得即便代碼簽名證書已通過期,您也無需重籤和從新發布已經簽名的代碼。

 

 

(10) 點擊「下一步」後,以下圖 10 所示,會提示已經完成數字簽名嚮導,點擊「完成」後還會提示您輸入私鑰密碼,就完成代碼簽名證書的代碼簽名。

 

 

(11) 如今,須要使用 chktrust.exe 來查驗已經簽名的代碼, chktrust.exe 文件已經打包在 signtool.rar 中。進入 DOS 命令提示符,並進入已經簽名的文件所在目錄 ( 如: d:\sign\TestCA.cab) ,鍵入命令: chktrust testcs.cab ,則會顯示實際應用時在 IE 瀏覽器下載頁面的狀況,以下圖 11 所示,對於Win XP操做系統,會顯示軟件名稱和發行者名稱,其中軟件名稱就是您在第(8)步輸入的描述,點擊此名稱就連接到您在第(8)步填寫的網址,而點擊發行者名稱,則會顯示您的簽名信息和時間戳信息。對於Win2000操做系統,則稍有不一樣,第 1 行的紅線部分就是時間戳記錄的簽名時的本地時間,請注意:此時間不是取簽名電腦的時間,而是提供時間戳服務的服務器計算出來的簽名電腦設置的所在時區的本地時間。第 1 行藍色文字就是在第 8 步中輸入的描述文字,點擊此藍色文字就能夠訪問在第 8 步中輸入的 Web 描述頁面。第 2 行藍色文字則爲該代碼的發行者,也就是代碼簽名證書的申請者(擁有者)( 如:深圳市沃通電子商務服務有限公司) ,點擊能夠查看證書的詳細信息;第 2 行有紅色下劃線部分顯示「發行商可靠性由 WoSign Code Signing Authority 驗證 」就是此代碼簽名證書的證書頒發者。

 

 

12) 點擊「是」或「運行」,則會提示「 TestSign.cab: Succeeded 」表示代碼 TestSign.cab 簽名驗證有效,能夠放到網站上了。請注意:簽名後的CAB文件放到網站上須要使用 object 方式。

 

請注意:不能僅簽名CAB文件,CAB包中全部DLL文件都要先簽名後再打包,再簽名CAB文件,不然IE瀏覽器會顯示爲「未驗證的發行者」而影響正常使用,甚至殺毒軟件會認爲是毒而被刪除!以下圖所示的實際案例:

 

 

 

 

 

 

 

在Web頁中加入ActiveX 控件

 

在修改了IE的安全設置後,依然不能調用控件的方法,須要將訪問的站點設置爲「受信站點」,則方能正常使用控件
在<html> 和<head>之間插入
<!-- saved from url=(0017)http://localhost/ -->
則在IE窗口上方不會彈出黃色提示條 。

 

  

在HTML頁面中使用ActiveX控件包含三個基本操做:將控件放入HTML中;將該控件下載給用戶;在用戶機器上安裝該控件。若是隻是針對IE用戶,在HTML中插入ActiveX控件就比較簡單;若是同時兼顧IE和Netscape用戶,則要作更多工做。你們知道,HTML文件由文本和各類標誌(tags)組成,ActiveX 控件對於IE在HTML中的標誌是<OBJECT>,該標記有幾個重要的參數特性,它們是:

 

 

  1.ID:爲控件提供一個標識名稱,爲HTML代碼提供一種訪問該控件的方式。

 

 

  2.CLASSID:是該控件惟一的UUID,告訴IE裝入哪一個對象。若是使用已經開發好的控件,它的CLASSID能夠經過調用Win95或NT下的應用Regedit來查找。從開始菜單中運行該程序,展開HKEY_CLASSES_ROOT項,能夠看到按字母順序排列的註冊表,找到須要使用的控件名,例如WClnt,展開時可看到一個CLSID文件夾,裏面就是該控件的CLASSID。

 

 

  若是是本身用VC開發控件,該UUID能夠在ActiveX控件項目中的ODL(對象描述庫)文件中找到;經過查看控件的類信息註釋來定位特定控件的UUID,例如,要找到CMyControl控件的UUID,則須要找到如下代碼:

 

 

  // Class information for CMyControl

 

 

  [uuid (051C4748-1262-11D2-87C1-00A024D948FB),

 

 

  licensed,

 

 

  helpstring(「CmyControl Control」), control ]

 

 

  uuid後面括號中的內容就是該控件的UUID。

 

 

  3.CODEBASE:若是在用戶機器上沒有控件的當前版本,該參數告訴用戶瀏覽器在哪裏可找到要下載的控件和最新版本號.當控件做了修改後,能夠更改版本號強制用戶從新下載。

 

 

  4.PARAM:該標記用於設置控件的初始屬性值,它有兩個特性:Name和Value,即屬性名稱和屬性值。

 

 

  此外還有一些標記,如:Width表示該控件所佔的寬度,Height表示高度等,整體來講,這樣一個插入控件的HTML代碼和插入Java Applet的HTML代碼很是類似。

 

 

  下面是一個嵌有ActiveX控件的HTML代碼示例:

 

 

 

 

 

ID=「CMyControl」

 

 

CLASSID=「clsid:051C4748-1262-11D2-87C1-00A024D948FB 」

 

 

CODEBASE=「http://www.mysite.com.cn/ocxdir/mycontrol.ocx#version=1,0,0,1」

 

 

WIDTH=400

 

 

HEIGHT=200

 

 

ALIGN=center

 

 

HSPACE=0

 

 

VSPACE=0

 

 

 

 

  若是但願控件還能在Netscape中運行,除了Netscape需加裝插件外,HTML也要加一些附加標記,下面的例子中EMBED段就是爲Netscape加上的。若是使用MFC開發OCX控件,則少數用戶第一次訪問時除了下載OCX文件外,還要下載相應的MFC DLL,下載量變大,這時可將相關文件在服務器端打包成能夠在客戶端自解壓安裝的CAB文件。通過修改後的HTML代碼段以下:

 

 

<ALIGN=「CENTER」 CLASSID=「clsid:

 

 

7BCA18C6-2178-11D2-87C1-00A024D948FB」

 

 

WIDTH=「1200」 HEIGHT=「900」 ID=「marquee」

 

 

CODEBASE=「http://218.168.188.188/scadaweb/

 

 

WClnt.cab#version=1,0,0,1」>

 

 

<EMBED ALIGN=「CENTER」CLASSID=「clsid:7BCA18C6- 2178-11D2-87C1-00A024D948FB」

 

 

WIDTH=「1200」 HEIGHT=「900」 ID=「marqueequot;」

 

 

CODEBASE=「http://218.168.188.188/scadaweb/

 

 

WClnt.OCX#version=1,0,0,1」

 

 

TYPE=「application/oleobject」 >

 

 

 

 

 

 

 

 

 

 

實時動態頁面的實現方案

 

 

  對實時動態頁面的要求多產生於一些要求自動更新實時數據的應用中,如電網監控、股市監測等。具體要求是:用戶只需選取但願瀏覽的圖表,但無需介入操做,該圖表就能根據實時數據不斷更新,用戶總能觀察到最新狀況。

 

 

  要實現上述功能,結構上有兩種方案:一種是設置一箇中介服務器,該服務器做爲控件和後臺系統信息交流的中介;另外一種是不設中介服務器,但在提供實時數據的後臺服務器上留出供控件通訊用的數據接口,控件能夠直接從後臺服務器上定時得到當前實時數據。按數據提供方式分也有兩種:一種是由客戶端定時向服務器發出請求,指明須要的實時數據,服務器收到請求後將知足請求的動態數據發送至相應客戶;另外一種是客戶端只請求一次,服務器端便定時將知足請求的實時數據傳到客戶端,直到客戶更換要顯示的圖表或中止刷新。上述各方案都有其優勢和侷限,在應用中可考慮實際狀況採用相應方案。

 

 

  工做流程爲:用戶先從Web服務器上下載包含ActiveX 控件的網頁,控件隨即在客戶機上註冊運行,並經過Winsock同中介服務器或直接同提供實時信息的網,如股票信息網相鏈接,定時取得動態實時數據,並刷新顯示。在這個體系中,客戶有兩條線路得到信息,一條是和Web Server的鏈接,從這條線上用戶訪問主頁;另外一條就是控件和後臺信息網的鏈接,從這條線路上用戶能夠訪問實時數據。後一條線路用Winsock創建,傳輸速度遠大於前一條線路,且控制靈活、效率高,不和主頁下載爭資源。經過這條線路,用戶甚至能夠傳送遠程控制信息實現遙控操做。

 

 

利用MFC開發ActiveX控件

 

 

  利用VC5.0開發的這種控件,功能可擴展性強,理論上獨立的VC5.0程序具備的功能,該控件都能實現,例如控件直接繪製瀏覽器,可使用OpenGL等圖庫,圖形圖像功能強大。實時數據刷新頻率理論上可達毫秒級,用戶經過鼠標能夠實現各種交互操做,如旋轉、縮放,圖2就是一幅GL圖形,並有一個縮放工具條進行縮放操做。若是是在計算機上觀看,能夠看到這幾個三維圖在不斷旋轉。

 

 

  應該說,較好的開發工具可直接用API編程或使用ATL模板庫,利用MFC開發ActiveX控件不是一個好的選擇,由於控件運行須要MFC DLL的支持。假如客戶機器上沒有這些類庫(這種狀況不多,但確實存在),第一次下載就要花費些工夫。不過對於熟悉MFC的開發員來講,這些問題相對MFC提供的便利來講都是能夠忽略的。

 

 

  因爲VC5.0對ActiveX控件的開發提供了許多便利,因此開發一個ActiveX控件並不像許多人想象中的那麼困難複雜,經過VC 5.0的AppWizard,實現控件的主類從ColeControl類派生出來,該類則是CWnd的一個子類,因此你能夠像對窗口類編程同樣對這個主類編程。爲了實現上面說起的功能,首先必要重載它的OnDraw函數加入須要繪製的對象,加入Winsock類(CSocket或CAsyncSocket),以實現與後端數據服務器的通訊。若是須要用OpenGL繪製豐富多彩的立體圖,則要初始化GL環境。其餘的工做就在於用戶如何控制程序的調度,使得各功能都能正常工做且與其餘部分正常通訊。此外,後端服務器程序也要增長對應於該控件的接口。

 

 

  這樣的一個程序編譯經過後,就成爲一個可用於Web的控件,後綴名是OCX。按照前面敘述的方法將該OCX置入主頁,基本的工做就算完成。

 

 

  綜上所述,利用VC5.0開發ActiveX控件用於Web瀏覽,主要有如下幾個特色:

 

 

  1.採用Winsock的通訊機制,速度快、控制靈活、效率高;

 

 

  2.控件採用VC5.0編制,功能可擴展性很強;

 

 

  4.控件第一次下載雖然稍費時間,但下載後即在用戶機上註冊,之後可直接調用,速度效率均好;

 

 

  5.ActiveX技術是微軟發展的重中之重,且已成爲當前軟件發展的潮流所向,發展空間廣闊;

 

 

  6.系統採用VC開發,能夠利用已有的採用C語言編制的系統,開發工做量大大減小。

 

 

 

 

  Web頁面的開發主要分爲三類:靜態Web頁面、半動態Web頁面以及Client端動態頁面。本文重點論述基於ActiveX Control(控件)動態實時頁面的開發。

 

regsvr32 netshare.ocx        註冊netshare.ocx控件

 

regsvr32 /u netshare.ocx    解除netshare.ocx控件的註冊

相關文章
相關標籤/搜索