孫鑫VC學習筆記:ActiveX 控制項

來源:互聯網
上載者:User

孫鑫VC學習筆記:ActiveX 控制項
作者:華仔 | 錄入時間:2007-12-26 | 點擊:313 次    列印此文章 | 字型:大 中 小
基本概念:

容器和伺服器程式

      容器應用程式時可以嵌入或連結化物件的應用程式。Word 就是容器應用程式。伺服器應用程式是建立對象並且當對象被雙擊時,可以被啟動的應用程式。Excel 就是伺服器應用程式。ActiveX 控制項不能獨立運行,它必須被嵌入容器應用程式中,和容器應用程式一起運行。
 
---------------------------------------------------------------------------------
編寫一個 ActiveX 時鐘控制項

      1.利用 MFC ActiveX ContrlWizard 建立一個 Clock 工程

      2.在建立的工程中有三個類,其中 CClockApp 從 COleControlModule 中派生出來的,

可以將其看作是應用程式類,它的一個執行個體表示控制項程式本身。
 
      COleControl 從 CWnd 派生得到,也是一個視窗類別,
      CClockCtrl 相當於單文檔程式的主視窗類。
      這個類包含重繪用的 OnDraw 函數,也包含了一些訊息映射,包括調度映射。
      Dispatch maps 調度映射,主要是 MFC 提供讓外部應用程式可以訪問控制項的屬性和方法。
      Event maps 事件映射,控制項向包含它的容器發送事件通知。
 
