一個完善的ActiveX Web控件教程


免費打工仔:一個完善的ActiveX Web控件教程

出自Ogre3D開放資源地帶

 
跳轉到:  導航搜索

原作者 David Marcionek.

翻譯 免費打工仔

這個教程可以幫助你快速開發一個ActiveX控件。其中將要講解關於ActiveX開發的一些基礎概念,諸如方法(method)、屬性(propertiy)和事件(event),以及ActiveX控件和網頁之間的通訊方法。

下載演示程序 - 231 Kb

 

 

目錄

[隱藏]

介紹

http://www.codeproject.com/com/CompleteActiveX/MyActiveX.jpg

 

ActiveX是微軟九十年代中期開發的一種技術,它允許你創建一個類似applet的應用程序,並允許你在微軟的瀏覽器中下載和運行。這篇教程的閱讀對象是那些希望使用Visuall C++開發第一個ActiveX程序但卻不知道如何下手的人。當我自己嘗試學習這種技術的時候,我發現關於ActiveX技術使用的信息大部分都沒什么用處,是太老了或者缺失一些關鍵的信息。這讓我建立一個可用ActiveX控件工程的過程困難重重。我寫這篇文章的用意就是幫助你快速的建立一個ActiveX控件。其中將要講解關於ActiveX開發的一些基礎概念,諸如方法(method)、屬性(propertiy)和事件(event),以及ActiveX控件和網頁之間的通訊方法。並將要學習如何再Windows XP系統中的IE瀏覽器默認的安全設置中無警告的執行這個控件。


在這個指南中,我們將要創建一個ActiveX控件用來顯示一個GIF動畫表現的進度條,用來表示這個控件的載入和執行信息。這個控件的功能將會展示如何在網頁和控件之間的信息。我們將會指導你如何使用微軟Visual Studio 2005中一步一步的創建這個控件。

創建一個ActiveX控件

為了創建一個ActiveX控件,需要對微軟Visual Studio 2005執行以下步驟:

 

  • 1.選擇文件\新建\項目
  • 2.打開如圖1一樣的對話框,選擇Visual C++,MFC。在右面模板對話框中選擇MFC ActiveX控件。
  • 3.在名稱中輸入MyActiveX;在位置中輸入你需要代碼工程放置的硬盤位置,之后選擇確定。

http://www.codeproject.com/com/CompleteActiveX/image002.jpg

圖1.新建項目對話框

  • 4.在MFC ActiveX控件向導對話框中(如圖2所示),選擇控件設置
  • 5.在創建的控件基於下拉菜單中選擇STATIC。我們使用了一個靜態的控件,我們只是簡單的輸出結果,並不需要接受輸入信息。
  • 6.在附加功能中,確定可見時激活無閃爍激活兩項被激活,其它的都被關閉。

http://www.codeproject.com/com/CompleteActiveX/image004.jpg

圖2.MFC ActiveX控件向導

  • 7.單擊完成按鍵讓MFC ActiveX控件向導創建工程以及相關代碼。在默認的情況下,向導會把MFC作為一個動態連接庫使用。我們需要對其作一些更改,否則ActiveX控件無法在沒有提供MFC動態連接庫的系統當中下載和運行。這會導致當網頁下載和運行ActiveX控件時候導致錯誤警報。在Visual Studio目錄中, 選擇工程、屬性。然后選擇配置屬性->常規->MFC的使用,把MFC的使用改成在靜態庫中使用MFC
  • 8.向導將會給我們建立下面三個不同的類型以供使用:
  • CMyActiveXApp – 這個是ActiveX應用程序類,繼承於COleControlModule。后者是驅動一個OLE控件的基礎。控件模塊對象包含了初始化(InitInstance)和清理(ExitInstance)的成員函數。
  • CMyActiveXCtrl – 由基類COleControl驅動。它提供了我們的控件的大部分功能。
  • CMyActiveXPropPage – 由基類COlePropertyPage驅動。它被用來管理控件的屬性頁對話框。ActiveX Control控件向導會建立一個默認的對話框為這個控件提供屬性頁。

加入對GIF動畫的支持

