程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 創建適用於多種容器的控件

創建適用於多種容器的控件

編輯:關於C語言

 

 

即使是一個符合OLE標准的控件,在不同的ActiveX容器裡其行為也會偶爾不同。不能成功地適應容器之間的差別將嚴重影響控件在某些容器內的應用,甚至導致控件完全無法在個別容器使用。

   本文討論使用Visual C++創建控件時如何適應容器相關的需求,特別是為大范圍內使用而開發ActiveX控件時必須執行的策略。例如,如何解決諸如許可、線程、內容檢驗、鍵盤事件響應等問題。

 

   一、關於ActiveX控件

 

   在具體討論容器之間的差別前(這種差別使得為多種容器開發ActiveX控件復雜化),有必要回顧一下何謂ActiveX控件以及它的創建過程。

 

   ActiveX控件可以看成是實現了標准OLE接口的COM對象。所有的控件都必須最終定位於某種容器,如Visual Basic、Visual C++、IE浏覽器。容器使用標准的OLE接口和控件協商。例如,容器可以創建、定制、存儲控件以便以後使用。容

器和ActiveX控件之間的所有交互都通過標准的OLE接口進行,由此,ActiveX控件追隨了“黑盒”這一思想。控件的用戶除了需要了解它的外部接口外,並不需要知道它的內部工作過程。只要開發工具(容器)以及編程語言理解並使用標准的

OLE接口,就可以在多種容器中使用ActiveX控件。當然,這僅僅是理論;在實踐中,沒有兩種容器是相同的,開發者必須把握它們之間的不同之處。

 

   創建ActiveX控件開始於選擇開發工具。可供選擇的工具很多,從VB到Delphi到VJ++。本文由VC++為出發點討論控件創建。使用VC++可以獲得更快的執行速度和對創建過程更多的控制,以及最大范圍的平台SDK和API支持。VC++提供了MFC ActiveX控件向導來簡化ActiveX控件的創建。這個向導引導您通過創建控件外殼的每一步。向導提出的第一個問題是是否需要許可。

 

   二、許可控件

 

   控件操作有兩個不同的環境:運行時和設計時。一個需要許可證的控件包含幾個接口用於設計時限制某些訪問。缺乏適當許可的用戶只能在運行環境下使用該控件,而不能在設計環境下使用它。如果打算在企業內部、Internet、本地Intranet上使用控件,一般會避免使用許可證。然而,如果是出售商業產品或打算限制設計時訪問控件的能力,就應該利用許可所帶來的優點。

 

   如果選擇許可某個控件,控件向導就自動加入了必要的接口並創建可定制的許可文件(LIC)。剩下必須做的工作只是修改主文檔(如myprojectCTL.CPP)中幾個變量。請修改許可文件的內容使之符合許可證鍵:

 

   static const TCHAR BASED_CODE

 

   _szLicFileName[] = _T("control.lic");

 

   static const WCHAR BASED_CODE

 

   _szLicString[] ="My Unique Validation String";

 

   在許可文件可用之後,開發工具經常在工程內緩沖控件的許可證鍵。如果許可文件本身不再可用,應用程序就使用緩沖的許可證鍵驗證控件。在桌面環境下這是可行的,但在Internet(和Intranet)環境下並沒有內建的機制以通過HTML安全地緩沖這個許可信息。

 

   有兩種方法解決這個問題。第一,可以使用Microsoft的一個叫LPK_Tool.exe的工具,它是Microsoft Internet Client SDK的一部份。LPK_Tool.exe能夠將許可文件轉換為可在HTML文檔內引用的加密文件。IE能夠在實例化一個需要許可證的控件時從LPK文件提取許可信息:

 

   第二個辦法需要定制控件的許可驗證例程。例如,它可以詢問容器自己正處於設計模式還是運行模式。控件所繼承的類(COleControl)包含成員函數AmbientUserMode,此函數在控件處於設計模式時返回TRUE。

 

   然而,並非所有容器響應此查詢(包括IE浏覽器)。此時AmbientUserMode總是返回TRUE;換句話說,它總是假定控件是在設計模式下。如果容器錯誤地響應查詢,可以寫一個函數強制控件認為自己處於運行模式,這樣就可以避免這個限制了:

 

   BOOL CCtrl::OptimisticAmbientUserMode(){

 

   BOOL bUserMode;

 

   if (!GetAmbientProperty(

 

   DISPID_AMBIENT_USERMODE,

 

   VT_BOOL, &bUserMode))

 

   bUserMode = TRUE;

 

   //如果容器沒有回答則假定為運行模式

 

   return bUserMode;}

 

   三、線程模型和資源共享

 

   Microsoft的兩種線程模型,單線程和單元模型,同樣使得在多種容器內使用控件復雜化。單線程控件在單一線程內執行所有對象;單元線程控件可在任何時候任何線程內執行一個對象。

 

   某些情況下可能需要將特定資源全局化以便控件的所有實例訪問。例如,如果控件的多個實例執行許多數據庫操作,此時需要為所有實例創建單一的、共享的數據庫連接,而不是為每個實例單獨創建連接(其它的情況還包括只有一個可用資源的情形,例如設備上下文或端口)。

 

   在單元模型線程環境下共享資源時有一個重大問題需要解決。例如,兩個線程能夠同時嘗試使用同一個資源。這可能導致數據錯誤或其它非預期的結果。那麼,容器如何才能知道控件是單元模型線程安全的?在類工廠(類對象)調用UpdateRegistry期間控件寫入數據到注冊表。當控件為線程安全時常量

 

   afxRegApartmentT

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved