自己动手绘制ToolBar

VC MFC工具栏(CToolBar)控件

工具栏

工具栏控件在控件面板里没有对应的选项(图标),但有一个工具栏控件类CToolBar,所以我们如果要创建一个工具栏控件并显示在窗口里的话,只能用代码来完成,事实上任何一种控件,都可以用代码创建,如CButton按钮类,现举一个用代码创建按钮控件并显示在窗口里的例子。

CButton类的Create成员函数可以创建一个按钮控件,这个函数的格式如下:
BOOL CButton::Create(
     LPCTSTR lpszCaption,//按钮显示的文本
     DWORD dwStyle,//按钮样式
     const RECT& rect,//按钮控件显示的区域(大小)相对于父窗口
     CWnd* pParentWnd,//按钮的父窗口(按钮属于哪个窗口)
     UINT nID//指明按钮控件ID号

);
这个函数的第二个参数dwStyle是按钮控件的样式,也就是在可视化添加按钮控件时,右击按钮控件,选择属性,之后会弹出一个对话框,这个对话框有一个样式的选项,该参数即对应这个样式。

好了,了解了上面这些我们就来动态创建一个按钮吧,首先在对应话类里添加一个按钮类成员变量CButton m_Button;

然后在对话框编辑区里给对话框添加一个按钮控件(单击这个按钮创建按钮控件),然后添加这个按钮控件单击消息处理函数,并在函数添加以下语句:

RECT ButtonRect;//按钮控件显示的区域(大小)相对于父窗口
 ButtonRect.left=10;
 ButtonRect.top=10;
 ButtonRect.right=80;
 ButtonRect.bottom=30;
 m_Button.Create("动态创建",WS_CHILD,ButtonRect,this,1115);
 m_Button.ShowWindow(SW_SHOW);//显示按钮控件

知道了怎样动态创建按钮控件,我们就来创建工具栏控件。

首先在对话类中添加一个CToolBar类成员变量CToolBar m_Toolbar;

然后在对话类文件中定义工具栏命令ID

#define ID_BUTTON1    501
#define ID_BUTTON2    502
#define ID_BUTTON3    503

接着我们就要创建工具栏资源了,用于工具栏按钮的显示图片

方法是进入ResourceView(资源视图选项卡),再随便选中一个选项,右击选择插入,在弹出的对话框里选中Toolbar,点新建。

接着创建三个按钮。如下图所示:

好了,下面把三个按钮ID号,改成上面宏定义的ID号,如果要改变“天”字按钮,选中该按钮,然后回车键,就会弹出一个对话框,

在ID项填入ID_BUTTON1,就可以了。接着依次把两个ID号改为ID_BUTTON2,ID_BUTOON3。在这个对话框里也可以改变工具栏按钮的大小。

接下来我们样在对话框类的OnInitDialog函数里的所有代码之后,return TRUE;之间添加以下语句:
     m_Toolbar.Create(this);//创建工具栏控件
     m_Toolbar.LoadToolBar(IDR_TOOLBAR1);//装载工具栏资源
  CRect rect(100,100,200,200);//
  m_Toolbar.MoveWindow(rect);//移动工具栏在父窗口的位置
  m_Toolbar.ShowWindow(SW_SHOW);//显示工具栏

但这样显示工具栏不是很方便,特别是当窗口大小改变后,还要计算工具栏在窗口中的位置,有没有什么方法,可以根据窗口大小自动调整工具栏到合适的位置呢?答案是肯定的,RepositionBars函数可以做到。实现方法如下,把上面的语句换成下面的:

m_Toolbar.Create(this);//创建工具栏控件
    m_Toolbar.LoadToolBar(IDR_TOOLBAR1);//装载工具栏资源
  //该函数用于显示工具栏,并根据窗口大小自动调整工具栏的位置
  RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

而响应工具栏按钮单击消息,跟前面介绍的添加按钮单击消息差不多,进入类向导,找到要添加的工具栏按钮ID,添加COMMAND消息响应函数,如下图:

工具栏按钮上显示真彩位图

上面的例子有一个缺陷,那就是工具栏按钮显示的图形,不能超过256色,如果我想在工具栏按钮显示真彩位图,上面的方法显示是无法实现的,那这个功能是如何实现呢?

SetImageList函数可以做到,既然要显示真彩位图,那就不能使用上面的工具栏资源(256色),所以一切都得到用代码实现

首先向工程引入六张位图(用于工具栏按钮显示的图片),假设ID号分别为IDB_BITMAP1,IDB_BITMAP2,IDB_BITMAP3,IDB_BITMAP4,IDB_BITMAP5,IDB_BITMAP6,大小为50X38

第一步:在对话框里添加两个成员变量分别是:

CToolBar m_Toolbar;
  CImageList m_ImageList;

第二步:在对话类文件添加以下宏定义:
#define ID_BUTTON1    501
#define ID_BUTTON2    502
#define ID_BUTTON3    503
#define ID_BUTTON4    504
#define ID_BUTTON5    505
#define ID_BUTTON6    506

接下来在对话框初始化函数OnInitDialog后面添加如下语句:

m_ImageList.Create(50,38,ILC_COLOR24|ILC_MASK,1,1);//图片大小必须一致
  CBitmap bmp;
  for(int i=0;i<6;i++)
  {
   bmp.LoadBitmap(IDB_BITMAP1+i);
   m_ImageList.Add(&bmp,RGB(255,255,255));
   bmp.DeleteObject();
  }
  UINT nArray[6];
  for(i=0;i<6;i++)
  {
   nArray[i]=ID_BUTTON1+i;
  }
     m_Toolbar.CreateEx(this);//创建工具栏控件,CreateEx函数创建的工具栏,默认有浮动按钮属性
  m_Toolbar.SetButtons(nArray,6);//创建六个工具按钮,并依次设置ID号,对应nArray数组的元素
  m_Toolbar.SetSizes(CSize(60,56),CSize(50,38));//函数第一个是按钮大小,第二个是图像大小,按钮必须比图像要大,具体是按钮的要

//比图像的宽大7或者以上,高6
  m_Toolbar.GetToolBarCtrl().SetImageList(&m_ImageList);//设置图像
  RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

运行效果如下图:

如果要响应工具栏按钮单击消息的话,必须手动添加消息映射:如

ON_COMMAND(ID_BUTTON1,Button1)   //button1为消息处理函数

如果要设置按钮显示文本的话,就是CToolBar类的 SetButtonText函数。

设置工具栏背景位图

用CReBar类可以实现在工具栏背景里显示位图,可以把工具栏设置成CReBar类对应的子窗口,以上面的工程为例子,再在对话类里添加一个成员变量: CReBar m_Rebar;接着导入一张位图,用做工具栏的背景,ID号为ID_TOOLBACK,然后在OnInitDialog函数的

RepositionBar(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);语句前面添加如下语句:
m_Rebar.Create(this);//创建窗口(控件)
  m_Rebar.AddBar(&m_Toolbar);//添加m_Toolbar为子窗口
  m_Rebar.RedrawWindow();//重画窗口
  REBARBANDINFO info;
  info.cbSize=sizeof(info);
  info.fMask=RBBIM_BACKGROUND;
  m_Toolbar.ModifyStyle(0,TBSTYLE_TRANSPARENT);//设置工具栏背景色透明
  info.hbmBack=LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_TOOLBACK));//加载位图
  m_Rebar.GetReBarCtrl().SetBandInfo(0,&info);

编译,运行效果如下:

为工具栏按钮添加鼠标停留提示信息

以上面的工程为例子,在对话类里添加一个成员变量CString str;

接着在m_Toolbar调用CreateEx函数后,调用这个语句:  m_Toolbar.EnableToolTips();//激活信息提示功能

然后在对话类里添加一个成员函数(用于TTN_NEEDTEXT消息处理函数),格式如下:

BOOL  OnDisplay(UINT id, NMHDR *pNMHDR, LRESULT *pResult)

然后添加TTN_NEEDTEXT消息映射宏

ON_NOTIFY_EX(TTN_NEEDTEXT,0,OnDisplay)

OnDisplay函数代码如下:

TOOLTIPTEXT *pTTT=(TOOLTIPTEXT *)pNMHDR;
UINT nID=pNMHDR->idFrom;//获取工具栏按钮ID
UINT nIndex=m_Toolbar.CommandToIndex(nID);//根据按钮ID获取索引
str.Format("工具栏按钮%d",nIndex);
pTTT->lpszText=str.GetBuffer(str.GetLength());//设置按钮提示信息
pTTT->hinst=AfxGetResourceHandle();
return TRUE;

工具栏按钮上显示图标

在按钮上显示图标,方法跟显示位图差不到哪去,只要让CImageList里添加的是图标就行了,首先向工程引入六个图标,假设ID号分别为IDI_ICON1、IDI_ICON2....IDI_ICON6

以上面的工程为例:在OnInitDialog函数最后添加如下代码:

m_ImageList.Create(48,48,ILC_COLOR24|ILC_MASK,1,1);//图片大小必须一致
 for(int i=IDI_ICON1;i<=IDI_ICON6;i++)
   m_ImageList.Add(AfxGetApp()->LoadIcon(i));//添加图标

UINT nArray[6];
  for(i=0;i<6;i++)
  {
   nArray[i]=ID_BUTTON1+i;
  }
     m_Toolbar.CreateEx(this);//创建工具栏控件
  m_Toolbar.EnableToolTips();//激活信息提示功能
  m_Toolbar.SetButtons(nArray,6);
  m_Toolbar.SetSizes(CSize(60,56),CSize(48,48));
  m_Toolbar.GetToolBarCtrl().SetImageList(&m_ImageList);
  m_Rebar.Create(this);
  m_Rebar.AddBar(&m_Toolbar);
  m_Rebar.RedrawWindow();
  REBARBANDINFO info;
  info.cbSize=sizeof(info);
  info.fMask=RBBIM_BACKGROUND;
  m_Toolbar.ModifyStyle(0,TBSTYLE_TRANSPARENT);//设置工具栏背景色透明
  info.hbmBack=LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_TOOLBACK));
  m_Rebar.GetReBarCtrl().SetBandInfo(0,&info);
  RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

运行效果如下:

设置工具栏按钮热点图片

像前面的SetImageList函数设置工具栏按钮正常显示时的图片,而SetHotImageList函数是设置工具热点按钮图片,也就是当鼠标停留在按钮上所显示的图片,用法跟SetImageList函数一样,只是CImageList类关联的图片不一样。

为了显示热点按钮图片,我们得准备两组图片,一组用于正常显示,一组用于热点显示。这里我的图片格式是图标。还有一点要说明的是,工具栏必须具有TBSTYLE_FLAT(浮动按钮)属性,这一点在用CreateEx函数创建工具栏的时候,已经默认包含了。

两组图片:

正常显示:

热点显示:

工具栏背景位图:

首先向工程引入这十二个图标:假设正常显示的图标ID号依次为:IDI_NORMAL1、IDI_NORMAL2、。。。IDI_NORMAL6

热点图标ID依次为:IDI_HOT1、IDI_HOT2、。。。IDI_HOT6

然后引入背景位图,ID号为IDB_TOOLBACK

做完了这些,我们就向对话类里添加四个成员变量:

CToolBar m_Toolbar;
  CImageList m_ImageList;
  CImageList m_hotImageList;

CReBar m_Rebar;

然后增加五个宏定义:

#define ID_BUTTON1    501
#define ID_BUTTON2    502
#define ID_BUTTON3    503
#define ID_BUTTON4    504
#define ID_BUTTON5    505

接着在OnInitDialog函数添加如下代码:

m_ImageList.Create(48,48,ILC_COLOR24|ILC_MASK,1,1);//图片大小必须一致
 m_hotImageList.Create(48,48,ILC_COLOR24|ILC_MASK,1,1);
 for(int i=0;i<5;i++)
 {
   m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_NORMAL1+i));
   m_hotImageList.Add(AfxGetApp()->LoadIcon(IDI_HOT1+i));
 }
  UINT nArray[5];
  for(i=0;i<5;i++)
  {
   nArray[i]=ID_BUTTON1+i;
  }
  m_Toolbar.CreateEx(this);//创建工具栏控件
  m_Toolbar.SetButtons(nArray,5);
  m_Toolbar.SetSizes(CSize(60,56),CSize(48,48));
  m_Toolbar.GetToolBarCtrl().SetImageList(&m_ImageList);
  m_Toolbar.GetToolBarCtrl().SetHotImageList(&m_hotImageList);
  m_Rebar.Create(this);
  m_Rebar.AddBar(&m_Toolbar);
  m_Rebar.RedrawWindow();
  REBARBANDINFO info;
  info.cbSize=sizeof(info);
  info.fMask=RBBIM_BACKGROUND;
  m_Toolbar.ModifyStyle(0,TBSTYLE_TRANSPARENT);//设置工具栏背景色透明
  info.hbmBack=LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_TOOLBACK));
  m_Rebar.GetReBarCtrl().SetBandInfo(0,&info);
  RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,0);

运行效果:

CToolBarCtrl工具栏控制类

这个类的用法跟CToolBar的用法大同小异,模式都差不多,只需要了解一下这个类里的Create和AddButtons函数就行了,Create函数定义如下:

BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );

dwStyle:工具栏控件的风格     rect:工具栏位置和区域   pParentWnd:工具栏父窗口句柄(属于哪个窗口) nID:工具栏控件ID号

AddButtons函数用于往工具栏里添加一组按钮,函数定义如下:

BOOL AddButtons( int nNumButtons, LPTBBUTTON lpButtons );
nNumButtons:要添加的按钮数量 也就是函数第二个参数数组大小。lpButtons:一个TBBUTTON结构数组的地址

TBBUTON结构定义如下:
typedef struct _TBBUTTON
{
  int iBitmap; // 按钮显示的图片索引,没有图像为NULL,
  int idCommand; // 与此按钮相关联的命令标识符,当fsStyle具有TBSTYLE_SEP属性时,该项必须为0
  BYTE fsState; // 按钮的状态标志
  BYTE fsStyle; //按钮风格
  DWORD dwData; // 用户定义的数据

int iString; // 按钮显示的文本内容索引,无为NULL。
} TBBUTTON;

“MFC类库详解”关于fsState和fsStyle参数的解释如下:

fsState 按钮的状态标志。它可以是下面列出的值的一个组合: · TBSTATE_CHECKED 该按钮具有TBSTYLE_CHECKED风格并且被按下。 · TBSTATE_ENABLED 按钮接收用户输入。一个不具有这个状态的按钮是不接收用户输入的,并且变灰。 · TBSTATE_HIDDEN 按钮不可见,并且不能接收用户输入。 · TBSTATE_INDETERMINATE 按钮是变灰的。 · TBSTATE_PRESSED 按钮被按下。 · TBSTATE_WRAP 按钮之后是一个分隔线。此按钮还必须具有TBSTATE_ENABLED状态。 sStyle 按钮风格。它可以是下列值的一个组合: · TBSTYLE_BUTTON 创建一个标准的按钮。 · TBSTYLE_CHECK 创建一个每次用户点击时可以在按下和弹起状态间切换的按钮。该按钮则处于按下状态时有一种不同的背景颜色。 · TBSTYLE_CHECKGROUP 创建一个核选按钮,它被选择后一直处于按下状态,直到同组中的另一个按钮被按下时它才弹起。 · TBSTYLE_GROUP 创建一个被选择后一直处于按下状态,直到同组中的另一个按钮被按下时它才弹起的按钮。 · TBSTYLE_SEP 创建一个分隔线,为按钮组之间提供一个小的间距。具有这个风格的按钮是不接收用户输入的。

