没有合适的资源?快使用搜索试试~ 我知道了~
首页VC++实例详解-2(不可多得的MFC教程)
资源详情
资源评论
资源推荐

下载
第 2 章 控 制 条
从第1章中可以注意到,通用控件窗口是由 Windows API提供,用于创建按钮、列表框和
编辑框等控件的特定子窗口。虽然工具栏可能看起来像这些控件窗口的集合,但实际上它只
是一种较长的控件窗口,该控件窗口在本窗口中绘制按钮。状态栏也只是一个较长的窗口,
不过它可以在自己的边界以内绘制其窗格。工具栏和状态栏都代表了叫做通用控制条的一类
特定通用控件窗口。
本章仅探讨如何使用Windows API创建通用控制条。然后研究利用 M F C 类通过A P I 所提供
的许多功能来创建它们。最后则看看由这些控制条所绘制的按钮和窗格的可用风格。
2.1 通用控制条
通用控制条有3种:工具栏、状态栏和伸缩条。工具栏和状态栏在 Wi n d o w s的各个版本中
都可以见到。另一方面,伸缩条 ( R e b a r ) 只能在Windows 98或者以后版本中以及系统安装了
I E 4 . 0 后才可以使用,本章最后将讨论伸缩条。工具栏是人们熟悉的控件窗口,它沿着应用主
窗口的顶端和四周布局并包含了多个按钮。状态栏通常位于主窗口的底部,它指示键盘状态
并显示帮助消息。
初看起来,用户可能会觉得工具栏上的按钮是一排使用通用控件类 B U T TO N创建的子窗
口,而状态栏则可能被认为是 S t a t i c控件的集合。实际上,这两者都是自己绘制并控制这些按
钮图像,请参见图2 - 1。
图2-1 工具栏和状态栏控制窗口
那么,为什么控制条要不厌其烦地重复创建这个功能而不使用已有的通用控件呢?答案
是控制条自己做这些工作可以节约许多开销。在创建窗口时, 5 0 % 以上的时间花费在背景定
位和资源初始化上。具有 1 0个或者1 0 个以上按钮的工具栏采用 1个绘图处理器比在1 0个处理器
中画得快得多。
虽然这些看起来像装载
了控件窗口的父窗口,
但它们中的每一个实际
上都是属于主框架窗口
的细而长的控件窗口
这些按钮
由工具条
控件窗口
绘制
这些窗格
由状态栏
控件窗口
绘制

2.2 用API创建控制条
现在看看只采用A P I 该如何创建并初始化控制条。因为这个工作的大部分可以由 M F C来完
成,这里的介绍就不拘泥于细节了。
创建工具栏或者状态栏的 Windows API与创建通用控件的A P I是一样的,只是其窗口类结
构不同。可以使用下列语句创建工具栏:
HWND hWnd = :: CreateWindowEx(..., "To o l b a r Wi n d o w 3 2 " , . . . ) ;
工具栏控件可以由一个定义了一套按钮外观的位图对象来初始化。为了定义这个位图对
象,可以向这个控件发送一个如下所示的 T B _ A D D B I T M A P 窗口消息:
::SendMessage (hWnd, TB_ADDBITMAP, nNumButtons,&tbab);
这里使用的 t b a b 参数是一个 T B A D D B I T M A P 结构,该结构包含了位图对象的句柄。
n N u m B u t t o n s 参数则告诉工具栏该位图代表了多少个按钮表面。一旦该位图被定义,就可以发
送如下的T B _ A D D B U T TO N S消息以告诉工具栏绘制什么按钮以及在哪里绘制它们:
::SendMessage (hWnd, TB_ADDBUTTONS, nNumButtons, &tbbutton);
这里使用的t b b u t t o n 参数代表一个定义了每个按钮的 T B B U T TO N结构数组。该结构指出
针对具体的按钮绘制什么样的按钮表面以及按钮被单击之后产生什么命令消息 I D。
可以使用下列语句创建状态栏:
HWND hWnd = :: CreateWindowEx (..., "msctls_statusbar32" ,...);
状态栏由通常显示文本的窗格组成。可以使用 S B _ S E T PA RT S窗口消息创建这些窗格:
::SendMessage (hWnd, SB_SETPA RTS, nParts, Wi d t h s ) ;
n P a r t s参数告诉控件要创建多少个窗格,而 Wi d t h s 参数则是一个整型数数组,它定义了以
像素为单位计算的每个窗格的大小。可以使用 S B _ S E T T E X T消息在窗格上添加文本:
::SendMessage (hWnd, SB_SETTEXT, nPane, "pane text");
n P a n e告诉状态栏控件在哪个窗格上添加文本。
控制条风格
对所有通用控件,工具栏和状态栏都可以用标准的 Wi n d o w s 风格 ( W S _ C H I L D、
W S _ V I S I B L E 等)创建,也可以使用它们自己的风格来创建。工具栏风格有一个 T B S T Y L E _前
缀,而状态栏风格则具有 S B A R S _ 前缀,但现在只用一种状态栏风格。这两种风格的实例可以
参见表 2 - 1 。除了这些控件风格以外,这些控制条都还共享了一套名叫 Common Control
S t y l e s ( 通用控件风格)的通用风格。这些风格具有前缀 C C S _ 并且倾向于包括所有控制窗口共有
的风格。然而,因为控件窗口的特征不同,这些风格多数仅被控件采用。通用控件风格可以
参见表2 - 2,了解这些风格如何影响控制条请参见图 2 - 2 。
除了这些控件风格外,所有这些控件还有一个公共的风格集合,称为 common Control
Styles (通用控件风格)。这些风格的前缀也为 C C S-,其目的是要包含所有控件窗口的所有公
共风格。但是,因为控件窗口的不同特性,这些风格大多由控件条使用。表 2 - 2 中列出了这些
通用控件风格。要想了解这些风格对控件条的影响,请参见图 2 - 2 。
22第第第一部分第基第第础
下载

表2-1 一些工具栏和状态栏风格
风 格 使 用 说 明
T B S T Y L E _ F L AT 使工具栏上的按钮表面平坦,意味着按钮的边界不会被绘制出来,除非鼠标指针指
在上面
T B S T Y L E _ L I S T 按钮文本显示在按钮的左边
T B S T Y L E _ TO O LT I P S 如果用户将鼠标指针停留在按钮上较长时间就使按钮产生 T T N _ N E E D T E X T通知消
息。程序员需要负责为这个工具提示提供说明文本
T B S T Y L E _ W R A PA B L E 使控件将其按钮排成多行以适应当前的控件大小
SBARS_SIZEGRIP 唯一的状态栏风格,使状态栏在控件底部显示熟悉的把手条。因为控件正常情况下定
位于应用窗口的底部,所以该状态栏看起来影响了整个窗口
表2-2 通用控件风格
风 格 使 用 说 明
C C S _ N O R E S I Z E 被创建的控制条的大小由: : C r e a t e Window() API调用来指定。该风格忽略以下 4种风
格:这些风格则忽略指定的大小
C C S _ TO P 使控制条一开始沿其父窗口框架的顶部 /底部对齐和延伸。高度则被设置为系统标
C C S _ B O T TO M 准。C r e a t e Windos() API调用中指定的大小则被忽略。注意:如果父窗口被重置大小,
则必须自己重置控制条大小
C C S _ L E F T 同上,但控制条必须沿父框架左 /右对齐并且其宽度设置为系统标准
C C S _ R I G H T
C C S _ N O D I V I D E R 通用控制条自动地沿其顶部绘制一条直线:通常用来将工具栏和菜单分隔开
C C S _ A D J U S TA B L E 允许用户动态地配置其工具栏,这并不是 Developer Studio提供的良好方式,请参
看实例9以了解这一Developer Studio方法
C C S _ N O M O V E Y 这些风格或者是没有明显的效果或者是重复了以上所述的风格
C C S _ N O M O V E E X
CCS_NOPARENTALIGN
图2-2 工具栏风格实例
第 2 章控控控制控条控控23
下载
即使是左对齐,工具
条仍然垂直绘制
工具条的尺寸和位置
可在创建时指定
工具条中的按钮被设定为特定控
件尺寸,但C C S _W R A PA B L E 不
能与C C S _ L E F T一起使用

如上表和上图所示,控制条可用窗口风格是相当少的,即便加上通用控件风格也是这样。
控制条在控件的顶部(而不是在其底部或是左边、右边 )自动地绘制一条直线,而且也没有垂直
放置通用控制条的风格(可以沿主窗口的左边或者右边对齐控制条,但按钮会消失在控件之外)。
此外,创建的控制条不能自动地与其他控制条共享主窗口的客户区。事实上,必须手工重置
其大小并移动它们以使视和控制条可见。通用工具栏的另一个难题是用户不能移动它们。现
在的多数应用程序中的工具栏可以移动到应用主窗口的任意一边或者浮动在其自己特定的窗
口框架上。然而,由 Windows API提供的控制条不支持以上任何功能。为了弥补这个功能上
的缺陷,M F C提供了几个类来封装并增强应用程序的控制条功能。
2.3 用MFC创建控制条
M F C 提供的两种类封装了创建工具栏和状态栏的 Windows API(与在第1章中所述的C W n d
封装Windows API 创建窗口一样)。这些类是C To o l B a r C t r l和C S t a t u s B a r C t r l类。
2.3.1 CToolBarCtrl和CStatusBarCtrl
为了用M F C 创建工具栏,使用以下代码:
C ToolBarCtrl tb;
tb.Create ( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
UINT nID );
为了向该工具栏中增加位图,使用如下语句:
tb.AddBitmap(int nNumButtons, CBitmap* pBitmap );
最后,按照如下语句定义一个实际工具栏按钮:
tb.AddButton(int nNumButtons, LPTBBUTTON lpButtons );
l p B u t t o n s 参数与以上用A P I 定义按钮的T B B U T TO N S数组是一样的。为了创建状态栏,使
用如下代码:
CStatusBarCtrl sb;
sb.Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
UINT nID );
可以使用如下代码增加窗格和文本:
sb.SetParts( int nParts, int* pWidths );
s b . S e t Text( LPCTSTR lpszText, int nPane, int nType );
p Wi d t h s和n P a n e参数在以上A P I版本中已经用过。
正如所看到的,这两个类立即带来的好处就是使得 C + +程序中与A P I 对话变得容易多了。
然而,由于它们只是简单地封装了 A P I而没有增加附加的功能,所以由它们所创建的工具栏和
状态栏不会比A P I版本增加更多的功能。它们也不能移动或被用户停靠或者垂直对齐。它们仅
能用于在控制条内更方便地设置并控制按钮和窗格,所以,为了得到这些所希望的功能就必
须创建自己的控制条,这就要用到另外两个 M F C 类: C To o l B a r和C S t a t u s B a r。
2.3.2 CToolBar和CStatusBar
为了使用C To o l B a r创建工具栏,需要再次使用下列熟悉的 C r e a t e ( )成员函数:
24第第第一部分第基第第础
下载