CClockPropPage 類由 COlePropertyPage 派生而來:
 
      COlePropertyPage
 
      The COlePropertyPage class is used to display the properties of a custom control in a graphical interface, similar to a dialog box. 被用來顯示一個自訂控制項的屬性,類似於一個對話方塊。它是對話方塊類,於是 enum { IDD = IDD_PROPPAGE_CLOCK }給它關聯了一個對話方塊資源。
 
      在工程中,還有兩個全域函數:STDAPI DllRegisterServer(void);將控制項資訊寫入註冊表中 STDAPI DllUnregisterServer(void)卸載註冊資訊。

      3.在三個類之上,還有類似小勺的表徵圖 Dclock,_DClockEvents,它們表示介面。

      介面是外部程式和控制項進行通訊的協議,可以把介面看作是函數的集合,外部程式通過介面提供的方法,去訪問控制項的屬性和方法。也可以將介面看作抽象基類,介面中所定義的所有函數都是純虛函數, 這些函數的實現都是在 CClockCtrl 類中實現,MFC 通過底層的封裝使 CClockCtrl 類繼承 Dclock 介面。所以調用介面,事實上調用的是 CClockCtrl 類中的函數。由於封裝,底層的通訊細節我們看不到,如果對這個感興趣,可以看一些 COM 編程的資料。
 
      4.如果些時編譯一下工程,會產生一個 Clock.ocx 檔案,它就是 ActiveX 控制項的檔案。

       要用控制項的時候,只需要把這個檔案傳遞給對方。注意:ActiveX 控制項不能單獨使用,必須嵌入到一個視窗當中一直運行。當我們用 VB 添加控制項時,發現了我們剛才編譯的控制項,但是 VB 怎麼知道我們建立的控制項的位置呢? 我們發現編譯時間,輸出視窗的最後一行 “Registering ActiveX Control...”說明編譯時間會註冊控制項。事實上編譯之後,VC 會調用 regsvr32 註冊控制項,並將資訊寫入到註冊表中,VB 在載入 ActiveX 控制項時,會從註冊表中搜尋相關的 ActiveX 控制項資訊。注意:ActiveX 控制項在使用之前都需要註冊。

      如果想卸載控制項,可以在“運行”中輸入命令:
      “regsvr32 /u 控制項檔案完整路徑名”,事實上是調用工程中全域函數 DllUnregisterServer 來完成卸載的。
      如果想再次註冊控制項,可以在“運行”中輸入下面命令:
      “regsvr32 控制項檔案完整路徑名”事實上是調用工程中全域函數 DllRegisterServer 來完成註冊的。
 
      5.下面實現在控制項上輸出當時系統時間。

      可以在 OnDraw 函數中完成這個功能。
 
      這樣就能做出一個靜態時間控制項,如果我們想使控制項即時顯示時間,需要添加兩個訊息響應函數  WM_CREATE,WM_TIMER.要使時間可以每秒更新,我們先在 CClockCtrl 類中添加 WM_CREATE 訊息處理,在其響應函數 OnCreate()中設定一個計時器:SetTimer(1,1000,NULL);接著增加一個 WM_TIMER 訊息響應處理,在 OnTimer 中寫上 Invalidate(); 使視窗發生重繪。也可以調用 InvalidateControl()強制控制項重繪自身。
 
      6.在 VB 測試中發現,其他很多控制項可以修改控制項的背景色、前景色彩和字型顏色,而我們還不行。

      ActiveX 控制項有四種屬性:
      Stock:為每個控制項提供的標準屬性,如字型或顏色。
      Ambient:圍繞控制項的環境屬性——已被置入容器的屬性。
      這些屬性不能被修改,但控制項可以使用它們調整自己的屬性。
      Extended:這些是由容器處理的屬性,一般包括大小和在螢幕上的位置。
      Custom:由控制項開發人員添加的屬性。
 
      7.這時在 VB 測試中,我們的控制項也可以修改控制項的背景色和前景色彩了,但是設定完以後沒有效果,因為還要 OnDraw 函數中自己編寫代碼來完成這些改變。要得到控制項標準屬性,要通過一些函數來完成,如COleControl::GetForeColor 得到前景色彩,COleControl::GetBackColor 得到背景色,不過要注意的是它們得到的是 OLE_COLOR 的顏色,還需要通過 TranslateColor 方法轉換成 COLORREF。
 
      8.控制項一般都會有屬性頁面,當我們右鍵點擊控制項時會彈出這個屬性頁面方便對控制項屬性的設定,我們的控制項已經有一個屬性頁面,通過 CClockPropPage 類來實現的,顯示的面容是對話方塊資源的內容,下面修改控制項屬性頁面:
      屬性頁面之所以可以在視窗中看得到,是因為在 ClockCtl.cpp 中的 BEGIN_PROPPAGEIDS(CClockCtrl, 1)與 END_PROPPAGEIDS(CClockCtrl)之間調用了 PROPPAGEID(CClockPropPage::guid),其中的 guid 表示通用唯一識別碼,它是一個128位的整數,用來唯一地標識一個組件或者一個介面。我們可以用 PROPPAGEID 宏增加屬性頁面。
 
      增加顏色屬性頁面
      首先在 BEGIN_PROPPAGEIDS(CClockCtrl, 1)與END_PROPPAGEIDS(CClockCtrl)之間添加代碼 PROPPAGEID(CLSID_CColorPropPage)來添加屬性頁面。
 
      CLSID_CColorPropPage 屬性工作表單是控制項自身提供的, 我們添加之後不用作任何處理,就可以使用,效果如下:
 
      注意:
      BEGIN_PROPPAGEIDS(CClockCtrl, 2)中的數字2表示有多少個屬性頁面代碼要顯示,
      如果增加了屬性頁面數字一定要加1,不然如果沒有修改或修改錯誤,會產生不可預料錯誤。
 
      9.增加一個自訂屬性也是通過 MFC ClassWizard 來完成,與第6步增加前景色彩與背景色的步驟相同。

      1)下面增加設定時間間隔的屬性,用這個屬性來控制項時間重新整理頻率:
 
      屬性添加成功以後,在_DClock 介面中增加了 Interval 屬性,同時在 CClockCtrl 類中增加了一個
 成員變數 m_interval 和 OnIntervalChanged()方法(當外部屬性修改之後就會調用這個方法)。
 而且它們都在調度映射當中:
 
      2)在 CClockCtrl::OnIntervalChanged()中添加屬性處理常式代碼
 
      10.使增加的自訂屬性在屬性工作表單中設定

      在對話方塊資源中添加一個編輯框,再為這個編輯框關聯一個變數, 注意,我們在為編輯框關聯一個變數 m_updateInterval 的同時也關聯了一個屬性是,這樣我們不需要增加代碼就能把控制項和自訂屬性相關聯。在 void CClockPropPage::DoDataExchange(CDataExchange* pDX)中會產生下面代碼:
 
      這樣,我們就可以在屬性頁面裡面設定時間間隔了。
 
      11.為控制項添加一個方法:

      為控制項增加函數,MFC ClassWizard-->Automation-->Add Method Class Name 要選擇CClockCtrl 輸入函數名,之後就可以在 CClockCtrl 類中找到了。方法添加成功以後,在_DClock 介面中增加了 Hello 方法,同時在 CClockCtrl 類中增加了 Hello 方法。接下來,我們可以在 CClockCtrl 類中增加了 Hello 方法添加自己的代碼就可以了。

      12.為控制項添加一個標準事件

      我們選擇 MFC ClassWizard-->ActiveX Events--->Add Event。事件添加成功以後,會在_DClockEvents 中增加一個事件 Click,DClockEvents 介面是源介面,控制項將用這個介面發送通知事件,它不是控制項本身實現的介面,這個介面是通過容器來實現的
 
      13.增加一個自訂事件:當秒數為0時,發出一個 NewMinute 事件。

      1)增加一個自訂事件的過程與增加一個標準事件的步驟相同,也可以這樣添加在事件介面_DClockEvents 上點擊右鍵,選擇增加事件,效果一樣,都會彈出 Add Event 對話方塊。事件添加成功以後,會在_DClockEvents 中增加一個事件NewMinute事件,同時在在 CClockCtrl 類中增加了void FireNewMinute(),也就是在控制項內部可以調用 FireNewMinute()向容器發送事件通知,而這個函數內部會調用介面的 void NewMinute()向容器發出事件通知。
 
      2)在 OnDraw()方法添加代碼 if(0 == time.GetSecond())FireNewMinute();使當秒數為0時,向容器發出一個 NewMinute 事件通知。標準訊息不需要另外寫代碼向容器發出事件通知,VC在底層代碼內部實現了這個過程。

      14.將我們自訂的控制項屬性在修改之後永久儲存下來,使用者開啟程式之後,控制項的屬性都是使用原先儲存的值。需要在 void CClockCtrl::DoPropExchange(CPropExchange* pPX)加入如下代碼 PX_Short(pPX,"Interval",m_interval,1000);之後再在程式中 OnCreate()方法中將 SetTimer(1,1000,NULL); 修改代碼為 SetTimer(1,m_interval,NULL);
 
      15.在屬性頁面中修改自訂控制項屬性的時候,通知容器做相應的調整,從而使容器屬性列表中即時地顯示我們對屬性所作的修改。在 void CClockCtrl::OnIntervalChanged() 中加入如下代碼:BoundPropertyChanged(0x1);   //通知容器分派識別碼 為1的屬性發生了改變
 
      16.前面都是讓控制項在容器設計時改變控制項屬性,如果希望使用者在設計模式時時鐘控制項停止運行,而在使用者模式下時間會跳動,在控制項內部可以通過 AmbientUserMode()方法得到當前控制項是處於設計狀態還是運行狀態。在 void CClockCtrl::OnTimer(UINT nIDEvent)下修改代碼如下:
      if(AmbientUserMode())  InvalidateControl();

      17.編寫完控制項以後,我們可以選擇 Win32 Release 方式進行編譯,產生發行版 ActiveX 控制項。在開發的時候通常是以 Win32 Debug 模式下編譯的,這種模式下開發有助於我們開發過程的產生的錯誤,例如非法記憶體訪問錯誤;還可以協助我們偵錯工具,跟蹤程式進而排查錯誤。但是在偵錯模式下產生的檔案比較大,因為在檔案中包含了調試的資訊。

      而當我們開發完成後,在 Release 模式下進行編譯時間,VC 編譯器會在代碼產生上、執行速度上做一些最佳化,同時產生的可執行程式或控制項檔案會比較小。