用CToolBarCtrl类在窗口里显示一个工具栏的步骤如下:

引入四个图标文件到工程里,然后在对话框类定义两个变量:

CImageList m_ImageList;
  CToolBarCtrl m_TBarCtrl;

然后在OnInitDialog函数添加如下代码:

TBBUTTON button[4];
 m_ImageList.Create(32,32,ILC_COLOR32|ILC_MASK,0,0);
 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON3));
 m_ImageList.Add(AfxGetApp()->LoadIcon(IDI_ICON4));
    m_TBarCtrl.Create(WS_CHILD|WS_VISIBLE,CRect(0,0,0,0),this,1200);
 m_TBarCtrl.SetImageList(&m_ImageList);
 for(int i=0;i<4;i++)
 {
  button[i].fsState=TBSTATE_ENABLED;
  button[i].fsStyle=TBSTYLE_BUTTON;
  button[i].iBitmap=i;
 }
    m_TBarCtrl.AddButtons(4,button);
 m_TBarCtrl.AutoSize();
 m_TBarCtrl.SetStyle(TBSTYLE_FLAT|CCS_TOP);

运行效果:

为CToolBarCtrl类创建的工具栏添加按钮单击处理消息

上面的TBBUTON结构里有一个成员idCommand,这个成员跟菜单项的ID值一样,用于标识工具栏按钮项,也就是说idCommand是工具栏项ID号,就是最前面设置工具栏资源时,选择一个按钮,然后按回车,弹出一个对话框,里面有一个ID项,跟这个是一样的。

所以呢,我们只要把上面的给TBBUTTON结构成员赋值的语句改成下面这样就行了:
 for(int i=0;i<4;i++)
 {
  button[i].fsState=TBSTATE_ENABLED;
  button[i].fsStyle=TBSTYLE_BUTTON;
  button[i].iBitmap=i;

button[i].idCommand=1100+i;//新加的语句
 }

这样我们只要添加ON_COMMAND消息映射就可以处理一个按钮单击消息了,如上面第一个按钮的ID号是:1100;那么手工添加这个按钮单击消息映射的语句就是:

ON_COMMAND(1100,OnToolbar1)

OnToolbar1为消息处理函数,可自行添加

自己动手绘制ToolBar,布布扣,bubuko.com

时间: 2024-10-26 00:45:18

自己动手绘制ToolBar的相关文章

【九天教您南方cass 9.1】 06 绘制方格网

同学们大家好,欢迎收看由老王测量上班记出品的cass9.1视频课程 我是本节课主讲老师九天. 我们讲课的教程附件也是共享的,请注意索取测量空间中. 九天老师的联系方式  点击直接请教九天老师吧! 这节课我们学习第6节绘制方格网. (高清视频请联系九天老师) 课程教案 地形图绘制完成后,需要为地形图绘制图框.地形图和其它制图不一样,因为它的图框需要以坐标为基础. 我们一般有自己动手绘制的,电脑绘制的两种. 手工绘制方格网:有多种方法看要求自行选择. 第一种: 第一步 命令: rectang 指定第

利用迅捷画图绘制精美流程图操作方法介绍

流程图在当下移动互联网的发展中占据举足轻重的地位,在工作学习中经常广泛使用,那为什么这么受欢迎呢?虽然不能一味的模仿,但是具体操作流程框架可以更直观的展示操作步骤,可以在基础操作中对内容进行扩展也可以达到意想不到的效果呢. 工具/原料: 能上网的电脑并带有浏览器 迅捷画图在线网站 推荐理由: 迅捷画图是集自己动手绘制与套用模板为一体的在线编辑流程图网站,并且里面可以添加链接,图片等元素.套用模板直接将其内容修改为自己需要的内容即可,使用都比较方便. 操作方法介绍:1.进入迅捷画图官网中,在列表页

