ATL 实现定制的 IE 浏览器栏、工具栏和桌面工具栏(二)

翻译|其它|编辑:郝浩|2006-03-02 12:09:00.000|阅读 2027 次

概述:

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>


3.3 选择实现的 COM 接口
  有两个接口不是必须实现的,但也许很有用:IInputObject 和 IContextMenu。如果 band 对象需要接收用户的输入,那么必须实现 IInputObject 接口。IE 实现了 IInputObjectSite 接口,当容器中有多个输入窗口时,它调用 IInputObject 接口方法去负责管理用户的输入焦点。

    在浏览器栏中需要实现3个函数:UIActivateIO()、HasFocusIO()、TranslateAcceleratorIO()。
当浏览器栏激活或失去活性的时候,IE 调用 UIActivateIO 函数,当激活的时候,浏览器栏一般调用 SetFocus 去设置它自己窗口的焦点。当 IE 需要判断哪个窗口有焦点的时候,它调用 HasFocusIO 。当浏览器栏的窗口或其子窗口有输入焦点时,则应返回 S_OK,否则返回 S_FALSE。TranslateAcceleratorIO 允许对象处理加速键,例子程序中没有实现,所以直接返回 S_FALSE。
STDMETHODIMP CExplorerBar::UIActivateIO(BOOL fActivate, LPMSG pMsg)
{
    if(fActivate)
    SetFocus(m_hWnd);

    return S_OK;
}

STDMETHODIMP CExplorerBar::HasFocusIO(void)
{
    if(m_bFocus)
    return S_OK;

    return S_FALSE;
}

STDMETHODIMP CExplorerBar::TranslateAcceleratorIO(LPMSG pMsg)
{
    return S_FALSE;
}
  Band 对象能够通过包容器的 IOleCommandTarget::Exec() 调用执行命令。而 IOleCommandTarget 接口指针,则可以通过调用包容器的 IInputOjbectSite::QueryInterface(IID_IOleCommandTarget,...) 函数得到。CGID_DeskBand 是命令组,当一个 band 对象的 GetBandInfo 被调用的时候,包容器通过 dwBandID 参数指定一个 ID 给 band 对象,对象要保存住这个ID,以便调用 IOleCommandTarget::Exec()的时候使用。ID 的命令有:
    DBID_BANDINFOCHANGED
    Band 的信息变化。设置参数 pvaIn 为 band ID, 该 ID 就是最近一次调用 GetBandInfo 所得到的值,容器会调用 band 对象的 GetBandInfo 函数来更新请求信息。
    DBID_MAXIMIZEBAND
    最大化 band。设置参数 pvaIn 为 band ID,该 ID 就是最近一次调用 ?GetBandInfo ?所得到的值。
    DBID_SHOWONLY
    打开或关闭容器中其它的 bands。 设置参数 pvaIn 为VT_UNKNOWN 类型,它可以是如下的值:

描述
pUnk band 对象的 IUnknown 指针,其它的桌面 bands 将被隐藏
0 隐藏所有的桌面 bands
1 显示所有的桌面 bands

    DBID_PUSHCHEVRON
在菜单项左边显示“v”的选择标志。容器发送一个 RB_PUSHCHEVRON 消息,当 band 对象接收到通知消息 RBN_CHEVRONPUSHED 提示它显示一个"v"的标志。设置 IOleCommandTarget::Exec 函数中 nCmdExecOpt 参数为 band ID,该 ID 是最近一次调用 GetBandInfo ?所得到的值,设置 IOleCommandTarget::Exec 函数中 pvaIn 参数为 VT_I4 类型,这是应用程序定义的一个值,它通过通知消息 RBN_CHEVRONPUSHED 中lAppValue 回传给 band 对象。

3.4 Band 对象注册
  Band 对象必须注册为一个 OLE 进程内的服务器,并且支持 apartment 线程公寓。注册表中默认键的值是表示菜单的文字。对于浏览器栏,它加到 IE 菜单的“查看\浏览器栏”中;对于工具栏 band ,它加到 IE 菜单的“查看\工具栏”中;对于桌面 band, 它加到系统任务栏的快捷菜单中。在菜单资源中,可以使用“&”指明加速键。

通常,一个基本的 band 对象的注册表项目是:

HKEY_CLASSES_ROOT
CLSID
{你的 band 对象的 CLSID}
  (Default) = 菜单的文字
  InProcServer32
   (Default) = DLL 的全路径文件名
   ThreadingModel= Apartment

工具栏 bands 还必须把它们的 CLSID 注册到 IE 的注册表中。

在 HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Toolbar 下给出 CLSID 作为键名,而其键值是被忽略的。

HKEY_LOCAL_MACHINE
Software
Microsoft
Internet Explorer
Toolbar
  {你的 band 对象的 CLSID}

  还有几个可选的注册表项目(例子程序并不是这样实现的)。比如,你想让浏览器栏显示 HTML 的话,必须要如下设置注册表:

HKEY_CLASSES_ROOT
CLSID
{你的 Band 对象的 CLSID}
Instance
CLSID
  (Default) = {4D5C8C2A-D075-11D0-B416-00C04FB90376}

同时,如果要指定一个本地的 HTML 文件,那么要如下设置:

