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

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

 2008-01-19 20:26:50 来源:WEB开发网   
核心提示:了解这些之后,我们就可以填写DownloadBegin事件处理的_ATL_FUNC_INFO结构:_ATL_FUNC_INFO DownloadInfo = { CC_STDCALL, VT_EMPTY, 0 };现在,MFC程序员WTL指南(7)包容ActiveX控件(5),回到事件响应链,我们为每一个我们想要处理的

了解这些之后,我们就可以填写DownloadBegin事件处理的_ATL_FUNC_INFO结构:

_ATL_FUNC_INFO DownloadInfo = { CC_STDCALL, VT_EMPTY, 0 };

现在,回到事件响应链,我们为每一个我们想要处理的事件添加一个SINK_ENTRY_INFO宏,下面是处理DownloadBegin事件的宏:

class CMainDlg : public ...
{
...
  BEGIN_SINK_MAP(CMainDlg)
   SINK_ENTRY_INFO(37, DIID_DWebBrowserEvents2, DISPID_DOWNLOADBEGIN,
           OnDownloadBegin, &DownloadInfo)
  END_SINK_MAP()
};

这个宏的参数是事件的ID(37,与我们在IDispEventSimpleImpl的继承列表中使用的ID一样),事件接口的IID,事件的dispatch ID(可以在MSDN或exdispid.h头文件中查到),事件处理函数的名字和指向描述这个事件处理的_ATL_FUNC_INFO结构的指针。

编写事件处理函数

好了,等了这么长时间(吹个口哨!),我们可以写事件处理函数了:

void __stdcall CMainDlg::OnDownloadBegin()
{
  // show "Please wait" here...
}

现在来看一个复杂一点的事件,比如BeforeNavigate2,这个事件的原型是:

void BeforeNavigate2 (
   IDispatch* pDisp, VARIANT* URL, VARIANT* Flags,
   VARIANT* TargetFrameName, VARIANT* PostData,
   VARIANT* Headers, VARIANT_BOOL* Cancel );

此方法有7个参数,对于VARIANT类型参数可以从MSDN查到它到底传递的是什么类型的数据,我们感兴趣的是URL,是一个BSTR类型的字符串。

描述BeforeNavigate2事件的_ATL_FUNC_INFO结构是这样的:

_ATL_FUNC_INFO BeforeNavigate2Info =
   { CC_STDCALL, VT_EMPTY, 7,
     { VT_DISPATCH, VT_VARIANT|VT_BYREF, VT_VARIANT|VT_BYREF,
      VT_VARIANT|VT_BYREF, VT_VARIANT|VT_BYREF, VT_VARIANT|VT_BYREF,
      VT_BOOL|VT_BYREF }
};

和前面一样,返回值类型是VT_EMPTY表示没有返回值,nParams是7,表示有7个参数。接着是参数类型数组,这些类型前面介绍过了,例如VT_DISPATCH表示IDispatch*。

事件响应链的入口与前面的例子很相似:

BEGIN_SINK_MAP(CMainDlg)
   SINK_ENTRY_INFO(37, DIID_DWebBrowserEvents2, DISPID_DOWNLOADBEGIN,
           OnDownloadBegin, &DownloadInfo)
   SINK_ENTRY_INFO(37, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2,
           OnBeforeNavigate2, &BeforeNavigate2Info)
  END_SINK_MAP()

事件处理函数是这个样子:

void __stdcall CMainDlg::OnBeforeNavigate2 (
   IDispatch* pDisp, VARIANT* URL, VARIANT* Flags,
   VARIANT* TargetFrameName, VARIANT* PostData,
   VARIANT* Headers, VARIANT_BOOL* Cancel )
{
CString sURL = URL->bstrVal;
  // ... log the URL, or whatever you''d like ...
}

我打赌你现在是越来越喜欢ClassWizard了,因为当你向MFC的对话框插入一个ActiveX控件时ClassWizard自动为你完成了所有工作。

将CMainDlg转换成对象需要注意几件事情,首先必须修改全局函数Run(),现在CMainDlg是个COM对象,我们必须使用CComObject创建CMainDlg:

int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
   CMessageLoop theLoop;
   _Module.AddMessageLoop(&theLoop);
CComObject<CMainDlg> dlgMain;
   dlgMain.AddRef();
   if ( dlgMain.Create(NULL) == NULL )
     {
     ATLTRACE(_T("Main dialog creation failed!\n"));
     return 0;
     }
   dlgMain.ShowWindow(nCmdShow);
   int nRet = theLoop.Run();
   _Module.RemoveMessageLoop();
   return nRet;
}

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

Tags:MFC 程序员 WTL

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