為了讓這個ActiveX控件支持顯示一個GIF動畫表現的進度條功能,我們將要使用CPictureEx類型,它是Oleg Bykov在CodeProject Article提供的。這里提供一些相關的細節。首先,把源碼文件pictureex.cpp和pictureex.h加入到你的工程,在解決方案資源管理其中右鍵單機工程,選擇添加現有項目,然后選擇同文件和源文件,填交到代碼樹中。


為了添加一個GIF資源到項目中,我們必須面對Visual Studio 2005(以及vs2003)的一個問題,它不允許導入GIF圖像各式的文件到資源中。如果你這么做了,你對得到一個錯誤警告,你需要通過下面的途徑來繞過這個問題:

 

  • 1.拷貝GIF文件ProcessingProgressBar.gif文件到你的工程文件夾中,並改擴展名為gaf(即改為ProcessingProgressBar.gaf文件)。在資源視圖中,右鍵單擊資源文件夾MyActiveX.rc,並選擇添加資源。在添加資源對話框中,單擊導入按鍵,選擇文件ProcessingProgressBar.gaf。在資源定制類型對話框中輸入“GIF”作為資源的類型,選擇確定。這樣我們就把一個GIF圖像文件放入這個工程中來。你可以在資源中找到GIF文件夾找到我們的資源,在其屬性中把系統給的IDIDR_GIF1 改成IDR_PROGRESSBAR
  • 2.現在,我們需要把圖形文件正確配置。首先,保存資源文件MyActiveX.rc。在工程目錄中,用記事本打開他,把其中"ProcessingProgressBar.gaf"改成"ProcessingProgressBar.gif"同時我們也需要把gif文件擴展名稱改回ProcessingProgressBar.gif。在記事本中保存MyActiveX.rc文件。Visual Studio將要告知myactivex.rc被在外部改變,單擊確定讀入新的文件。選擇解決方案資源管理器,把“ProcessingProgressBar.gaf”改為“ProcessingProgressBar.gif”。

 

增加圖形進程條對話框

現在,我們將要增加一個圖形進程條對話框。

  • 1.在資源視圖中,右鍵單擊對話框文件夾,選擇插入dialog創建一個默認的對話框。
  • 2.刪除“確定”和“取消”兩個不需要的按鍵,並且調整對話框尺寸到230 x 40。
  • 3.改變對話框的其中一些屬性:Border – None, Style – Child, System Menu – False, Visible –True.
  • 4.改變控件ID到IDD_MAINDIALOG
  • 5.插入一個圖片控件(picture control)到對話框中來,選擇Visual Studio最右邊的工具箱,選擇picture control,然后點擊對話框。調整這個控件的尺寸到200 x 20。改變控件的ID到IDC_PROGRESSBAR,把Color屬性設置為White。
  • 6.為對話框創建一個類,右鍵單擊對話框選擇添加類。結果打開了MFC類向導如圖3所示。把類名定義為CMainDialog,繼承於CDialog。單擊完成讓想逃來創建這個類的默認源代碼。

http://www.codeproject.com/com/CompleteActiveX/image006.jpg

圖3.MFC類向導如圖 – CMainDialog

現在我們可以向類中增加成員變量了。成員變量m_MainDialog是一個CMainDialog類型,m_ProgressBar是我們將要加入主對話框的進度條控件。

 

  • 1.把變量m_MainDialog加入到類CMyActiveXCtrl中。選擇類視圖,右鍵單擊CMyActiveXCtrl,選擇添加,添加變量。輸入變量類型CMainDialog以及變量名m_MainDialog,然后單擊完成按鍵。
  • 2.類似的,增加成員變量m_ProgressBar到類CMainDialog中。輸入變量類型CPictureEx,變量名m_ProgressBar,並打開控件變量選項,然后確認控件ID為IDC_PROGRESSBAR,在單擊完成按鍵之前,確認一下變量CPictureEx而不是被改成的CStatic。

http://www.codeproject.com/com/CompleteActiveX/image008.jpg

Figure 4. 添加成員變量向導– m_ProgressBar

增加支持代碼