HKEY_CLASSES_ROOT
CLSID
{你的 Band 对象的 CLSID}
Instance
InitPropertyBag
  Url

  另外,还可以指定浏览器栏的宽和高,当然,它是依赖于这个栏是纵向还是横向的。其实这个项目无所谓,因为当用户调整了浏览器栏的大小后,会自动保存在注册表中的。

HKEY_CURRENT_USER
Software
Microsoft
Internet Explorer
Explorer Bars
{你的 Band 对象的 CLSID}
  BarSize

  BarSize 键的类型必须是 REG_BINARY 类型,它有8个字节。左起前4个字节,是用16进制表示的像素宽度或高度,后4个字节保留,你应该设置为0。下面是一个可以在浏览器栏上显示 HTML 文件的全部注册表项目的例子,默认宽度为291(0x123)个像素点:

HKEY_CLASSES_ROOT
CLSID
{你的 Band 对象的 CLSID}
 (Default) = 菜单文字
 InProcServer32
  (Default) = DLL 的全路径文件名
  ThreadingModel= Apartment
Instance
CLSID
  (Default) = {4D5C8C2A-D075-11D0-B416-00C04FB90376}
InitPropertyBag
  Url= 你的 HTML 文件名

HKEY_CURRENT_USER
Software
Microsoft
Internet Explorer
Explorer Bars
{你的 Band 对象的 CLSID}
  BarSize= 23 01 00 00 00 00 00 00

  对于注册表的设置,用 ATL 实现其实是异常简单的。打开工程的 xxx.rgs 文件,并手工编辑一下就可以了。 下面这个文件源码,是例子程序中 IE 工具栏的注册表样式,HKLM 是需要手工添加的,因为它不使用组件类型方式注册。而对于其它类型的 band 对象只要在类声明中添加:

BEGIN_CATEGORY_MAP(Cxxx) // 向注册表中注册 COM 类型
IMPLEMENTED_CATEGORY(CATID_InfoBand) // 垂直样式的浏览器栏
END_CATEGORY_MAP()
IE 工具栏类型 band 对象的“.rgs”文件HKCR // 这个项目是 ATL 帮你生成的,你只要手工修改“菜单上的文字”就可以了
{
    Bands.ToolBar.1 = s ''ToolBar Class''
     {
         CLSID = s ''{ 你的 CLSID }''
     }
    Bands.ToolBar = s ''ToolBar Class''
     {
         CLSID = s ''{ 你的 CLSID }''
         CurVer = s ''Bands.ToolBar.1''
      }
    NoRemove CLSID
      {
           ForceRemove { 你的 CLSID } = s ''用在菜单上的文字(&T)''
            {
                ProgID = s ''Bands.ToolBar.1''
                VersionIndependentProgID = s ''Bands.ToolBar''
                ForceRemove ''Programmable''
                InprocServer32 = s ''%MODULE%''
                 {
                     val ThreadingModel = s ''Apartment''
                  }
              ''TypeLib'' = s ''{xxxx-xxxx-xxxxxxxxxxxxxxx}''
      }
   }
}

HKLM // 这个项目是手工添加的IE工具栏所特有的
{
   Software
     {
       Microsoft
           {
              ''Internet Explorer''
                {
                     NoRemove Toolbar
                       {
                           ForceRemove val { 你的 CLSID } = s ''随便给个说明性文字串''
                        }
                 }
            }
      }
}

四、 ATL 实现
  下载代码后(VC 6.0 工程),请参照前面的说明仔细阅读,代码中也有一些关键点的注释。如果想运行,则可以用 regsvr32.exe 进行注册,然后打开 IE 浏览器或资源浏览器就可以看到效果了。如果想自己实践一下,可以按照如下的步骤构造工程:

4.1 建立一个 ATL DLL 工程
4.2 添加 New ATL Object...,选择 Internet Explorer Object,选这个类型的目的是让向导给我们添加 IObjectWithSite 的支持。如果你使用的是 .net 环境,则不要忘记选择支持这个接口。



4.3 输入对象名称,比如我想建立一个垂直的浏览器栏,不妨叫它 VerBar



4.4 线程模型必须选择 Apartment,接口类型的选择无所谓,看你想不想支持 IDispatch 接口功能了。在例子程序中的垂直浏览器栏中,由于想更简单的操纵 IE 和从 IE 中接受事件(连接点),选择 Dual 是必要的。聚合选项,你只要别选择 Only 就可以了。



4.5 展现你无穷的智慧,开始输入程序吧。如果是 Debug 方式编译,可能会出现一个连接错误,报告找不到_AtlAxCreateControl,那么你要在菜单 Project\Settings...\Link 中增加对 Atl.lib 的连接。或者使用 #pragma comment ( lib, "atl" )加入连接库。
4.6 如果想调试代码,在菜单 Project\Settings...\Debug 中输入 IE 的路径名称,比如:“C:\Program Files\Internet Explorer\IEXPLORE.EXE”,然后就可以跟踪断点调试了。 编译和调试桌面工具栏的 band 对象,是非常麻烦的,因为计算机启动时自动运行 Shell,而 Shell 就会加载活动的桌面对象。

五、结束语
好了,到这里,就到这里了。祝大家学习快乐^_^
 


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP