WEB开发网
开发学院软件开发VC MFC程序员WTL指南(7)包容ActiveX控件 阅读

MFC程序员WTL指南(7)包容ActiveX控件

 2008-01-19 20:26:50 来源:WEB开发网   
核心提示:调用控件的方法既然我们的对话框有一个浏览器控件,我们可以使用COM接口与之交互,MFC程序员WTL指南(7)包容ActiveX控件(4),我们做得第一件事情就是使用IWebBrowser2接口将其引导到一个新URL处,在OnInitDialog()函数中,下面是_ATL_FUNC_INFO的定义:#define _AT

调用控件的方法

既然我们的对话框有一个浏览器控件,我们可以使用COM接口与之交互。我们做得第一件事情就是使用IWebBrowser2接口将其引导到一个新URL处。在OnInitDialog()函数中,我们将一个CAxWindow变量与包容控件的AtlAxWin联系起来。

CAxWindow wndIE = GetDlgItem(IDC_IE);

然后声明一个IWebBrowser2的接口指针并查询浏览器控件的这个接口,使用CAxWindow::QueryControl():

CComPtr<IWebBrowser2> pWB2;
HRESULT hr;
hr = wndIE.QueryControl ( &pWB2 );

QueryControl()调用浏览器控件的QueryInterface()方法,如果成功就会返回IWebBrowser2接口,我们可以调用Navigate():

if ( pWB2 )
     {
     CComVariant v; // empty variant
     pWB2->Navigate ( CComBSTR("http://www.codeproject.com/"),
             &v, &v, &v, &v );
     }
响应控件触发的事件

从浏览器控件得到接口非常简单,通过它可以单向的与控件通信。通常控件也会以事件的形式与外界通信,ATL有专用的类包装连接点和事件相应,所以我们可以从控件接收到这些事件。为使用对事件的支持需要做四件事:

  1. 将CMainDlg变成COM对象
  2. 添加IDispEventSimpleImpl到CMainDlg的继承列表
  3. 填写事件映射链,它指示哪些事件需要处理
  4. 编写事件响应函数
CMainDlg的修改

将CMainDlg转变成COM对象的原因是事件相应是基于IDispatch的,为了让CMainDlg暴露这个接口,它必须是个COM对象。IDispEventSimpleImpl提供了IDispatch接口的实现和建立连接点所需的处理函数,当事件发生时IDispEventSimpleImpl还调用我们想要接收的事件的处理函数。

以下的类需要添加到CMainDlg的集成列表中,同时COM_MAP列出了CMainDlg暴露的接口:

#include <exdisp.h>  // browser control definitions
#include <exdispid.h> // browser event dispatch IDs
class CMainDlg : public CAxDialogImpl<CMainDlg>,
         public CUpdateUI<CMainDlg>,
         public CMessageFilter, public CIdleHandler,
         public CComObjectRootEx<CComSingleThreadModel>,
         public CComCoClass<CMainDlg>,
         public IDispEventSimpleImpl<37, CMainDlg, &DIID_DWebBrowserEvents2>
{
...
  BEGIN_COM_MAP(CMainDlg)
   COM_INTERFACE_ENTRY2(IDispatch, IDispEventSimpleImpl)
  END_COM_MAP()
};

CComObjectRootEx类CComCoClass共同使CMainDlg成为一个COM对象,IDispEventSimpleImpl的模板参数是事件的ID,我们的类名和连接点接口的IID。事件ID可以是任意正数,连接点对象的IID是DIID_DWebBrowserEvents2,可以在浏览器控件的相关文档中找到这些参数,也可以查看exdisp.h。

填写事件映射链

下一步是给CMainDlg添加事件映射链,这个映射链将我们感兴趣的事件和我们的处理函数联系起来。我们要看的第一个事件是DownloadBegin,当浏览器开始下载一个页面时就会触发这个事件,我们响应这个事件显示“please wait”信息给用户,让用户知道浏览器正在忙。在MSDN中可以查到DWebBrowserEvents2::DownloadBegin事件的原型

void DownloadBegin();

这个事件没有参数,也不需要返回值。为了将这个事件的原型转换成事件响应链,我们需要写一个_ATL_FUNC_INFO结构,它包含返回值,参数的个数和参数类型。由于事件是基于IDispatch的,所以所有的参数都用VARIANT表示,这个数据结构的描述相当长(支持很多个数据类型),以下是常用的几个:

VT_EMPTY: void

VT_BSTR: BSTR 格式的字符串

VT_I4: 4字节有符号整数,用于long类型的参数

VT_DISPATCH: IDispatch*

VT_VARIANT>: VARIANT

VT_BOOL: VARIANT_BOOL (允许的取值是VARIANT_TRUE和VARIANT_FALSE)

另外,标志VT_BYREF表示将一个参数转换成相应的指针。例如,VT_VARIANT|VT_BYREF表示VARIANT*类型。下面是_ATL_FUNC_INFO的定义:

#define _ATL_MAX_VARTYPES 8
struct _ATL_FUNC_INFO
{
   CALLCONV cc;
   VARTYPE vtReturn;
   SHORT   nParams;
   VARTYPE pVarTypes[_ATL_MAX_VARTYPES];
};

参数:

cc 我们的事件响应函数的调用方式约定,这个参数必须是CC_STDCALL,表示是__stdcall方式 vtReturn 事件响应函数的返回值类型 nParams 事件带的参数个数 pVarTypes 相应的参数类型,按从左到右的顺序

上一页  1 2 3 4 5 6 7  下一页

Tags:MFC 程序员 WTL

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接