好了,現在我們需要卷起袖子寫入一些代碼了,用來繪制主對話框和進度條控件。

  • 1.選擇類CMyActiveXCtrl。在屬性頁中,選擇消息圖標,在WM_CREATE條目下選擇<添加> OnCreate來添加處理WM_CREATE消息。向導將會幫助我們在類CMyActiveXCtrl中添加OnCreate方法來處理理WM_CREATE消息。
  • 2.對MyActiveXCtrl.cpp文件進行編輯,並添加下面代碼在OnCreate方法中用來創建除對話框:
m_MainDialog.Create(IDD_MAINDIALOG, this);

在OnDraw方法中增加下列代碼來對主對話框窗口填入背景色:

m_MainDialog.MoveWindow(rcBounds, TRUE);
CBrush brBackGnd(TranslateColor(AmbientBackColor()));
pdc->FillRect(rcBounds, &brBackGnd);
  • 3.選擇類型CMainDialog。在屬性頁中,選擇消息圖標,在WM_CREATE條目下選擇<添加> OnCreate來添加處理WM_CREATE消息。向導將會幫助我們在類CMainDialog 中添加OnCreate方法來處理理WM_CREATE消息。
  • 4.編輯MainDialog.cpp,並在OnCreate方法中增加下面代碼用來創建進度條GIF動畫:
if (m_ProgressBar.Load(MAKEINTRESOURCE(IDR_PROGRESSBAR),_T("GIF")))
    m_ProgressBar.Draw();

確定當前編譯模式為Release,並編譯MyActiveX ActiveX應用程序。

為ActiveX控件創建網頁

我們選擇的用來快速創建測試網頁的工具是微軟的ActiveX Control Pad。你可以到微軟去下載。

你也可以在其它的網站上面找到可用的下載鏈接,在你使用Visual Studio的系統上安裝並運行這個工具。為了便於測試程序的效果,你還需要裝上微軟的IIS web服務器。

當你第一次運行ActiveX Control Pad,它會為你創建一個默認的HTML網頁。為了插入ActiveX控件,右鍵單擊HTML代碼中<BODY>標簽,然后選擇ActiveX Control。在Insert ActiveX Control窗口中,選擇在剛才用Visual Studio創建的MyActiveX Control,然后選擇OK。


http://www.codeproject.com/com/CompleteActiveX/image010.jpg

圖5. ActiveX Control Pad – Insert ActiveX Control

 

之后在ActiveX Control Pad中會顯示兩個矩形對話框,讓你有機會修改你所選定的控件。屬性對話框提供給你更改控件屬性的方法,Edit ActiveX Control 對話框和意讓你手工編輯這個控件。你可以關閉這兩個窗口,我們之后會在HTML代碼中更加細致的對其進行手動配置。你現在需要找到HTML代碼中的OBJECT ID 標簽,類似圖6所示。把OBJECT ID標簽里面的size參數改變到“WIDTH=350”和“HEIGHT=50”。然后儲存HTML文件為myactivex.htm,並放置到IIS Web服務器的根文件夾中。


http://www.codeproject.com/com/CompleteActiveX/image012.jpg

圖6. ActiveX Control Pad – MyActiveX ActiveX Control

開始測試ActiveX控件,在IE中載入網頁http://localhost/myactivex.htm 。如果你得到了一些警告信息,只需要選擇確定忽略它們。正確的結果是會在網頁中顯示一個GIF動畫的進度條。如果沒有,或者你在控件中得到了一個紅色的X,那很可能是你對瀏覽器的安全設置把ActiveX下載或者運行給關閉了,這時候你應該打開IE的安全設置,把所有關於ActiveX的選項啟用。

 

http://www.codeproject.com/com/CompleteActiveX/image014.jpg

圖7. MyActiveX控件在IE中顯示

接下來,我們需要構建ActiveX控件讓其可以直接在IE瀏覽器中載入,而沒有讓然討厭的錯誤信息。

構建一個已簽名的ActiveX控件

為了構建一個已簽名的ActiveX控件,你需要從某個機構購買一個簽名代碼證書,這些可以欠發證書的機構包括Thawte,Verisign,以及GeoTrust等。當你接受了這項服務的話,它們會幫助你驗證程序不被篡改,並向你發放一個證書給你用來對你的ActiveX應用程序簽名。我選擇了Thawte提供的簽名證書,它提供給你兩個千名文件mycert.spc與mykey.pvk。

