⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wtl for mfc programmers, part vi - hosting activex controls - wtl.htm

📁 WT教程中文版 内有详细的介绍 包括各个方面
💻 HTM
📖 第 1 页 / 共 3 页
字号:
<html>
<head>
<title>WTL for MFC Programmers, Part VI - Hosting ActiveX Controls</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>

<body bgcolor="#33CCCC" text="#000000">
<p align="center"><b><font style="FONT-SIZE: 16pt" size="4" color="#0033CC">WTL 
  for MFC Programmers, Part VI - Hosting ActiveX Controls</font></b><br>
  <br>
</p>
<p align="left">原作 :<b><font color="#CC3366">Michael Dunn</font></b> [<a href="http://www.codeproject.com/wtl/WTL4MFC6.asp">英文原文</a>]<br>
  翻译 :<a href="mailto:inte2000@163.com">Orbit(桔皮干了)</a> [<a href="http://www.winmsg.com/cn/orbit.htm">http://www.winmsg.com/cn/orbit.htm</a>]</p>
<p align="left"><a href="demo/WTL4MFC6_demo.zip">下载演示程序代码</a></p>
 
<H2><font color="#FFFF66">本章内容</font></H2>
      <UL>
        <LI><A href="#intro">介绍</A> 
        <LI><A href="#appwizard">从使用向导开始</A> 
        <UL>
          <LI><A href="#createproject">建立工程</A> 
          <LI><A href="#appwizcode">自动生成的代码</A> </LI></UL>
        <LI><A href="#addreseditor">使用资源编辑器添加控件</A> 
        <LI><A href="#atlhostclasses">ATL中使用控件的类</A> 
        <UL>
          <LI><A href="#CAxDialogImpl">CAxDialogImpl</A> 
          <LI><A href="#AtlAxWin">AtlAxWin和CAxWindow</A> </LI></UL>
        <LI><A href="#callmethods">调用控件的方法</A> 
        <LI><A href="#sinkevents">响应控件触发的事件</A> 
        <UL>
          <LI><A href="#changemaindlg">CMainDlg的修改</A> 
          <LI><A href="#writesinkmap">填写事件映射链</A> 
          <LI><A href="#writehandler">编写事件处理函数</A> </LI></UL>
        <LI><A href="#sampleoverview">回顾例子工程</A> 
        <LI><A href="#runtimecreating">运行时创建ActiveX控件</A> 
        <LI><A href="#keyboard">键盘事件处理</A> 
        <LI><A href="#upnext">继续</A> 
        <LI><A href="#revisionhistory">修改记录</A> </LI></UL>
      
<H2><A name=intro></A><font color="#FFFF66">介绍</font></H2>
      
<P>在第六章,我将介绍ATL对在对话框中使用ActiveX控件的支持,由于ActiveX控件就是ATL的专业,所以WTL没有添加其他的辅助类。不过,在ATL中使用ActiveX控件与在MFC中有很大的不同,所以需要重点介绍。我将介绍如何包容一个控件并处理控件的事件,开发ATL应用程序相对于MFC的类向导来说有点不方便。在WTL程序中自然可以使用ATL对包容ActiveX控件的支持。</P>
<p>例子工程演示如何使用IE的浏览器控件,我选择浏览器控件有两个好处:</p>
<OL>
        
  <LI>每台计算机都有这个控件,并且
  <LI>它有很多方法和事件,是个用来做演示的好例子。</LI>
</OL>
      
<P>我当然无法与那些花了大量时间编写基于IE浏览器控件的定制浏览器的人相比,不过,当你读完本篇文章之后,你就知道如何开始编写自己定制的浏览器!</P>
<H2><A name=appwizard></A><font color="#FFFF66">从使用向导开始</font></H2>
      
<H3><A name=createproject></A><font color="#FFFF66">创建工程</font></H3>
      
<P>WTL的向导可以创建一个支持包容ActiveX控件的程序,我将开始一个名为IEHoster的新工程。我们像上一章一样使用无模式对话框,只是这次要选上支持ActiveX控件包容(Enable 
  ActiveX Control Hosting),如下图:</P>
      
<P><IMG height=387 alt=" [AppWizard - 22K] " 
      src="images/appwiz6.png" 
      width=477 align=bottom border=0></P>
      
<P>选上这个check box将使我们的对话框从CAxDialogImpl派生,这样就可以包容ActiveX控件。在向导的第二页还有一个名为包容ActiveX控件的check 
  box,但是选择这个好像对最后的结果没有影响,所以在第一页就可以点击“Finish”结束向导。</P>
<H3><A name=appwizcode></A><font color="#FFFF66">向导生成的代码</font></H3>
      
<P>在这一节我将介绍一些以前没有见过的新代码(由向导生成的),下一节介绍ActiveX包容类的细节。</P>
<p>首先要看的文件是stdafx.h,它包含了这些文件:</p>
<PRE><SPAN class=cpp-preprocessor><font color="#0033FF">#include &lt;atlbase.h&gt;</font></SPAN>
<font color="#0033FF"><SPAN class=cpp-preprocessor>#include &lt;atlapp.h&gt;</SPAN>
 
<SPAN class=cpp-keyword>extern</SPAN> CAppModule _Module;
 
<SPAN class=cpp-preprocessor>#include &lt;atlcom.h&gt;</SPAN>
<SPAN class=cpp-preprocessor>#include &lt;atlhost.h&gt;</SPAN>
<SPAN class=cpp-preprocessor>#include &lt;atlwin.h&gt;</SPAN>
<SPAN class=cpp-preprocessor>#include &lt;atlctl.h&gt;</SPAN>
<SPAN class=cpp-comment>// .. other WTL headers ...</SPAN></font></PRE>
      
<P>atlcom.h和atlhost.h是很重要的两个,它们含有一些COM相关类的定义(比如智能指针CComPtr),还有可以包容控件的窗口类。</P>
<p>接下来看看maindlg.h中声明的CMainDlg类:</p>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">class</font></SPAN><font color="#0033FF"> CMainDlg : <SPAN class=cpp-keyword>public</SPAN> CAxDialogImpl&lt;CMainDlg&gt;,
                 <SPAN class=cpp-keyword>public</SPAN> CUpdateUI&lt;CMainDlg&gt;,
                 <SPAN class=cpp-keyword>public</SPAN> CMessageFilter, <SPAN class=cpp-keyword>public</SPAN> CIdleHandler</font></PRE>
      
<P>CMainDlg现在是从CAxDialogImpl类派生的,这是使对话框支持包容ActiveX控件的第一步。</P>
<p>最后,看看WinMain()中新加的一行代码:</p>
<PRE><SPAN class=cpp-keyword><font color="#0033FF">int</font></SPAN><font color="#0033FF"> WINAPI _tWinMain(...)
{
<SPAN class=cpp-comment>//...</SPAN>
    _Module.Init(NULL, hInstance);
 
    <B>AtlAxWinInit();</B>
 
    <SPAN class=cpp-keyword>int</SPAN> nRet = Run(lpstrCmdLine, nCmdShow);
 
    _Module.Term();
    <SPAN class=cpp-keyword>return</SPAN> nRet;
}</font></PRE>
      
<P>AtlAxWinInit()注册了一个类名未AtlAxWin的窗口类,ATL用它创建ActiveX控件的包容窗口。</P>
<H2><A name=addreseditor></A><font color="#FFFF66">使用资源编辑器添加控件</font></H2>
      
<P>和MFC的程序一样,ATL也可以使用资源编辑器向对话框添加控件。首先,在对话框编辑器上点击鼠标右键,在弹出的菜单中选择“Insert ActiveX 
  control”:</P>
      
<P><IMG height=345 alt=" [Insert menu - 8K] " 
      src="images/insertmenu6.png" 
      width=355 align=bottom border=0></P>
      
<P>VC将系统安装的控件显示在一个列表中,滚动列表选择“Microsoft Web Browser”,单击Insert按钮将控件加入到对话框中。查看控件的属性,将ID设为IDC_IE。对话框中的控件显示应该是这个样子的:</P>
      
<P><IMG height=244 alt=" [ IE control in editor - 6K] " 
      src="images/iectrl6.png" 
      width=350 align=bottom border=0></P>
      
<P>如果现在编译运行程序,你会看到对话框中的浏览器控件,它将显示一个空白页,因为我们还没有告诉它到哪里去。</P>
<p>在下一节,我将介绍与创建和包容ActiveX控件有关的ATL类,同时我们也会明白这些类是如何与浏览器交换信息的。</p>
<H2><A name=atlhostclasses></A><font color="#FFFF66">ATL中使用控件的类</font></H2>
      
<P>在对话框中使用ActiveX控件需要两个类协同工作:CAxDialogImpl和CAxWindow。它们处理所有控件容器必须实现的接口方法,提供通用的功能函数,例如查询控件的某个特殊的COM接口。</P>
      <H3><A name=CAxDialogImpl></A><font color="#FFFF66">CAxDialogImpl</font></H3>
      
<P>第一个类是CAxDialogImpl,你的对话框要能够包容控件就必须从CAxDialogImpl类派生而不是从CDialogImpl类派生。CAxDialogImpl类重载了Create()和DoModal()函数,这两个函数分别被全局函数AtlAxCreateDialog()和AtlAxDialogBox()调用。既然IEHoster对话框是由Create()创建的,我们看看AtlAxCreateDialog()到底做了什么工作。</P>
<p>AtlAxCreateDialog()使用辅助类_DialogSplitHelper装载对话框资源,这个辅助类遍历所以对话框的控件,查找由资源编辑器创建的特殊的入口,这些特殊的入口表示这是一个ActiveX控件。例如,下面是IEHoster.rc文件中浏览器控件的入口:
<PRE><font color="#0033FF">CONTROL <SPAN class=cpp-string>""</SPAN>,IDC_IE,<SPAN class=cpp-string>"{8856F961-340A-11D0-A96B-00C04FD705A2}"</SPAN>,
        WS_TABSTOP,<SPAN class=cpp-literal>7</SPAN>,<SPAN class=cpp-literal>7</SPAN>,<SPAN class=cpp-literal>116</SPAN>,<SPAN class=cpp-literal>85</SPAN></font></PRE>
      
<P>第一个参数是窗口文字(空字符串),第二个是控件的ID,第三个是窗口的类名。_DialogSplitHelper::SplitDialogTemplate()函数找到以'{'开始的窗口类名时就知道这是一个ActiveX控件的入口。它在内存中创建了一个临时对话框模板,在这个新模板中这些特殊的控件入口被创建的AtlAxWin窗口代替,新的入口是在内存中的等价体:</P>
<PRE><font color="#0033FF">CONTROL <SPAN class=cpp-string>"{8856F961-340A-11D0-A96B-00C04FD705A2}"</SPAN>,IDC_IE,<SPAN class=cpp-string>"AtlAxWin"</SPAN>,
        WS_TABSTOP,<SPAN class=cpp-literal>7</SPAN>,<SPAN class=cpp-literal>7</SPAN>,<SPAN class=cpp-literal>116</SPAN>,<SPAN class=cpp-literal>85</SPAN></font></PRE>
      
<P>结果就是创建了一个相同ID的AtlAxWin窗口,窗口的标题是ActiveX控件的GUID。所以你调用GetDlgItem(IDC_IE)返回的值是AtlAxWin窗口的句柄而不是ActiveX控件本身。</P>
      
<P>SplitDialogTemplate()函数完成工作后,AtlAxCreateDialog()接着调用CreateDialogIndirectParam()函数使用修改后的模板创建对话框。</P>
      
<H3><A name=AtlAxWin></A><font color="#FFFF66">AtlAxWin and CAxWindow</font></H3>
      
<P>正如上面讲到的,AtlAxWin实际上是ActiveX控件的宿主窗口,AtlAxWin还会用到一个特殊的窗口接口类:CAxWindow,当AtlAxWin从模板创建一个对话框后,AtlAxWin的窗口处理过程,AtlAxWindowProc(),就会处理WM_CREATE消息并创建相应的ActiveX控件。ActiveX控件还可以在运行其间动态创建,不需要对话框模板,我会在后面介绍这种方法。</P>
      
<P>WM_CREATE的消息处理函数调用全局函数AtlAxCreateControl(),将AtlAxWin窗口的窗口标题作为参数传递给该函数,大家应该记得那实际就是浏览器控件的GUID。AtlAxCreateControl()有会调用一堆其他函数,不过最终会用到CreateNormalizedObject()函数,这个函数将窗口标题转换成GUID,并最终调用CoCreateInstance()创建ActiveX控件。</P>
      
<P>由于ActiveX控件是AtlAxWin的子窗口,所以对话框不能直接访问控件,当然CAxWindow提供了这些方法通控件通信,最常用的一个是QueryControl(),这个方法调用控件的QueryInterface()方法。例如,你可以使用QueryControl()从浏览器控件得到IWebBrowser2接口,然后使用这个接口将浏览器引导到指定的URL。</P>
<H2><A name=callmethods></A><font color="#FFFF66">调用控件的方法</font></H2>
      
<P>既然我们的对话框有一个浏览器控件,我们可以使用COM接口与之交互。我们做得第一件事情就是使用IWebBrowser2接口将其引导到一个新URL处。在OnInitDialog()函数中,我们将一个CAxWindow变量与包容控件的AtlAxWin联系起来。</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -