程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> 用VC++來設計ActiveX控件

用VC++來設計ActiveX控件

編輯:vc教程

ActiveX是Microsoft提出的一組使用COM(ComponentObjectModel,部件對象模型)使得軟件部件在網絡環境中進行交互的技術集。它與具體的編程語言無關。作為針對Internet應用開發的技術,ActiveX被廣泛應用於WEB服務器以及客戶端的各個方面。本文著重介紹以Visual C++ 5.0為工具,利用系統提供的AppWizard快速構造一個簡單的ActiveX控件。

通常VC++5.0提供兩個途徑開發ActiveX控制:MFC和ATL(ActiveXTemplateLibrary)。使用MFC,可以不必理會控制接口的細節,把注意力集中在控制本身的功能上,但是生成的控制比較大。而且,客戶端如果要運行此ActiveX控制,必須擁有相應版本的MFC類庫的DLL,否則,必須同時下載這些巨大的類庫;使用ATL,由於不汲及MFC的標准類庫,生成的控制相對較小,但開發者必須了解COM、OLE技術的細節。這裡,我們主要說明一下使用MFC開發ActiveX控制的方法,因為這種方法相對比較容易。

在Microsoft Developer Studio環境下,按如下的操作步驟可以快速生成一個標准的ActiveX控件。首先,啟動系統的AppWizard,用File菜單下的New菜單項創建新的項目。注意:我們選擇的是列表框中的MFC ActiveX ControlWizard項。也可以使用ATL COM AppWizard項來產生ActiveX控件,這樣實現的控件的最終代碼量較小,但由於用這種方法加入的ActiveX控件對象從最基本的COM對象出發,故不能使用MFC類庫中的COleControl所提供的強大功能。而用MFC ActiveX ControlWizard項則產生以COleControl為基類的控件對象類,它繼承了所有COleControl類中實現的OLE控件的特性,包括窗口對象特性和方法、屬性及事件等。接著,按照系統給出的提示信息逐步完成創建工作。用戶可根據實際應用的要求定制控件的各項特性。

我們假定項目名為Test。創建工作完成後,打開Workspace文件Test.dsw,可以看到系統生成的Test控件框架,主要的類及實現功能描述見下表:

派生類 基類 實現功能
CTestApp COleControlModule 控件實例的初始化和撤消
CTestCtrl COleControl 控件窗口的創建、更新及消息處理
CTestPropPage COlePropertyPage 控件屬性頁的設置及與實際屬性值的交換

編譯此項目,生成Test.ocx。在當前的Developer Studio環境下,這個控件已經被自動注冊了。用系統提供的工具ActiveX Control Test Container可以立即進行測試,在已提供的可插入OLE控件列表中,Test Control就是我們生成的控件名。如果想在其它環境下使用它,則必須先對Test.ocx文件進行注冊,具體做法是在命令行方式下鍵入命令:“regsvr32 …Test.ocx”。此後,我們就可在任何支持ActiveX控件的環境中使用它了。注意:.ocx文件應該隨時更新和注冊。

當然,這樣生成的控件沒有什麼實質性的用處,若在任何一個包容器中測試它,則只可見一個矩形框和一個內切橢圓,除了縮放和位置移動功能外不能進行任何操作。

然而,我們希望開發出來的控件就像一個通常的編輯環境一樣:用戶可以在窗口內進行文本的輸入和編輯,而且有工具條來支持各項操作。

1、為控件添加工具條和子窗口 

VC++的模板常常是很有用的工具,我們設計一個類CToolbar,為控件類T添加工具條,顯示每個按鈕及提示信息。我們的控件類CtestCtrl是從這個類派生出來的,從而可為控件加上設計好了的工具條。

以下是實現工具條模板類的定義 (在Toolbar.h文件中) :

template
class CToolbar
{
public:
CToolbar();
void CreateToolbar(HWND hParent);// 創建工具條
void AddButtons();// 逐個加入按鈕
void DestroyToolbar();// 撤消工具條
LRESULT OnToolbarNeedText(WPARAM, LPNMHDR pnmh, BOOL&);
// 工具條上按鈕的提示信息
protected:
HWND m_hwndToolbar;// 工具條的窗口句柄
}; 
 