對ActiveX程序進行簽名,我們需要把程序打包成CAB文件。讓其可以從網頁下載這個ActiveX控件並進行安裝。在安裝過程中包括了注冊ActiveX組件的過程。為了實現這個功能,我們需要為ActiveX控件設置一個VERSIONINFO結構的OLESelfRegister值,在Visual Studio 2003中會幫助我們完成,而在VS2005中需要我們進行處理。我們需要編輯資源文件myactivex.rc加入下面OLESelfRegister值,如下:

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x4L
 FILETYPE 0x2L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904e4"
        BEGIN
            VALUE "CompanyName", "TODO: <Company name>"
            VALUE "FileDescription", "TODO: <File description>"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", "MyActiveX.ocx"
            VALUE "LegalCopyright", 
                  "TODO: (c) <Company name>. All rights reserved."
            VALUE "OLESelfRegister", "\0"
            VALUE "OriginalFilename", "MyActiveX.ocx"
            VALUE "ProductName", "TODO: <Product name>"
            VALUE "ProductVersion", "1.0.0.1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1252
    END
END


在我們簽名應用程序之前,ActiveX控件需要被打包成CAB文件。CAB文件中同時包含了一個INF文件被用來安裝ActiveX 控件。為了構件CAB文件,你需要運行Cabinet Software Development Kit的cabarc.exe工具。下面提供了一個簡單的INF文件例子,用來包裝MyActiveX控件到CAB文件。你需要把CLSID行的值改成HTML文件中OBJECT ID標簽所使用的值(之前用ActiveX Control Pad生成)。

[Add.Code]
myactivex.ocx=myactivex.ocx
myactivex.inf=myactivex.inf

[myactivex.ocx]
file=thiscab
clsid={36299202-09EF-4ABF-ADB9-47C599DBE778}
RegisterServer=yes
FileVersion=1,0,0,0
 
[myactivex.inf]
file=thiscab

建立CAB文件,向下面一樣運行cabarc工具。 重要:確認在運行cabarc.exe時OCX和INF文件在相同的文件夾中,否則的話CAB文件從網頁中下載之后會產生錯誤。這是一個導致警告的問題。

cabarc -s 6144 N myactivex.cab myactivex.ocx myactivex.inf

當對一個CAB文件進行簽名的時候,你需要得到Microsoft MSDN上的signcode.exe工具。這里關系到“可信的簽名和檢查”將會在這個文章的后面提到。你使用signcode工具把從外面賣到的代碼證書綁定到CAB文件中。下面是一個使用簽名代碼簽名myactivex.cab文件的例子:

signcode -n "myactivex" -i 
   http://www.myactivex.com -spc mycert.spc -v mykey.pvk -t 
   http://timestamp.verisign.com/scripts/timstamp.dll myactivex.cab

在上面的例子中,http://www.myactivex.com 提供了這個給簽名ActiveX控件提供更多用戶信息的網頁。


把這個CAB文件應用到網頁中,首先拷貝myactivex.cab到你網頁所在的文件夾,然后你必須修改網頁中OBJECT ID標記中CODEBASE參數索引到你的CAB文件上來。參照圖8的例子。如果你在IE中載入這個網頁,它將會下載CAB文件並安裝你的ActiveX控件,過程中並不會出現一個沒有簽名的警告。


http://www.codeproject.com/com/CompleteActiveX/image016.jpg

圖8. ActiveX Control Pad – MyActiveX with CODEBASE

構建一個安全的ActiveX控件

如果希望再IE載入控件的時候不對控件不安全作出警告的信息的話,你必須保證執行代碼使用安全的初始化和腳本的Active控件。相關的細節可以參照微軟MSDN上的文章“Safe Initialization and Scripting for ActiveX Controls”。本文的后面會給出鏈接地址。不過我在這篇文章里面看到了大量的錯誤和冗長的文章。其實只需要在代碼中加入DllRegisterServer和DllUnregisterServer這兩個方法。下面我們就一步步指導你把ActiveX控件改成安全的:


