工具条研究手记(2) - 认识CToolBar工具条类

工具条研究手记(2) - 认识CToolBar工具条类
作者:佚名    文章来源:VC知识库    点击数: <script src="http://www.91tech.net/Article/GetHits.asp?ArticleID=5406"></script> 384    更新时间:2008-11-27
*****************************************************************/
/*        工具条研究手记(2) - 认识CToolBar工具条类               */
/*****************************************************************/

一、首先来看工具条类的派生关系

工具条类的派生关系如下:
//---------------------------
 CObject
          |_____CCmdTarget
                   |______CWnd
                            |____CControlBar
                                    |_____CToolBar
//----------------------------
由于这样的继承关系,工具条类具有下列的特点和功能:

(1)从CObject继承来的功能
   a. 串行化支持
   b. 运行时刻的类信息
   c. 对象诊断输出
   d. 兼容 collection 类
 
如果在继承类的实现和声明中,使用了一些预定义宏,则派生类就可以实现CObject类的许多优点,
包括:
   a.一级宏 DECLARE_DYNAMIC和IMPLEMENT_DYNAMIC。使用该宏,将允许在运行时刻访问类的名字和它在继承表中的位置,也就意味着可以用来进行诊断。
   b.二级宏 DECLARE_SERIAL 和 IMPLEMENT_SERIAL。该宏涵盖了一级宏的所有功能,并允许对象可以通过archive进行串行化。

(2)从CCmdTarget继承来的功能
CCmdTarget是MFC中所有具备消息循环的类的基类,主要包括CView, CWinApp, CDocument, CWnd, 和CFrameWnd。
除了消息循环,该类还提供了:
   a. 漏斗鼠标
   b. Dispatch映射,用于ole自动化中的IDispatch 函数,为VB调用提供了接口
(3)从CWnd类继承的功能
 CWnd 类提供可所有MFC库中窗口类的基本功能,CWnd类与windows下的窗口是有所区别的,但是两者有紧密的联系:CWnd类的构造函数和析构函数生成 和销毁一个CWnd对象,窗口对象是CWnd类的Create函数生成的,在它的虚析构函数中销毁窗口对象。 DestroyWindow 函数也可以销毁窗口对象,但是不是CWnd对象。

 CWnd类以及它的消息映射机制隐藏了WndProc函数,所有Windows消息被自动通过消息映射表转发到相应的OnMessage成员函数。应该在派生类中重载OnMessage成员函数来处理某个特定的消息。这意味着工具条可以有自己的消息映射表。

 除此以外,CWnd还提供了很多功能,比如绘图,输出文字,设置菜单等等,但是某些功能在工具条中不能用,后面将通过剖析其源代码进行分析。

(4)从CControlBar继承的功能

 CControlBar 是控制条类的基类,包括 CStatusBar, CToolBar, CDialogBar, CReBar 和COleResizeBar. 一个控制条窗口通常位于一个框架窗口的左侧或者右侧。它可以包含一些子项,有些是
窗口控件,比如列表框和编辑框,负责产生和响应Windows 消息,有些是非窗口控件,比如状态条面板和位图由应用程序和框架负责管理。

 控制条窗口通常是一个框架窗口的子窗口,和客户区视窗口或者MDI客户区处于同一个地位。因此控制条
使用父窗口的客户区矩形信息来定位自己。而且负责把剩余的未使用的客户区大小通知父窗口。

二、使用CToolBar类
 
 CToolbar对象具有一行位图按钮和可选的分割条,这些按钮的行为和下压按钮,check-box按钮和单选按钮一样。CToolBar对象通常嵌入 CFrameWnd 或者 CMDIFrameWnd对象里面。

 CToolBar类的成员函数GetToolBarCtrl允许你使用Windows通用控件支持的特性来设计工具条或者添加额外的功能。 CToolBar的成员函数已经提供了Windows通用控件的大多数功能,如果你调用GetToolBarCtrl,会返回一个 CToolBarCtrl对象的引用,利用它可以实现 Windows 95工具条的许多特性。