在线绘制思维导图精简方法

绘制思维导图有由最开始的手绘变为软件绘制现在是在线绘制,这样无论在哪只要有电脑就可以操作,不会因为没有绘制软件而不能操作,那具体要怎样在线绘制思维导图呢?下面是小编经常使用的操作方法,分享给大家,希望可以帮助到你们. 工具/原料: 迅捷画图在线网站,能上网的电脑并带有浏览器 操作方法介绍: 1.进入迅捷画图官网中,在上述列表中有三项操作,选择模板点击进去可以看到有很多制作精美的模板,并且不同的分类归纳的很清楚,需要套用模板的可以点击模板进行编辑使用. 2.需要动手绘制可以从模板页面中返回首页,点

如何绘制思维导图

思维导图是很实用的工具,可以将我们的思维最大化的展示出来,发挥个人潜力,可以通过文字,图片,颜色,等进行展示,最好通过图文并茂的形式进行展示,这样会加大视觉体验,可以让思维导图发挥其更大的用途,当然也有很多绘制思维导图的书籍,里面有很多理论知识,但是看完之后很容易忘记,所以自己动手绘制是一件很好的方法,那要如何绘制思维导图呢?下面是分享的操作方法希望可以帮助到大家. 绘制工具及原料: 电脑,网线 绘制方法: 1.小编这里讲述的是利用在线网站绘制思维导图,那要做的就是在百度中搜索在线绘制思维导图工

Python 电路绘制库 schemdraw 你会吗?【面试必学】

前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:skyztttt 引子 由于最近在学习ardunio的使用,其中牵涉到绘制一些简单的电路图,又不愿意使用一些复杂的软件进行绘制,调查中发现python中的schemdraw库就能很好地完成这个任务,遂学习使用之.如果你还没学到Python绘制库,建议你先去小编的Python学习.裙 :一久武其而而流一思(数字的谐音)转换下可以找到了,里面有最新Python教程项目,多跟

Android仿京东首页轮播文字(又名垂直跑马灯)

Android仿京东首页轮播文字(又名垂直跑马灯) 京东客户端的轮播文字效果: 本次要实现的只是后面滚动的文字(前面的用ImageView或者TextView实现即可),看一下实现的效果 实现思路 上图只是一个大概的思路,要实现还需要完善更多的细节,下面会一步步的来实现这个效果: 1.封装数据源:从图上可以看到,轮播的文字是分为两个部分的,暂且把它们分别叫做前缀和内容,而且实际的使用过程中点击轮播图肯定是需要跳转页面的,而且大部分应该是WebView,不妨我们就设置点击时候需要获取的内容就是一个

在Delphi中显示Windows图标

栏目刊登了一篇<提取图标的Delphi控件>的文章,所介绍的方法可以用于提取包含在文件中的图标,但对于本身没有包含图标的文件却无法像Windows的“资源管理器”那样显示出其默认的图标.本文介绍了在Delphi的ListView组件中显示这种图标的方法,和<提取图标的Delphi控件>一文结合起来就可以显示出几乎所有的图标了.该方法的一大特色是不用绘制任何图标就能够显示许多Windows图标. 原文来自: [100脚本网 www.pc100.net] ---- 大量的图标显示是Wi

Java虚拟机原理图解 2.3、常量池详解(下)

[java] view plaincopyprint? package com.louis.jvm; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public 

Java实现红黑树

转自:http://www.cnblogs.com/skywang12345/p/3624343.html 红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键值,小于等于右孩子的键值.除了具备该特性之外,红黑树还包括许多额外的信息. 红黑树的每个节点上都有存储位表示节点的颜色,颜色是红(Red)或黑(Black).红黑树的特性:(1) 每个节点或者