編輯MyActiveX.cpp文件加入下面代碼。在你的ActiveX控件中CLSID_SafeItem的值需要等於你在MyActiveXCtrl.cpp文件中的IMPLEMENT_OLECREATE_EX,同時,這個值也要和你在網頁中的OBJECT ID標記CLSID值相同。

 #include "comcat.h"
 #include "strsafe.h"
 #include "objsafe.h"
  
 // CLSID_SafeItem - Necessary for safe ActiveX control
 // Id taken from IMPLEMENT_OLECREATE_EX function in xxxCtrl.cpp
  
 const CATID CLSID_SafeItem =
 { 0x36299202, 0x9ef, 0x4abf,{ 0xad, 0xb9, 0x47, 0xc5, 0x99, 0xdb, 0xe7, 0x78}};
 
 // HRESULT CreateComponentCategory - Used to register ActiveX control as safe 
  
 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
    size_t len;
    // Make sure the provided description is not too long.
    // Only copy the first 127 characters if it is.
    // The second parameter of StringCchLength is the maximum
    // number of characters that may be read into catDescription.
    // There must be room for a NULL-terminator. The third parameter
    // contains the number of characters excluding the NULL-terminator.
    hr = StringCchLength(catDescription, STRSAFE_MAX_CCH, &len);
    if (SUCCEEDED(hr))
        {
        if (len>127)
          {
            len = 127;
          }
        }   
    else
        {
          // TODO: Write an error handler;
        }
    // The second parameter of StringCchCopy is 128 because you need 
    // room for a NULL-terminator.
    hr = StringCchCopy(catinfo.szDescription, len + 1, catDescription);
    // Make sure the description is null terminated.
    catinfo.szDescription[len + 1] = '\0';
 
    hr = pcr->RegisterCategories(1, &catinfo);
    pcr->Release();
 
    return hr;
}
 
// HRESULT RegisterCLSIDInCategory -
//      Register your component categories information
 
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 - Remove entries from the registry
 
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方法:

STDAPI DllRegisterServer(void) {
    HRESULT hr;    // HResult used by 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;
}

修改DllUnregisterServer方法:

STDAPI DllUnregisterServer(void)
{
    HRESULT hr;    // HResult used by Safety Functions
 
    AFX_MANAGE_STATE(_afxModuleAddrThis);
 
    if (!AfxOleUnregisterTypeLib(_tlid, _wVerMajor, _wVerMinor))
      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;
}

ActiveX控件屬性、方法以及事件

在ActiveX控件和網頁之間傳遞消息需要通過屬性、方法以及事件。為了便於展示這方面的技術,我們將要創建一個簡單的網頁,其中包含了簡單的form元素,包括一個文本框與一個提交按鍵,文本通過一個輸入參數屬性被輸入到ActiveX控件中。有一個控件方法把文本拷貝到輸出參數屬性上,然后激發一個事件把文本顯示到網頁中。我們需要做下列步驟:

 

  • 1.首先,我們需要建立一個ActiveX控件屬性來用作處理文本。在類視圖中,展開MyActiveXLib元素,選擇_DMyActiveX。右鍵單擊_DMyActiveX,選擇增加,增加屬性。在添加屬性向導對話框中(圖9),選擇BSTR作為屬性類型,輸入“InputParameter”作為屬性名稱。向導會幫助自動添入其他項目,“m_InputParameter”作為變量名稱,“OnInputParameterChanged”作為通知函數。選擇完成按鍵來讓向導自動創建屬性代碼。同樣的方法,我們添加BSTR類型的“OutputParameter”屬性。

http://www.codeproject.com/com/CompleteActiveX/image018.gif

圖9. 添加屬性向導

  • 2.然后,我們需要創建一個方法用來讓網頁通知控件輸入字符串參數。在類視圖中,展開MyActiveXLib元素,右鍵單擊_DMyActiveX,選擇增加,增加方法。在添加方法向導對話框中(圖10),返回值選擇void類型,輸入“LoadParameter”作為方法名稱。向導會自動幫助我們添入“LoadParameter”作為內部名稱。 選擇完成按鍵來讓向導自動創建方法代碼。

http://www.codeproject.com/com/CompleteActiveX/image020.jpg

