第七章 使用ActiveX控件.docx
《第七章 使用ActiveX控件.docx》由会员分享,可在线阅读,更多相关《第七章 使用ActiveX控件.docx(26页珍藏版)》请在冰豆网上搜索。
第七章使用ActiveX控件
第七章使用ActiveX控件
Windows本身已经提供了很多的控件,我们已经在本书前面的章节中对这些控件作了一些介绍。
但是,应用程序用户的需求是各种各样的,而且,程序员本身的创造力也不应该因此而受到制约。
然而,经历过的人都会深深的体会到,仅仅凭借自己的力量,要想完成一个完善的功能强大的应用程序并非易事——不是不可以,只是非常之的艰难。
绝大多数的优秀的应用程序,都凝结了很多优秀的程序员的天才的创造力和辛勤的劳动。
因此,在很多时候,我们不得不对自己能不能够使用VisualC++写出一个既有强大的实用功能,又具有美观的用户界面的应用程序表示怀疑。
很不幸,坦率的说,要自己从底层写起,一个这样的应用程序常常会埋葬无数的时间。
但是,当我们从一个更大的范围来观察这一情况的时候,我们发现,事实上,就很多编程课题而言,无数的程序员在做的仅仅是一些重复的劳动。
大量优秀的人才浪费在为同一个目的编写功能相同的软件上。
这启发了我们,如果能够制定一套规则,程序员们在此规则的基础上开发各种各样的功能组件,这些功能组件可以方便的用于多个应用程序。
ActiveX技术就是这样的一种技术。
基于ActiveX技术的为数众多的软件组件都提供了满足某个规范的一系列编程接口,应用程序可以通过该编程接口使用由软件组件提供的各种功能,而无需知道这些功能在具体的软件组件里是如何实现的。
这种方式也是我们早在本书一开始的时候所提到的面向对象的程序设计的一个主要特点。
ActiveX技术本身是一种非常复杂的技术,尽管有很多的书籍在讲述这一内容时故意淡化这一点。
要想通过很短的篇幅以很通俗的语言阐明这个技术本身几乎是一件不可能的事。
从本书的写作意图和篇幅来考虑,我们不打算深入的讨论ActiveX本身和如何创建基于ActiveX技术的各种软件组件,而把关心的焦点放到如何应用ActiveX控件本身上。
本章的焦点放到两个问题上:
●什么是ActiveX控件●如何在应用程序中使用ActiveX控件
第一节什么是ActiveX控件
什么是ActiveX控件?
这个问题本身也并不容易说得清楚。
在下面的内容中,我们将侧重的于控件使用者,而不是控件开发者的角度来说明这个问题。
ActiveX控件过去被称作OLE控件,其开发基于通常对象模型(CommonObjectModel,COM),它可以嵌入对话框或其它的ActiveX控件容器,如InternetExplorer和VisualBasic应用程序中使用。
ActiveX控件取代了过去的16位的VisualBasic控件(VBX)。
更专业一点说,ActiveX控件是这样的一个基于COM的对象:
它可以自己的窗口内绘制自身,可以用户的如单击鼠标或按下键盘之类的操作事件,此外是最重要的一点,使用ActiveX控件的应用程序可以通过该控件所包括的一系列的属性和方法(合起来称作接口)来操作该控件的行为。
不要为ActiveX控件本身这个名词所误导,ActiveX控件并不仅仅限用于与用户的可视交互,它还可以用于其它用途,如访问数据库、监视数据等。
ActiveX控件所能提供的功能要远远超过自定义控件的能力。
这些能力包括很多新鲜而有趣的特性,比如将控件本身所提供的菜单嵌入到容器的菜单中等。
ActiveX控件一般以.OCX文件的形式提供,并在系统中进行注册。
对于ActiveX控件这一复杂的课题,我们现在只打算给一个最简单的概念。
下一步我们将通过一个示例来说明ActiveX控件在编程中的使用。
事实上,使用实例来说话往往对初学者往往要更具效果。
第二节使用ActiveXMovie控件的视频播放器
在下面的过程中,我们将通过使用ActiveMovie控件创建一个视频播放器,该播放器支持多种文件格式。
按下面的步骤来创建示例程序VideoPlayer:
1.使用AppWizard创建一个基于对话框的MFC工程。
所有步骤均使用AppWizard给出的默认设置。
在这种情况下,应用程序自动提供了对ActiveX控件的支持。
紧接着删除应用应用程序主对话框中的所有控件,包括“确定”和“取消”按钮。
2.在主对话框中单击鼠标右键,选择InsertActiveXControl命令。
随后弹出如图7.1所示的对话框。
图7.1向对话框中插入ActiveX控件
3.在图7.1的列表框中选择ActiveMovieControlObject,并单击OK按钮。
●注意:
如果在你在如图7.1所示的列表框中找不到项ActiveMovieControl,则说明你的计算机系统中没有安装ActiveMovie控件,或者ActiveMovie控件没有在你的系统中进行正确的注册。
这时,你需要安装ActiveMovie控件才可以继续创建示例程序VideoPlayer。
可以有多个途径得到ActiveMovie控件。
你可以从InternetExplorer4.0软件包中获得该控件,也可以从Microsoft获得该控件的单独发布版本。
4.这时,回到应用程序VideoPlayer的主对话框,右击新添加的控件,选择ClassWizard为新添加的控件映射一个成员变量(下面的步骤将说明这个成员变量的类型)。
5.在添加成员变量映射的过程中,ClassWizard将会弹出如图7.2所示的对话框,以询问是否为ActiveMovieControlObject创建一个类以封装对该控件提供的接口的调用。
在该对话框中单击确定。
图7.2询问是否创建一个C++类以封装ActiveMovieControl对象
图7.3为ActiveMovie控件创建新类CActiveMovie
在如图7.3所示的对话框中为ActiveMovieControl创建新的类CActiveMovie。
上面的步骤也可以使用其它的途径来完成。
首先,在Project菜单的AddToProject子菜单下选择ComponentsandControls命令。
该命令打开如图7.4所示的对话框,在该对话框中双击RegisteredActiveXControls,并从中选择ctiveMovieControlObject。
单击Insert按钮,也弹出如图7.3所示的对话框。
按第五
步中所讲述的内容完成类CActiveMovie。
这时,在Controls工具箱中将会多一个按钮
,单击该按钮,即
可像添加一般的标准控件那样添加ActiveMovie控件。
相比较而言,后一种方法要更为直观一些。
但两种方法的最后结果都是一致的,具体到每一个编程者来说,选择哪一种完成是任意的。
但很明显,如果需要一次向对话本事添加多于一个的同一ActiveX控件,使用后面的方法要省事得多。
图7.4从ComponentsandControlsGallery中向工程添加ActiveX控件
在完成这一步骤之后,为新添加的ActiveMovie控件(我们设置其ID为IDC_AMOVIE)映射类型为CActiveMovie的成员变量m_amovie。
6.现在我们来大致的浏览一下类CActiveMovie的定义。
该定义保存在头文件ActiveMovie.h中。
#if!
defined(AFX_ACTIVEMOVIE_H__9B0F9FA0_1F04_11D2_9717_0000B4810A31__INCLUDED_)
#defineAFX_ACTIVEMOVIE_H__9B0F9FA0_1F04_11D2_9717_0000B4810A31__INCLUDED_
#if_MSC_VER>=1000
#pragmaonce
#endif//_MSC_VER>=1000
//注意:
不要修改你在这里看到的文件的内容。
如果该类是由VisualC++所创建的话,
//您在这里所作的修改将会被覆盖
/////////////////////////////////////////////////////////////////////////////
//CActiveMovie封装类
classCActiveMovie:
publicCWnd
{
protected:
DECLARE_DYNCREATE(CActiveMovie)
public:
CLSIDconst&GetClsid()
{
staticCLSIDconstclsid={0x5589fa1,0xc356,0x11ce,{0xbf,0x1,0x0,0xaa,0x0,0x55,0x59,0x5a}};
returnclsid;
}
virtualBOOLCreate(LPCTSTRlpszClassName,
LPCTSTRlpszWindowName,DWORDdwStyle,
constRECT&rect,
CWnd*pParentWnd,UINTnID,
CCreateContext*pContext=NULL)
{returnCreateControl(GetClsid(),lpszWindowName,dwStyle,rect,pParentWnd,nID);}
BOOLCreate(LPCTSTRlpszWindowName,DWORDdwStyle,
constRECT&rect,CWnd*pParentWnd,UINTnID,
CFile*pPersist=NULL,BOOLbStorage=FALSE,
BSTRbstrLicKey=NULL)
{returnCreateControl(GetClsid(),lpszWindowName,dwStyle,rect,pParentWnd,nID,
pPersist,bStorage,bstrLicKey);}
//Attributes
public:
//Operations
public:
voidAboutBox();
voidRun();
voidPause();
voidStop();
longGetImageSourceWidth();
longGetImageSourceHeight();
CStringGetAuthor();
CStringGetTitle();
CStringGetCopyright();
CStringGetDescription();
CStringGetRating();
CStringGetFileName();
voidSetFileName(LPCTSTRlpszNewValue);
doubleGetDuration();
doubleGetCurrentPosition();
voidSetCurrentPosition(doublenewValue);
longGetPlayCount();
voidSetPlayCount(longnNewValue);
doubleGetSelectionStart();
voidSetSelectionStart(doublenewValue);
doubleGetSelectionEnd();
voidSetSelectionEnd(doublenewValue);
longGetCurrentState();
doubleGetRate();
voidSetRate(doublenewValue);
longGetVolume();
voidSetVolume(longnNewValue);
longGetBalance();
voidSetBalance(longnNewValue);
BOOLGetEnableContextMenu();
voidSetEnableContextMenu(BOOLbNewValue);
BOOLGetShowDisplay();
voidSetShowDisplay(BOOLbNewValue);
BOOLGetShowControls();
voidSetShowControls(BOOLbNewValue);
BOOLGetShowPositionControls();
voidSetShowPositionControls(BOOLbNewValue);
BOOLGetShowSelectionControls();
voidSetShowSelectionControls(BOOLbNewValue);
BOOLGetShowTracker();
voidSetShowTracker(BOOLbNewValue);
BOOLGetEnablePositionControls();
voidSetEnablePositionControls(BOOLbNewValue);
BOOLGetEnableSelectionControls();
voidSetEnableSelectionControls(BOOLbNewValue);
BOOLGetEnableTracker();
voidSetEnableTracker(BOOLbNewValue);
BOOLGetAllowHideDisplay();
voidSetAllowHideDisplay(BOOLbNewValue);
BOOLGetAllowHideControls();
voidSetAllowHideControls(BOOLbNewValue);
longGetDisplayMode();
voidSetDisplayMode(longnNewValue);
BOOLGetAllowChangeDisplayMode();
voidSetAllowChangeDisplayMode(BOOLbNewValue);
LPUNKNOWNGetFilterGraph();
voidSetFilterGraph(LPUNKNOWNnewValue);
LPDISPATCHGetFilterGraphDispatch();
unsignedlongGetDisplayForeColor();
voidSetDisplayForeColor(unsignedlongnewValue);
unsignedlongGetDisplayBackColor();
voidSetDisplayBackColor(unsignedlongnewValue);
longGetMovieWindowSize();
voidSetMovieWindowSize(longnNewValue);
BOOLGetFullScreenMode();
voidSetFullScreenMode(BOOLbNewValue);
BOOLGetAutoStart();
voidSetAutoStart(BOOLbNewValue);
BOOLGetAutoRewind();
voidSetAutoRewind(BOOLbNewValue);
longGetHWnd();
longGetAppearance();
voidSetAppearance(longnNewValue);
longGetBorderStyle();
voidSetBorderStyle(longnNewValue);
BOOLGetEnabled();
voidSetEnabled(BOOLbNewValue);
BOOLIsSoundCardEnabled();
longGetReadyState();
};
//{{AFX_INSERT_LOCATION}}
#endif//!
defined
(AFX_ACTIVEMOVIE_H__9B0F9FA0_1F04_11D2_9717_0000B4810A31__INCLUDED_)
尽管我们可以由此得知由该ActiveX控件所提供的各个接口属性和方法的参数和返回值,但是,这些信息并不足以正确的使用该ActiveX控件。
一般来说,由第三方开发商提供的ActiveX控件都附带了对所提供的控件的各个接口属性和方法的说明及其与使用该控件进行程序设计所需的信息。
7.按表创建应用程序的菜单资源IDR_MENU。
接着使用属性对话框将应用程序主对话框的菜单资源设置为IDR_MENU。
8.设计用于音量调节的对话框,该对话框如图7.5所示,其资源ID为IDD_VOLUME。
设计完成之后使用ClassWizard为该对话框创建新的类CVolumeDlg,并为滑块控件映射类型为CSliderCtrl的成员变量m_sld。
根据下面的代码在完成类CVolumeDlg,该类提供了外部编程接口SetVolume,该公有成员函数使用一个指向CActiveMovie对象的指针作为其参数,所进行的音量调节作用于该控件。
这里需要注意的是,拖动或点击滑块控件时,向父窗口发送的消息是WM_HSCROLL,该消息的处理函数OnHScroll,传递给该处理函数的第二个参数的类型为CScrollBar*,我们需要使用强调类型转换将其转换为CSliderCtrl*,以便能正确的调用由CSliderCtrl对象所提供的各种成员函数。
表7.1应用程序VideoPlayer使用的菜单资源IDR_MENU
顶层菜单项
子菜单项
资源ID
文件(&F)
打开(&O)
ID_FILEOPEN
关闭(&C)
ID_FILECLOSE
具有Separator样式的菜单分隔符
退出(&X)
ID_FILEEXIT
播放(&P)
开始(&S)
ID_PLAYSTART
暂停(&P)
ID_PLAYPAUSE
停止(&T)
ID_PLAYSTOP
视频(&V)
原始大小(&O)
ID_VIDEO1X
原始大小的2倍(&T)
ID_VIDEO2X
音频(&A)
调节音量(&V)
ID_AUDEOVOLUME
调节左右声道平衡(&B)
ID_AUDEOBALANCE
帮助(&H)
关于
视频播放器(&A)ID_HELPABOUT
图7.5用于调节音量的对话框:
IDD_VOLUME
以下是类CVolumeDlg的代码清单。
为了节省篇幅和便于读者阅读和理解,我们删除了一些由AppWizard生成的代码和注释。
//VolumeDlg.h:
头文件
//
classCActiveMovie;
/////////////////////////////////////////////////////////////////////////////
//CVolumeDlg对话框
classCVolumeDlg:
publicCDialog
{
//构造
public:
voidSetVolume(CActiveMovie*pAmovie);
CVolumeDlg(CWnd*pParent=NULL);//标准构造函数
//{{AFX_DATA(CVolumeDlg)
enum{IDD=IDD_VOLUME};
CSliderCtrlm_sld;
//}}AFX_DATA
//重载
//{{AFX_VIRTUAL(CVolumeDlg)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDV支持
//}}AFX_VIRTUAL
//实现
protected:
CActiveMovie*m_pAmovie;
//{{AFX_MSG(CVolumeDlg)
virtualBOOLOnInitDialog();
afx_msgvoidOnHScroll(UINTnSBCode,UINTnPos,CScrollBar*pScrollBar);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//VolumeDlg.cpp:
实现文件
//
#include"stdafx.h"
#include"VideoPlayer.h"
#include"VolumeDlg.h"
#include"activemovie.h"
/////////////////////////////////////////////////////////////////////////////
//CVolumeDlg对话框
CVolumeDlg:
:
CVolumeDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CVolumeDlg:
:
IDD,pParent)
{
//{{AFX_DATA_INIT(CVolumeDlg)
//注意:
ClassWizard将在这里添加对成员的初始化代码
//}}AFX_DATA_INIT
}
voidCVolumeDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVolumeDlg)
DDX_Control(pDX,IDC_SLIDER1,m_sld);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVolumeDlg,CDialog)
//{{AFX_MSG_MAP(CVolumeDlg)
ON_WM_HSCROLL()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CVolumeDlg消息处理函数
BOOLCVolumeDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
//设置音量滑块的最小值和最大值、标度和当前位置等
m_sld.SetRange(-10000,0);
m_sld.SetTicFreq(1000);
m_sld.SetLineSize(200);
m_sld.SetPageSize(1000);
//以ActiveMovie控件的当前音量作为音量滑块的当前位置
m_sld.SetPos(m_pAmovie->GetVolume());
returnTRUE;
}
//提供给类外部的使用者的编程接口方法
voidCVolumeDlg:
:
SetVolume(CActiveMovie*pAmovie)
{
m_pAmovie=pAmovie;
//如果未加载任何媒体文件,则音量调节不可用。
ActiveMovie控件的CurrentState属
//性返回控件的当前状态,-1表示未加载任何文件,此时弹出出错提示信息
if(m_pAmovie->GetCurrentState()!
=-1)
{
DoM