接著,要對TestCtl.h和TestCtl.cpp作相應的修改。在TestCtl.h中要先包含Toolbar.h文件,並將控件類定義為:

class CTestCtrl : public COleControl, public CToolbar
然後,再加進消息映射宏:
BEGIN_TOOLBAR_MAP(CTestCtrl)
TOOLBAR_BUTTON(ID_New)
TOOLBAR_SEPARATOR()
TOOLBAR_BUTTON(ID_CUT)
......
TOOLBAR_SEPARATOR()
......
END_TOOLBAR_MAP()

以響應定制的工具條上的各個按鈕消息。上面的宏在Toolbar.h文件中被定義。於是,在CTestCtrl類的成員函數中就可以靈活使用CToolbar類的各項操作了。

另外,我們再為控件設計一個可編輯的子窗口。這實現起來很方便,在控件類定義中直接加入CEdit類的對象作為成員變量m_TestEdit即可。

要想真正生成我們自己的控件窗口,則需重載COleControl::CreateControlWindow函數。控件窗口被創建時,該函數被調用,函數中先調用基類同名函數,再依次調用CreateToolbar和CreateTestEdit 生成控件中的工具條和子窗口。自然,我們不再需要系統缺省調用的畫圖函數,將CTestCtrl::OnDraw 中畫矩形框和橢圓的部分去掉。CreateToolbar在工具條模板類中實現;CreateTestEdit 在控件類中自定義,函數先計算控件窗口的客戶區和工具條的窗口大小,得到子窗口的位置,使之填滿控件中工具條以外的全部區域,然後調用m_TestEdit.Create函數,設置參數使子窗口具有用戶所希望的各項風格。

2、調整控件窗口中各個對象的位置 

工具條和子窗口已經在控件中生成後,還有一項重要的工作就是當控件位置移動或大小改變時,要相應地調整工具條和子窗口的位置和大小。

COleControl類為我們提供了這樣的函數:

COleControl::OnSetObjectRects(LPCRECT lpRectPos, LPCRECT lpRectClip); 

其中的參數給出了控件的新位置。重載此函數,先按系統提供的功能自動調整工具條,調用:

::SendMessage(m_hwndToolbar, TB_AUTOSIZE, 0L, 0L) 

然後,同創建時一樣計算控件窗口的客戶區(參數lpRectPos已給出),調用GetWindowRect獲得工具條的窗口大小。為使子窗口填滿控件中工具條以外的全部區域,應先計算出相應的矩形位置並調用m_TestEdit.SetWindowPos來 實現子窗口的位置調整。為了美觀起見,也可在子窗口的四邊留出少許富余。最後,調用基類的OnSetObjectRects函數。

3、實現對控件內對象的控制 

因為有了子窗口,實際上用戶的各項功能操作都是由子窗口來控制完成的。我們將焦點的控制權交給子窗口,使用戶能進行輸入和編輯操作,在CTestCtrl::OnSetFocus中調用m_TestEdit.SetFocus。同樣,當控件對象捕獲到工具條上的按鈕被按下的消息時,要調用 m_TestEdit 的相應函數以執行用戶的命令。

工具條上提示信息的顯示也由控件對象來控制。在CTestCtrl::OnNotify函數中加入如下代碼:

NMHDR *pNMHDR = (NMHDR *)lParam;
BOOL tmp;
if (pNMHDR->code == TTN_NEEDTEXT)
return OnToolbarNeedText(wParam, pNMHDR, tmp); 

這樣,當鼠標移動並停留在工具條的某個按鈕上時,控件對象就會調用工具條模板類中的OnToolbarNeedText 函數以獲得相應的提示信息。

4、控件窗口及內部對象的撤消

最後需要說明的是,如果我們在控件中創建了新的工具條和子窗口,則也應該及時撤消控件窗口及其內部對象。撤消控件窗口,即是在 CTestEdit::OnDestroy函數中依次調用DestroyToolbar和 m_TestEdit.DestroyWindow 來清除工具條和子窗口。

遵循以上四個工作步驟就可以很好地創建一個帶有工具條和編輯子窗口的ActiveX控件。子窗口可由用戶自己定義,象通常的應用程序那樣去實現各種各樣或簡單或復雜的功能。工具條的存在使用戶執行各項操作更加方便。此外,在控件中加進其它各種所需的對象並進行控制也是可能的。

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