Figure 10. 添加方法向導

  • 3.最后,我們將要創建一個ActiveX控件事件用來通知網頁完成文本從輸入參數到輸出參數的傳遞。在網頁中的代碼將會對這個事件進行處理並顯示輸出參數中的文本,用來校驗在ActiveX控件中的轉換是否正確。在類視圖中,右鍵單擊CMyActiveXCtrl,選擇增加,增加事件。在添加事件向導對話框中(圖11),輸入“ParameterLoaded”作為事件名稱,並把內在的名稱改為“FireParameterLoaded選擇完成按鍵來讓向導自動創建代碼來支持事件。


http://www.codeproject.com/com/CompleteActiveX/image022.jpg

圖11.添加事件向導

在上面的過程中,向導幫助我們創建了大多數的工作。我們只需要簡單的添加幾行代碼來添加ActiveX控件拷貝文本和通知網頁的事件。編輯文件MyActiveXCtrl.cpp,並且增加下面的代碼來讀入參數。

// Copy text from the input parameter to the output parameter
m_OutputParameter = m_InputParameter;
// Fire an event to notify web page
FireParameterLoaded();

為了測試,下面使用ActiveX Control Pad工具來創建HTML代碼:

<HTML>
<HEAD>
<TITLE>MyActiveX - Methods, Properties, and Events</TITLE>

<SCRIPT LANGUAGE="JavaScript">
 
function PassParameter()
{
    if (StringInput.value != " ")
    {
        MyActiveX1.InputParameter = StringInput.value;
        MyActiveX1.LoadParameter();
    }
}
</SCRIPT>
 
</HEAD>
<BODY>
< CENTER>
MyActiveX - Methods, Properties, and Events Example
< P>< /P>
 
<OBJECT ID="MyActiveX1" WIDTH=350 HEIGHT=50
 CLASSID="CLSID:36299202-09EF-4ABF-ADB9-47C599DBE778">
    <PARAM NAME="_Version" VALUE="65536">
    <PARAM NAME="_ExtentX" VALUE="2646">
    <PARAM NAME="_ExtentY" VALUE="1323">
    <PARAM NAME="_StockProps" VALUE="0">
</OBJECT>
< p>< /p>
 
Input Parameter: <INPUT TYPE ="text" NAME="StringInput" VALUE=" ">
< p>< /p>
<INPUT TYPE="button" NAME="Submit" 
       VALUE="Submit" ONCLICK=PassParameter()>
 
<SCRIPT FOR=MyActiveX1 EVENT=ParameterLoaded()>
</SCRIPT> 

< /center>
</BODY>


儲存這些HTML代碼到你的服務器上,並運行它。你將會看到一個網頁顯示一個進度條,並且擁有一個提交文本的form元素,其中包含一個文本輸入框和一個提交按鍵。黨提交后會顯示一個新的頁面,在其中顯示“The parameter you entered is: ”,和你輸入的文本。下面我們將會對網頁HTML代碼介紹一下概況。

 

當你按下提交,JavaScript腳本函數PassParameter將會被調用。在這個函數中在StringInput中的文本將會被拷貝到ActiveX控件的InputParameter屬性中。接下來方法LoadParameter被調用,把InputParameter屬性的值拷貝到OutputParameter中,最后調用FireParameterLoaded()來觸發一個ActiveX事件。下面的HTML代碼被用來處理這個事件。

 

<SCRIPT FOR=MyActiveX1 EVENT=ParameterLoaded()>
</SCRIPT>

提及:

  1. Add GIF-animation to your MFC and ATL projects with the help of CPictureEx and CPictureExWnd by Oleg Bykov, CodeProject.
  2. Packaging ActiveX Controls, Microsoft.
  3. Signing and Checking with Authenticode, Microsoft.
  4. Safe Initialization and Scripting for ActiveX Controls, Microsoft.

David Marcionek

Click here to view David Marcionek's online profile.

 

其它關於COM/DCOM/COM+的文章:

A tutorial for programmers new to COM that explains how to reuse existing COM components, for example, components in the Windows shell.
How to create/use COM components in plain C, without MFC, ATL, WTL, or any other framework.
A C++ class that makes it extremely easy to use a COM object, even in console apps
A tutorial for programmers new to COM that explains the internals of COM servers, and how to write your own interfaces in C++


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM