分类: C/C++
2008-03-18 15:30:12
概要介绍:
Band对象有三类:Desk,Info和Comm以及Tools Bands。其中Desk Bands 用于任务栏;Info和Comm--又称浏览栏(Explorer Bar)--用于IE和资源管理器。Tools Bands用于资源管理器或IE的工具栏。本文的例子代码 MyBands.dll 实现了上述前面两种类型的Band对象应用,并介绍了如何在自己的程序中使用 Bands 对象。由于Tools Bands是IE5以后才有的新特性。有关它的实现细节将在另外一篇文章中介绍,关于 Bands 对象的基本概念请参考另外一篇MSDN译文“Windows区对象(Bands)的创建与定制”。
不久以前,有个朋友问我如何在任务栏里添加编辑框控制。他的思路是想获取任务栏的 HWND,然后将编辑框作为子窗口加到任务栏。我当时就断了他的想法:原因是不能再用过去那种龌龊的方法对现在的系统进行编程。如今的操作系统用COM高度集成,正确的方法应该是利用COM所提供的特性或接口与操作系统进行友善的沟通。
“请把菜单给我好吗?” “噢,当然可以,” “请拿好菜单。” “请现在执行这个命令好吗?” “没问题,由IContextMenu来做吧。” ......完成这些工作只需要外壳扩展中各种各样层出不穷的一个小小接口之一就能搞掂。
在这个编辑框中输入要查找的内容,然后按回车键,系统就会启动默认的浏览器并且用你在编辑框的上下文菜单中指定的Web搜索引擎进行查找。你还可以将这个Web搜索框拖到桌面,这时它就变成了一个普通窗口,如图二所示:
图二 任务栏中的Web搜索框变成了一个普通对话框
实现Web搜索框的程序是 Mybands.dll,它是一个DLL。聪明人肯定会问,这个DLL的名字怎么有复数形式?因为它实现了所有三种类型的Band应用。这三种Band对象就是本文前面提到过的:Desk Bands,info/comm和Tools Bands。注意:IE5之后,微软将info/comm类型的Bands统称为Explorer Bars——浏览栏——用于IE或资源管理器--它包括垂直型和水平型,IE以及资源管理器"查看"菜单中"浏览栏"的"历史记录","收藏夹","搜索"(如图三)都属于info类型或者Explorer Bar类型的Bands应用。Tool Bands是IE5新增加的一种Band类型----工具栏Bands。
图三 其它形式的Bands
安装Mybands.dll的方法如下:下载源代码,编译后将dll拷到Windows的系统目录(system或system32),然后将它注册到系统中,方法是:
regsvr32.exe Mybands.dll
注册成功后,在IE或资源管理器的"查看"=〉"工具栏"和"浏览栏"菜单中会出现Bands的菜单项,如图三所示。显示Desk Band需要一点小技巧:必须重新启动资源管理器进程(针对Windows 9x。Windows 2000,Windows XP不需要)。方法是:按组合键"Ctrl+Atl+Del",删除掉资源管理器进程,重启之后你就可以在任务栏的上下文菜单的"工具栏"中看到Desk Band菜单项了如图四:
图四
使用BandObj编写band对象是很容易的,就以MyBands为例,它由几个模块组成,但只有一个模块是编写band对象的重点,那就是主模块:MyBands.cpp。MyBands由一个叫的App类,它派生于CBandObjDll(BandObj.h),而CBandObjDll又派生于MFC的COleControlModule。它们之间的派生关系为:
CWinApp COleControlModule CBandObjDll CBandObjDll
BOOL CMyBandsDll::InitInstance() { AddBandClass(CLSID_MYINFOBAND, RUNTIME_CLASS(CMyInfoBand), CATID_InfoBand, IDR_INFOBAND); AddBandClass(CLSID_MYCOMMBAND, ...); AddBandClass(CLSID_MYDESKBAND, ...); return CBandObjDll::InitInstance(); }它类似于DOC/VIEW,只是DOC/VIEW调用的是AddDocTemplate,而不是AddBandClass。对于每一个Band类,必须提供这个类的ID(GUID),MFC运行时类,种类(category)和资源IDs。种类ID就是一个GUID,它告诉Windows你的类是哪一种Band--是info,comm(Explorer Bar)还是Desk Band。从代码中不难看出,MyBands使用单独的类来处理每一种Band。CMyInfoBand,CMyCommBand,和 CMyDeskBand,它们都派生于CBandObj,并且都使用DECLARE/IMPLEMENT_DYNCREATE,这样MFC就能用其通常的运行时机制和COleObjectFactory来动态创建实例。它们都具有构造函数来负责初始化DESKBANDINFO结构中有关Band的信息及CBandObj::m_dbiDefault。例如,Desk Band有一个默认的宽度(100)及变高。
CMyDeskBand::CMyDeskBand() : CBandObj(CLSID_MYDESKBAND) { m_dbiDefault.ptActual = CPointL(100,0); m_dbiDefault.dwModeFlags = DBIMF_VARIABLEHEIGHT; }Explorer Bar 有固定高度30个像素,且没有标题。
CMyCommBand::CMyCommBand() : CBandObj(CLSID_MYCOMMBAND) { m_strTitle.Empty(); m_dbiDefault.ptMinSize = CPointL(0,30); m_dbiDefault.ptMaxSize = CPointL(-1,30); }不管你相不相信,MyBands中真正与Band对象有关的东西就这些。剩下的内容无非就是实现Band行为以及一些常规的MFC应用处理。如:CMyDeskBand中OnCreate处理函数的作用是创建编辑框控制,CMyCommBand中WM_PAINT处理函数的作用是绘制有关信息:
void CMyCommBand::OnPaint() { CPaintDC dc(this); dc.DrawText("欢迎访问VC知识库!"); }Band对象不像框架有最上层菜单,但如果你愿意的话可以为它添加上下文菜单。繁琐的细节都由CBandObj来处理。这时MyBands必须用与Band类相同的资源ID来创建菜单。命令会神奇般地通过所有正常渠道到达MyBands的ON_COMMAND处理函数。如果不是有GUIDs和种类(category)IDs,你很难了解MyBands是一个COM对象。CBandObj隐藏了全部的细节,留下一个自由的空间让你编写自己的Band。这就是我的最终目的所在。(待续)