Visual C++ 提供了两种生成工具条的方法:
要生成一个工具条,应该遵循下面的步骤:
1、生成一个工具条资源
2、构造工具条对象
3、调用 Create (或者 CreateEx) 函数生成一个工具条窗口,并把它关联到 CToolBar对象。
4、调用 LoadToolBar 函数加载工具条的资源。

或则采用下面的步骤:
1、构造一个工具条对象。
2、调用 Create (或者 CreateEx) 函数生成一个工具条窗口,并把它关联到 CToolBar对象。
3、调用 LoadBitmap 函数来加载包含工具条按钮图片的位图。
4、调用 SetButtons 函数来设置工具条按钮的样式并且把每个按钮与位图中的某个图片相关联。

一个工具条中的所有图片都来自于一个位图,该位图应该至少为每个按钮提供一个图片,所有的图片必需是相同的尺寸,缺省定义是 16 象素宽,15 象素高。在位图中,图片必需一个挨着一个。

 SetButtons 函数使用一个指向 控制ID的数组指针和一个给出id数目的整数。该函数把工具条每个按钮的id设置成数组中对应的值,并且为每个按钮分配一个图片。如果数组中包含ID_SEPARATOR的项,则不会给它关联图片。

 通常图片的顺序就是他们在屏幕上画的顺序,但是你可以通过函数SetButtonInfo来改变这个顺序。

 一个工具条的所有按钮都是相同的尺寸。缺省定义是 24 x 22 象素,迎合了 Windows 软件设计接口规范的要求。在图片和按钮之外的其它多余空间是用来生成一个边框。

 每个按钮有一个图片。不同的按钮状态和属性下 (压下,抬起,禁用,激活,以及中间态)的图片都从那个图片产生。虽然图片可以用任何颜色,但是带有灰色阴影的黑色图片效果最好。

 工具条上的按钮初始状态都是下压按钮。然而,它们可以改成check-box 按钮或者单选按钮。Check-box 按钮具有三个状态:选中,清除和中间态,单选按钮只有两个状态:选中和清除。

 要设置一个按钮或者分隔条的属性,可以通过函数 GetButtonStyle获得属性,然后调用 SetButtonStyle进行设置,而不用SetButtons。 SetButtonStyle函数在运行时刻改变按钮的属性十分好用。

 要在按钮上显示文字,可以通过函数 GetButtonText获取文字,调用 SetButtonText设置文字。

  要生成一个 check-box 按钮,只需加上 TBBS_CHECKBOX属性,或者在 ON_UPDATE_COMMAND_UI 处理函数中使用CCmdUI对象的SetCheck函数设置。只要调用SetCheck函数就会自动把下压按钮改变成为check-box按钮。

 要生成一个单选按钮,可以在ON_UPDATE_COMMAND_UI处理函数中,调用CCmdUI对象的SetRadio函数。为了提供一组单选按钮的排它功能,你必须为该组的所有按钮都生成ON_UPDATE_COMMAND_UI处理函数。

三、关于通用控制条的认识(来自技术备忘录31:控制条)

本文所论及的内容包括MFC中的控制条类:
 CControlBar, CStatusBar, CToolBar, CDialogBar, 和 CDockBar.
(一)CControlBar

 ControlBar 派生自 CWnd,通常定位于框架窗口的顶端或者底部。它可以包含窗口类的子项,比如 CDialogBar,或者非窗口类的子项,比如CToolBar和 CStatusBar。

 控制条支持的样式包括:

 CBRS_TOP   (缺省的)位于顶部
 CBRS_BOTTOM  放置在底部
 CBRS_NOALIGN 在父窗口尺寸变化的时候,不要重新定位控制条

 从 CControlBar派生的类提供了更加有趣的功能:

 (a) 状态条CStatusBar ,它的子项是包含文字的面板
 (b) 工具条CToolBar ,对于工具条来说,子项是排列成一行的位图按钮
 (c)  对话框条CDialogBar 象一个框架一样的工具条,包括标准windows控件 (从一个对话框模板资源生成)
 (d)  CDockBar,可以认为它是为其它控制条类提供对接区域的一个区域。该类的成员函数和变量在将来可能还要变化。

  记住:所有的控制条对象必需是某个框架窗口的子窗口。通常它们被作为框架客户区(例如,一个MDI客户区或者一个视窗口)的同级窗口。对于一个控制条来 说,它的子窗口ID是非常重要的。仅仅当它的ID的值位于AFX_IDW_CONTROLBAR_FIRST和 AFX_IDW_CONTROLBAR_LAST之间时,控制条的缺省布局才能起作用。

#define AFX_IDW_CONTROLBAR_FIRST        0xE800
#define AFX_IDW_CONTROLBAR_LAST         0xE8FF

注意,虽然一共有256个控制条ID,前面的32个是做特殊用途的,它们直接被打印预览结构支持。

 CControlBar类提供了
 A.在框架窗口里面定位工具条的标准实现。
 B.分配控制条项队列
 C.支持派生类的实现

 C++ 控制条对象通常作为成员嵌入一个CFrameWnd派生类对象中。而且当父窗口销毁的时候,它也被清除。如果你想在堆中分配一个控制条对象,你可以将它的 m_bAutoDestruct成员设置成 TRUE,从而当HWND销毁的时候允许它 “delete this”。

 重要提示:如果你派生了自己的控制条对象,则必须重载Create函数,在其中设置 m_dwStyle数据成员,例如:

// CMyControlBar is derived from CControlBar
BOOL CMyControlBar::Create( CWnd* pParentWnd, DWORD dwStyle, UINT nID )
{
   m_dwStyle = dwStyle;

   .
   .
   .
}

(二)控制条的布局原理

 控制条的布局原理非常简单,框架窗口按照 Z-顺序发送消息 WM_SIZEPARENT给所有控制条子窗口,并跟随这个消息传递一个父窗口客户区矩形的指针。控制条使用这个矩形信息来定位自己,并且把父窗口的客户 区尺寸减小,剩下的是正常的客户区域,用于定位主要的客户区窗口,通常是一个MDI客户区,视或者拆分窗口。

 详细情况可以参考 CWnd::RepositionBars 和 CFrameWnd::RecalcLayout 两个函数。

 MFC 私有窗口消息,包括WM_SIZEPARENT,都在技术备忘录24中说明。


(三)工具条

工具条支持两种按钮: 下压按钮和check box按钮。通过使用check box按钮组加上适当的ON_UPDATE_COMMAND_UI处理,可以得到单选按钮组的功能。

工具条中的所有按钮的图片都取自同一个位图。每个按钮尺寸相同(缺省尺寸是24x22象素大小),每个按钮的图片尺寸相同而且相连, 图片的缺省大小是16x15象素,所以如果一个工具条具有10个按钮,则需要位图的尺寸是160象素宽,15 象素高。

工具条按钮的所有状态的图片都是通过一定的算法从那一个图片中转换得到。因此,虽然理论上按钮图片可以使用任何颜色,但是对于这个算法来说,如果原始图片使用灰色阴影效果比较好。

项              Windows 颜色           缺省RGB值
工具条背景      COLOR_BTNFACE          RGB(192, 192, 192)
工具条左/上边框 COLOR_BTNHIGHLIGHT     RGB(255, 255, 255)
工具条右/下边框 COLOR_BTNSHADOW        RGB(128, 128, 128)

对工具条的 CCmdUI 支持:

工具条按钮的更新是通过空闲时刻调用 ON_UPDATE_COMMAND_UI 完成的。通过这个函数可以:

1、允许/禁止工具条按钮。
2、设置按钮为check状态。注意调用SetCheck函数会把按钮变成check box 按钮。
3、SetRadio: 设置类似单选按钮的功能。

工具条按钮会象正常的按钮一样发送WM_COMMAND消息,通常被一个ON_COMMAND函数处理。

工具条按钮一共有四种样式(代表四种状态):
TBBS_CHECKED
TBBS_INDETERMINATE
TBBS_DISABLED
TBBS_PRESSED

正式的按钮状态定义是六种,它们是:

Up = 0
Mouse Down = TBBS_PRESSED (| any other style)
Disabled = TBBS_DISABLED
Down = TBBS_CHECKED
Down Disabled = TBBS_CHECKED | TBBS_DISABLED
Indeterminate = TBBS_INDETERMINATE

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值