友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
C语言实例教程(PDF格式)-第21部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
工具条包括的是最经常使用的命令。大型程序通常有多个工具条来为
不同的用户任务服务。即使你的程序只有一个工具条,也要使用户在
感觉它碍事时能将其藏起来。
从编程的角度看,工具条是一个显示一系列位图按钮的子窗口。一旦
创建了工具条并使其可见,就不能再忽略它,因为它将和菜单与加速
键一样生成WM_MAND消息。但应使工具条的命令ID与菜单和加速键
的命令ID同步。
在这一节中,将介绍几个有关工具条的问题。我们将首先看看工具条
在MFC层次结构中的位置,然后我们再介绍有关动态创建和修改工具
…………………………………………………………Page 236……………………………………………………………
条的若干细节,最后,我们将说明工具条定位与消隐的一些技术并给
出一个相应的较小的例程。我们计划按下列顺序讲解:
l MFC控制条
l 创建工具条
l 显示和隐藏工具条
从图5。18中可见工具条类的基本类为CControlBar,而该基本类是由
CWnd类派生的。掌握这个继承关系对我们来说是很有用的。例如,由
于所有的控制条都是有CWnd类派生的,所有的控制条都连接到一个
Windows APIH窗口。因此,CWnd的所有功能――创建、移动、显示和
隐藏窗口――在用控制条工作是都是可用的。
CToolBar类有几个兄弟类,包括CStatusBar和COleResizerBar,
CDialotBar。当发生请求时,AppWizard通过创建一个CStatusBar对象
来创建一个状态条。正如我们在介绍菜单时所提到的,状态条位于帧
窗口的底部并显示有关菜单选择的帮助消息。当用户在各按钮上移动
鼠标时,状态条也显示关于不同工具条按钮的详细帮助信息。
图5。 18 类CToolBar继承关系图
CDialogBar类创建对话条,它位于工具条和对话框之间。对话条能够
象对话框那样起控制作用,但它象一个工具条那样位于帧窗口中。我
们对此不打算作详细介绍,有兴趣的读者可以参考有关书籍。
MFC控制条COleResizerBar可以改变在为OLE对象的大小。
MFC的工具条 (和对话条)都是可迁移的。如允许这一特性,用户就
可将一个工具条移到一个具有不同边界的帧窗口中。但它将根据这一
新窗口的边界而更新以表明它所迁移的位置。此外,工具条还可被移
出帧边界并被放到空闲的调色板上。
MFC工具条也支持工具便笺,工具便笺可帮助用户理解单独一个位图
按钮的作用。如允许这一特性,用户就可通过将鼠标光标移到一个工
…………………………………………………………Page 237……………………………………………………………
具条按钮上 (并不单击按钮)来调用工具便笺支持。过一会儿以后,
就会在工具条按钮上方的一个小的正文窗口中显示工具便笺――一个
简略的字或短语。
为在你的MFC程序中使用工具条,必须协调使用位图资源,包括工具
条自身以及帧窗口等几项。为帮助用户对此的理解。在后面我们将介
绍如何创建自己的工具条。
下面我们创建一个工具条。AppWiard 自动生成一个工具条。但它的某
些特性,比如象显示和隐藏工具条,则被隐藏在现有MFC类中。为了
能更详细地介绍工具条,我们将创建另一个菜单。在此之后,我们将
说明两个工具条如何共处于同一个程序中。这样,你就将看到创建一
个附加的工具条是多么容易。
创建工具条分五步。首先要创建按钮映象的位图。其次要建立一个将
按钮映射到你的程序命令码的数组。第三要编写创建工具条并将其适
当初始化的程序。一旦工具条窗口被创建,第四步和第五步是将按钮
映象和命令ID与工具条相连接。一旦这些基本步骤完成后,就可采取
其它步骤来进一步改善工具条。下面我们分别讲解。
1。 创建按钮映象位图。应将该位图作为位图资源存储起来。如图
5。19,打开资源编辑器,将按钮映象的位图创建到一行中。每个映象
的缺省大小是16×15象素。如果你希望使用别的大小,那么你就需要
调用函数CToolBar::SetSize通知应用程序相应的改变。该函数的相
关信息可以通过系统的帮助信息获得,在此不再赘述。
图5。 19 建立工具条位图资源
2。 定义命令码数组。映射按钮映象到命令ID号。下面的代码摘自例
程,无符号整形数组 (UINT)为上图所示工具条按钮的对应数组。
3。 创建并初始化工具条对象。与其它创建过程类似,采用两步法生
成:先声明对象,再调用初始化函数CToolBar::Create生成。该函数
原型为:
BOOL Create( CWnd* pParentWnd; DWORD dwStyle=WS_CHILD| WS_VISIBLE | CBRS_TOP;
UINT nID = AFX_IDW_TOOLBAR );
…………………………………………………………Page 238……………………………………………………………
该函数中参数pParentWnd为指向工具条所在父窗口的指针 (别忘了工
具条本身也是窗口 !),dwStyle为工具条的风格说明,其取值如表
5。1所示:
该函数最后一个参数表示工具条子窗口的ID号。
如下述代码生成一工具条:
d_pToolBar=new CToolBar( );
d_pToolBar…》Create(this;WS_CHILD|CBRS_TOP;0x9100);
表5。 1 工具条风格
标志 简单描述
WS_VISABLE 使工具条窗口初始可见
CBRS_BOTTOM 初始时将工具条放到窗口底部
CBRS_FLYBY 鼠标光标在按钮上暂停时,显
示命令描述
CBRS_NOALIGN 防止控制条在其父窗口改变大
小时被复位
CBRS_TOOLTIPS 鼠标光标在按钮上暂停时,显
示工具便笺
CBRS_TOP 初始时将工具条放在窗口底部
4。 将储存在位图资源中的按钮映象与程序的工具条相连接。这可以
通过函数调用CToolBar:LoadBitmap达到。该函数原型为:
BOOL LoadBitmap( LPCTSTR lpszResourceName );
BOOL LoadBitmap( UINT nIDResource );
该函数提供的重载两个不同版本,使我们既可以通过指向位图资源的
指针调用,也可以通过该位图的ID号调用达到。
如下段代码:
d_pToolBar…》LoadBitmap(IDR_TOOLS);
5。 作为该过程的最后一步,我们需要将按钮与命令ID联系起来。这
可以用一个在第二步中创建的数组的指针来调用函数
…………………………………………………………Page 239……………………………………………………………
CToolBar::SetButtons达到,该函数的原型为:
BOOL SetButtons( const UINT* lpIDArray; int nIDCount );
其中参数lpIDArray为指向一命令ID数组的指针。当然,为了使用不
含按钮的工具条,该参数可能为NULL,参数nIDCount为前一数组中的
元素个数。
一般来说,我们可以这样编写我们的程序:
d_pToolBar…》SetButtons(buttons;sizeof(buttons)/sizeof(UINT);
到此为止,我们所创建的工具条已经实现。当然,我们可能仍然需要
以别的方式改善工具条的操作。对于一般要求来说,最常用的操作也
许就是移动和显隐切换了。
我们先谈其移动。在缺省状况下,一个CToolBar工具条只能被应用程
序所移动。但也可以使用户能够将工具条移到帧的另一部分。为此,
需向工具条及帧窗口发送消息。这可通过调用
CToolBar::EnableDocking和CFrame::EnableDocking实现。二函数原
型均如下:
void EnableDocking( DWORD dwStyle );
其中参数dwStyle为工具条风格,对CToolBar其取值可如下:
而对于CFrame,风格值CBRS_FLOAT_MULTI不可用。
下面这段代码几乎也是标准的:
d_pToolBar…》EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
表5。 2 工具条停靠风格
风格 含义
CBRS_ALIGN_TOP 工具条可在客户区顶端移动
CBRS_ALIGN_BOTTOM 工具条可在客户区底端移动
CBRS_ALIGN_LEFT 工具条可在客户区左端移动
CBRS_ALIGN_RIGHT 工具条可在客户区右端移动
…………………………………………………………Page 240……………………………………………………………
CBRS_ALIGN_ANY 工具条可在客户区任意位置移动
CBRS_FLOAT_MULTI 允许在一单边窗口内存在多个可
移动控制条
用户也可以将工具条移动或定位。或者在程序控制下,通过调用
CFrameWnd::DockControlBar来移动以及调用
CFrameWnd::FloatControlBar来定位一工具条。它们的原型及参数如
下所示:
void DockControlBar( CControlBar * pBar; UINT nDockBarID = 0; LPCRECT lpRect =
NULL );
其中pBar为指向欲移动的工具条的指针,nDockBarID决定框架窗口哪
一边可移动。它为0时,则控制条可任意移动,它取值
AFX_IDW_DOCKBAR_TOP,AFX_IDW_DOCKBAR_ BOTTOM,
AFX_IDW_DOCKBAR_LEFT,AFX_IDW_DOCKBAR_RIGHT时,分别表示控制
条可移动至框架窗口的顶端,底端,左端及右端,该函数最后一个参
数标识控制条可放置的框架非客户区的屏幕坐标。
第二个函数的原型及参数读者不妨从系统帮助文件中查到。
例如,我们可以这样编写代码:
d_pToolBar…》EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
接下来我们再谈谈工具条的显隐控制。由于工具条是一个窗口,它的
显隐可以通过其父类CWnd的成员函数实现。
在我们要改变工具条状态前知道当时工具条的状态有时是至关重要
的,工具条的可视性可以通过函数CWnd::GetStyle拣取。该函数不带
参数,其原型为:
DWORD GetStyle( ) const;
函数返回当前控制条风格值。
而通过对函数CWnd::SetStyle的调用可以改变某些窗口风格,但该函
数不能改变WS_VISABLE,这意味着我们不得不通过调用其基类的成员
函数ShowWindow来实现:将参数SW_HIDE传给函数以使工具条不可见
或传递SW_SHOWNORMAL使工具条再次显示。函数SetStyle的原型及参
数读者不妨自己从系统的帮助文件中查到。
…………………………………………………………Page 241……………………………………………………………
一旦在程序中改变了工具条,就必须将这一改变通知帧窗口,为此需
再次计算控制条的位置,这可以通过调用函数
CFrameWnd::RecalcLayout来实现。该函数为一不带参数的函数,读
者在程序中可以简单地进行调用即可。例如程序中下列代码
RecalcLayout( );
即可将该工具条的变化通知到程序窗口中。
图5。 20 程序初始画面
图5。 21 两个工具条并存
l 注意:
l 限于篇幅原因,本节内容给出一个源程序代码,但较不完整。读
者如果感兴趣,可以自己试着编写完全。但需要注意的是,在编
…………………………………………………………Page 242……………………………………………………………
辑工具条时,应该将工具条的各个按钮作为位图储存。否则,在
程序进行编译时,会出现ID号未定义错。(Undeclared
Identifier error)。下面给出程序的一些关键性代码。而且由于
前文对各函数讲得较细致;对下面的源代码我们给 出的解释较简
单。同时;考虑到只有文件mainframe。cpp中改动较多;下面的源代
码仅为该文件。但我们给 出了几幅运行画面(图5。20到图5。22)供比
较。
图5。 22 隐去自编工具条
// mainfrm。cpp : 类DMainFrame的实现
//
// 。。。
#include 〃stdafx。h〃
// 。。。
//以上为程序包含文件部分。
IMPLEMENT_DYNCREATE(DMainFrame; CFrameWnd)
BEGIN_MESSAGE_MAP(DMainFrame; CFrameWnd)
//{{AFX_MSG_MAP(DMainFrame)
ON_WM_CREATE()
ON_MAND(ID_TOOLBAR_CREATE; OnToolbarCreate)
ON_MAND(ID_TOOLBAR_SHOW; OnToolbarShow)
…………………………………………………………Page 243……………………………………………………………
ON_UPDATE_MAND_UI(ID_TOOLBAR_CREATE; OnUpdateToolbarCreate)
ON_UPDATE_MAND_UI(ID_TOOLBAR_SHOW; OnUpdateToolbarShow)
ON_MAND(ID_EDIT_COPY; OnEditCopy)
ON_MAND(ID_EDIT_CUT; OnEditCut)
ON_MAND(ID_EDIT_PASTE; OnEditPaste)
ON_MAND(ID_EDIT_UNDO; OnEditUndo)
ON_MAND(ID_FILE_NEW; OnFileNew)
ON_MAND(ID_FILE_OPEN; OnFileOpen)
ON_MAND(ID_FILE_SAVE; OnFileSave)
ON_MAND(ID_FILE_PRINT; OnFilePrint)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//以上部分为消息响应;由于要在程序中改变图标选中状态;我们处理了消息
ON_UPDATE_MAND;
//该消息在每一个发送该消息之前发送;因此;通过处理该消息;我们就可以在用户看到该图标
出
//现以前改变该图标表现。
/////////////////////////////////////////////////////////////////////////////
// arrays of IDs used to initialize control bars
// toolbar buttons IDs are mand buttons
static UINT BASED_CODE buttons'' =
{
// same order as in the bitmap 'bitmap1。bmp'
ID_TOOLBAR_CREATE;
ID_SEPARATOR;
ID_TOOLBAR_SHOW
//以上部分为工具条上按钮对应情况;ID_SEPARATOR在两个相邻按钮间加一分隔线
…………………………………………………………Page 244……………………………………………………………
};
// toolbar buttons IDs are mand buttons
static UINT BASED_CODE Toolbar2Buttons'' =
{
// same order as in the bitmap 'toolbar。bmp'
ID_FILE_NEW;
ID_FILE_OPEN;
ID_FILE_SAVE;
ID_SEPARATOR;
ID_EDIT_CUT;
ID_EDIT_COPY;
ID_EDIT_PASTE;
ID_SEPARATOR;
ID_FILE_PRINT;
ID_APP_ABOUT;
//这一部分同上;注意;工具条按钮间分隔线最好在编程时确定。同时;一定要注意按钮的对应
情况。
};
static UINT BASED_CODE indicators'' =
{
ID_SEPARATOR; // status line indicator
ID_INDICATOR_CAPS;
ID_INDICATOR_NUM;
ID_INDICATOR_SCRL;
//状态条空间分配
};
/////////////////////////////////////////////////////////////////////////////
…………………………………………………………Page 245……………………………………………………………
// DMainFrame construction/destruction
DMainFrame::DMainFrame()
{
d_pToolbar2 = 0;
d_bToolbarVisible = FALSE;
//在此处我们为工具条初始化加入代码;新建工具条初始时不可见
//以上二变量在文件mainfrm。h中定义:
//public:
// CToolBar * d_pToolbar2; // Pointer for dynamic toolbar。
// BOOL d_bToolbarVisible; // Flag for toolbar visibility。
}
DMainFrame::~DMainFrame()
{
//mainframe类析构函数
}
int DMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == …1)
return …1;
//以下代码创建一工具条
if (!m_wndToolBar。Create(this) ||
!m_wndToolBar。LoadBitmap(IDR_MAINFRAME) ||
!m_wndToolBar。SetButtons(buttons;
sizeof(buttons)/sizeof(UINT)))
{
TRACE0(〃Failed to create toolbarn〃);
…………………………………………………………Page 246……………………………………………………………
return …1; // fail to create
}
//以下代码创建一可移动工具条;如程序不希望如此;可删除下列代码
m_wndToolBar。EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
//此下代码使能工具提示;如不需要;可移去
m_wndToolBar。SetBarStyle(m_wndToolBar。GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY);
//以下代码创建状态条
if (!m_wndStatusBar。Create(this) ||
!m_wndStatusBar。SetIndicators(indicators;
sizeof(indicators)/sizeof(UINT)))
{
TRACE0(〃Failed to create status barn〃);
return …1; // fail to create
}
return 0;
//以上部分为系统对给出的工具条;状态条的初始化;读者不妨对其仔细研究一下。
}
/////////////////////////////////////////////////////////////////////////////
// DMainFrame diagnostics
// 。。。
//其中删节部分调试程序时有用
// 。。。
/////////////////////////////////////////////////////////////////////////////
…………………………………………………………Page 247……………………………………………………………
// DMainFrame message handlers
//以下为消息处理函数
// 菜单项Toolbar|Create消息处理;用于创建工具条
void DMainFrame::OnToolbarCreate()
{
// 仅在工具条不存在时断言成立
ASSERT(d_pToolbar2 == 0);
// 创建工具条对象;由于正文中已作较多解释;此处从简
d_pToolbar2 = new CToolBar();
d_pToolbar2…》Create(this; WS_CHILD | CBRS_TOP |
CBRS_TOOLTIPS | CBRS_FLYBY;
0x9100);
//获得位图;并与工具条相联系
d_pToolbar2…》LoadBitmap(IDR_TOOLS);
d_pToolbar2…》SetButtons(Toolbar2Buttons;
sizeof(Toolbar2Buttons)/sizeof(UINT));
//使能工具条移动
d_pToolbar2…》EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CB
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!