-------------------------------------------------------------------

在 VC 中編寫一個用戶端調用 ActiveX 控制項:

1.建立一個基於 MFC 對話方塊的 ClockTest 工程項目

2.點擊右鍵,選擇“插入 ActiveX 控制項”,然後在彈出的對話方塊中選擇剛才我們建立的控制項。

也可以通過菜單的方式增加控制項:
 “工程”->增加到工程->Componets and Controls
 選擇登入控制項"Registered ActiveX Contrlos",找到我們自己控制項,再按下插入。
 
通過這種方式插入 ActiveX 控制項時,會在工程中自動產生一個類 CCock,其基類為 CWnd。這個類是一個封裝類,封裝了對 ActiveX 控制項進行訪問的一些操作。同時在 VC 的工具箱上面也增加一個時鐘控制項,可以直接將一個時鐘控制項拖放到表單上。

3.用第二種方法插入的控制項,除了將控制項手動插入到表單以外,我們也可以通過代碼動態產生一個控制項。

1)CClockTestDlg 增加一個成員變數:CClock m_clock;
2)在 CClockTestDlg 的標頭檔中包含一個 clock.h
3)接下來就要以在一個按鈕的單擊事件中增加建立控制項的代碼:
4)在設計時,可以點擊右鍵為控制項添加事件響應。

 

 

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/yanghao58686763/archive/2008/02/06/2085196.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.