C ToolBar tb;
tb.Create( CWnd* pParentWnd, DWORD dwStyle, UINT nID );
如上所示,创建工具栏已经是一件很容易的事,而且不需要考虑 r e c t 参数。但最大的方便
还在于装载位图和定义按钮的时候:
t b . L o a d ToolBar(UINT id);
此时不用编程定义位图和每个按钮,使用 Toolbar Editor创建一个将要引用的资源即可。
L o a d ToolBar 函数接下来负责将资源翻译为 A P I调用以设置该工具栏。
状态栏类也很容易使用,如下代码所示:
CStatusBar sb;
sb.Create( CWnd* pParentWnd, DWORD dwStyle, UINT nID );
sb.SetIndicators( const UINT* lpIDArray, int nIDCount );
这时不用为状态栏定义文本和窗格的数目,可以使用 String Editor创建一组在I D A r r a y 数
组中定义的字符串,该数组则被传送给 S e t I n d i c a t o r s ( )函数。
使用这些类不仅使装载和配置控制条变得更容易,而且还可以得到下列增强的功能:
■ 使用C To o l B a r 类,工具栏中使用的位图的颜色自动地随当前按钮颜色而变化。淡灰色
是标准的Wi n d o w s 按钮表面色,但是,如果用户确定为自己的桌面选定一种新的色彩方案 (例
如淡紫红色),那么如果工具栏仍保持淡灰色,按钮看起来就好像偏离了本来的位置。因此,
C To o l B a r将它们转变成当前的按钮颜色,所有这些替代颜色如表 2 - 3所示
表2-3 CTo o l B a r位图颜色转换
工具栏位图颜色 系 统 颜 色 工具栏位图颜色 系 统 颜 色
黑 C O L O R _ B T N T E X T 亮灰 C O L O R _ B T N FA C E
暗灰 COLOR_BTNSHADOW 白色 COLOR_BTNHIGHLIGHT
■ 由C To o l B a r和C S t a t u s B a r 提供的其他成员函数则建立在 Windows API的功能之上。例如,
C To o l B a r : : S e t B u t t o n Te x t ( ) 函数允许直接设置工具栏按钮的颜色而不用关心所有做出这一改变
的A P I 调用。
■ 这些类还自动提供了启用或者禁用工具栏按钮和状态栏窗格或者对其设置复选状态的
能力。换句话说,除非工具栏是用 C To o l b a r 创建的,否则 O n C m d U I ( )消息处理器不会启用或
者禁用工具栏按钮。
按照 C + + 的继承思想,可以认为 C To o l B a r 和C S t a u s B a r 类是从 C To o l B a r C t r l和
C S t a t u s B a r C t r l 类派生的,因此可以得到这两者的功能。但是,微软决定从一种名叫
C C o n t r o l B a r的新类来派生C To o l B a r和C S t a u s B a r,这种新类包含两者共同的新功能。那是否意
味着微软必须在C To o l B a r中复制C To o l B a r C t r l 类的功能呢?答案是“不”,这是因为C To o l B a r
和C To o l B a r C t r l 都通过发送消息给一个控件的窗口句柄来同控件对话,这样,事实上可以同时
拥有一个C To o l B a r和C t o o l B a r C t r l 类的实例来控制同样的工具栏并共享一个窗口句柄。实际上,
C To o l B a r 类的一个名叫 G e t To o l B a r C t r l ( )的成员函数将自动地创建一个 C To o l B a r C t r l 类的实例
并指向同一个工具栏。状态栏也提供了类似的函数 G e t S t a t u s B a r C t r l ( )。请参见图2 - 3了解它们
是如何协同工作的。
第 2 章控控控制控条控控25
下载
剩余21页未读,继续阅读












安全验证
文档复制为VIP权益,开通VIP直接复制

评论1