现在做出来的选项卡实在太丑的,咱们怎么把他弄得好看一点呢

tabctrl是可以添加icon图标的,那派生与tabctrl的mfctabctrl肯定也能添加图标,他们两个添加图标的原理一样,但是还是有点不同

首先给项目添加三个图标

然后在成员变量中添加ImageList对象,必须要添加在成员变量中,否则加载不出来图片。

    CImageList m_imglist;

之后在初始化中创建CImageList,他的声明为

BOOL Create(int cx, int cy, UINT nFlags, int nInitial, int nGrow);

其中各项参数的含义为:

cx定义图像的宽度,单位为象素;

cy定义图象的高度,单位为象素;

nFlags确定建立图像列表的类型,

可以是以下值的组合:ILC_COLOR、ILC_COLOR4(图像为24色)、ILC_COLOR8(图像为28色)、ILC_COLOR16(图像为216色)、ILC_COLOR24、ILC_COLOR32、ILC_COLORDDB和ILC_MASK;

nInitial用来确定图像列表包含的图像数量;

nGrow用来确定图像列表可控制的图像数量。

图像控制的属性类包括返回m_hImageList.控制句柄GetSafeHandle、取得图像列表中的图像数量GetImageCount、设置图像列表的背景颜色SetBkColor、取得图像列表的背景颜色SetBkColor和取得图像的有关信息SetBkColor。

图像控制的操作方法包括将一个图像列表绑定到一个对象上Attach、将对象上的图像列表解除绑定并返回句柄Detach、删除一个图像列表DeleteImageList、将一个图像增加到图像列表中Add和将一个图像从图像列表中删除Remove等。

我们来添加三个图标

m_imglist.Create(, , ILC_COLOR32 | ILC_MASK, , );
m_imglist.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_imglist.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_imglist.Add(AfxGetApp()->LoadIcon(IDI_ICON3));
m_tab.SetImageList(m_imglist);//将ImageList绑定到tab上

要注意的是SetImageList这个方法,根据MSDN上的描述,当你创建tabctrl为平面样式,例如 STYLE_FLAT 时,你的图标加载是失败的,平面样式不支持图标的绑定,这个一定要注意了。

例如这样

我们将图标写进了队列,也绑定上了选项卡,但是如何让页面知道我是用到了哪个图标呢,这得回到添加标签页的地方,我们来看AddTab的方法定义

virtual void AddTab(
CWnd* pTabWnd,
UINT uiResTabLabel,
UINT uiImageId = (UINT)-,
BOOL bDetachable = TRUE
);

这里给出一个uiImageId 的参数,这个是图标的索引,你第几个页面要用到哪个图标,你就要填这个图标在CImageList 队列里的索引值。例如我第二个画面m_dlg2要用到第一个图标,第一个图标的索引值为0;就应该为

m_tab.AddTab(m_dlg2,L"还没想好些什么控件",,FALSE);

做好的图标就是这个样子

CSDN上还有很多样式定义,但是也有很多不能用,我不知道为什么,下面来举几个例子

标签在顶部/底部

    m_tab.SetLocation (CMFCTabCtrl::LOCATION_BOTTOM);//Tab标签在底部
m_tab.SetLocation (CMFCTabCtrl::LOCATION_TOP);//Tab标签在顶部

添加关闭页面按钮

m_tab.EnableActiveTabCloseButton();//是否添加关闭选项卡按钮

把某一页选项置顶

m_tab.SetActiveTab(); //激活选项卡,以当前选项卡为第一页。

设置选项卡样式

    m_tab.ModifyTabStyle (style);//设置CMFCTabCtrl的样式

参数:
STYLE_3D 三维样式。
STYLE_3D_ONENOTE Microsoft OneNote样式。
STYLE_3D_VS2005 Microsoft Visual Studio 2005样式。
STYLE_3D_SCROLLED 三维与矩形选项卡标签的样式。
STYLE_FLAT_SHARED_HORZ_SCROLL 有共享水平滚动条的平面样式。
STYLE_3D_ROUNDED_SCROLL 三维与设置选项卡标签的样式。
 

标签拖拽

m_tab.EnableTabSwap (TRUE);//可以拖拽
m_tab.EnableTabSwap (FALSE);//不可拖拽

选项卡标签和边框颜色

    CArray<COLORREF, COLORREF> arColors;
arColors.Add (RGB (, , ));
arColors.Add (RGB (, , ));
arColors.Add (RGB (, , )); m_tab.EnableAutoColor (TRUE);
m_tab.SetAutoColors (arColors);

整个选项卡初始化代码

void CtabView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit(); CRect rc;
GetClientRect(rc); if (!m_tab.Create(CMFCTabCtrl::STYLE_3D_ONENOTE, rc, this, , CMFCTabCtrl::LOCATION_TOP,))
{
return ;
} m_dlg1=new CDialog1;
m_dlg2=new CDialog2;
m_dlg3=new CDialog3; m_dlg1->Create(IDD_DIALOG1,&m_tab);
m_dlg1->SetFont(&afxGlobalData.fontRegular);
m_dlg1->SetWindowTextW(L"Listctrl控件"); m_dlg2->Create(IDD_DIALOG2,&m_tab);
m_dlg2->SetFont(&afxGlobalData.fontBold);
m_dlg2->SetWindowTextW(L"还没想好些什么控件"); m_dlg3->Create(IDD_DIALOG3,&m_tab);
m_dlg3->SetFont(&afxGlobalData.fontDefaultGUIBold);
m_dlg3->SetWindowTextW(L"还有什么控件比较难写吗"); m_imglist.Create(, , ILC_COLOR32 | ILC_MASK, , );
m_imglist.Add(AfxGetApp()->LoadIcon(IDI_ICON1));
m_imglist.Add(AfxGetApp()->LoadIcon(IDI_ICON2));
m_imglist.Add(AfxGetApp()->LoadIcon(IDI_ICON4));
m_tab.SetImageList(m_imglist); m_tab.AddTab(m_dlg1,L"Listctrl控件",,TRUE);
m_tab.AddTab(m_dlg2,L"还没想好些什么控件",,FALSE);
m_tab.AddTab(m_dlg3,L"还有什么控件比较难写吗",,FALSE); //m_tab.SetLocation (CMFCTabCtrl::LOCATION_BOTTOM);//Tab标签在底部
m_tab.SetLocation (CMFCTabCtrl::LOCATION_TOP);//Tab标签在顶部 m_tab.EnableActiveTabCloseButton();//是否添加关闭选项卡按钮 m_tab.SetActiveTab(); //激活选项卡,以当前选项卡为第一页。 //m_tab.ModifyTabStyle (style);//设置CMFCTabCtrl的样式 CArray<COLORREF, COLORREF> arColors;
arColors.Add (RGB (, , ));
arColors.Add (RGB (, , ));
arColors.Add (RGB (, , )); m_tab.EnableAutoColor (TRUE);
m_tab.SetAutoColors (arColors); m_tab.EnableTabSwap (TRUE);//可以拖拽
//m_tab.EnableTabSwap (FALSE);//不可拖拽
}

阶段效果

到现在还是觉得这个选项卡难看,咱们继续美化

首先每个窗口背景色太难看了,我们来把背景色换成白的

改变背景色有很多种方法,有OnCtlColor、OnPaint、 OnEraseBkgnd都可以改变背景色,这个现在不用太纠结选哪种,随便用一个就行,但是他们的添加方法都相同。

在每一个子窗口中添加消息函数WM_CTLCOLOR。实现方法返回一个系统自定义的白色画刷WHITE_BRUSH。

HBRUSH CDialog1::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor); // TODO: 在此更改 DC 的任何特性 // TODO: 如果默认的不是所需画笔,则返回另一个画笔
return (HBRUSH)::GetStockObject(WHITE_BRUSH);
}

那么美化暂时先到这,要想画出更好看的选项卡,就需要涉及到控件重绘了,也就是自定义控件,这篇帖子我会持续更新的。马上我就要开下一篇功能实现的帖子。

代码:选项卡美化.zip

如何优雅的写UI——(4)选项卡美化的更多相关文章

  1. 如何优雅的写UI——(5)选项卡功能实现

    先在我们的选项卡可以说能用了,每个标签页都能点进去,但是这还远远没到能用的地步,比如说你把窗口最大化后. 立马就露出马脚了,所以这篇我们要先讲讲tabctrl的最基本的功能实现 改变选项卡大小 上图的 ...

  2. 如何优雅的写UI——(3)添加MFC选项卡

    窗体创建完成,接下来我们讲讲控件的使用 首先在CFormView窗体下选项卡的成员变量,这里我选择MFC下的选项卡类库:CMFCTabCtrl class CtabView : public CFor ...

  3. 如何优雅的写UI——(6)内存泄漏

    控件讲了这么久,其实我的程序有两个Bug不知道大家有没有发现,这两个Bug都不会报错,对程序运行来说都没有阻碍,但是这种Bug对整个代码来说是一个很大的安全隐患. 什么是内存泄漏 内存泄漏(Memor ...

  4. 如何优雅的写UI——(2)MFC下基于CFormView的文档视图程序

    在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...

  5. 如何优雅的写UI——(1)MFC六大核心机制-程序初始化

    很多做软件开发的人都有一种对事情刨根问底的精神,例如我们一直在用的MFC,很方便,不用学太多原理性的知识就可以做出各种窗口程序,但喜欢钻研的朋友肯定想知道,到底微软帮我们做了些什么,让我们在它的框架下 ...

  6. 基于jQuery UI的tabs选项卡美化

    很多朋友对JS望而生畏,但听很多朋友说jQuery很简单,因此开始使用jQuery,使用之后发现,只会写简单的功能,复杂的功能还是不太会写或者总是担心自己写的有性能问题,对前端人员来说只能通过不断学习 ...

  7. 我为什么还要造轮子?欠踹?Monk.UI表单美化插件诞生记!

    背景 目前市场上有很多表单美化的UI,做的都挺不错,但是他们都有一个共同点,那就是90%以上都是前端工程师开发的,导致我们引入这些UI的时候,很难和程序绑定.所以作为程序员的我,下了一个决定!我要自己 ...

  8. 优雅的写好Vue项目代码 — 路由拆分、Vuex模块拆分、element按需加载

    目录 路由的拆分 VUEX模块拆分 Element UI库按需加载的优雅写法 路由的拆分 项目较大路由较多时,路由拆分是一个不错的代码优化方案,按不同业务分为多个模块,结构清晰便于统一管理. requ ...

  9. 关于如何写UI及屏幕适配的一些技巧

    因为公司开启了一个新的iOS项目, 所以近期比较忙, 没有更新博客,今天打算总结一下关于UI布局及屏幕适配的一些实战技巧,尤其使用纯代码,会对提升效率及代码易于维护等方面有明显帮助,这里提到的没有使用 ...

随机推荐

  1. js字符串排序方法

    前端开发过程中有时需自己手写排序方法 一般想到数字的字符串排序方法 我们会用到 var newArr = arr. sort(function(a,b){return a - b})来进行排序 但除此 ...

  2. CF402E Strictly Positive Matrix(矩阵,强联通分量)

    题意 给定一个 n∗n 的矩阵 A,每个元素都非负判断是否存在一个整数 k 使得 A^k 的所有元素 >0 n≤2000(矩阵中[i][i]保证为1) 题解 考虑矩阵$A*A$的意义 ,设得到的 ...

  3. Git学习笔记 1,GitHub常用命令1

    廖雪峰Git教程 莫烦Git教程 莫烦Git视频教程 --------------- init > apt-get install git # 安装 > mkdir /home/yzn_g ...

  4. 恐怖的奴隶主(bob)

    题目 试题3:恐怖的奴隶主(bob) 源代码:bob.cpp 输入文件:bob.in 输出文件:bob.out 时间限制:1s 空间限制:512MB 题目描述 小L热衷于undercards. 在un ...

  5. 题解 P3605 【[USACO17JAN]Promotion Counting晋升者计数】

    这道题开10倍左右一直MLE+RE,然后尝试着开了20倍就A了...窒息 对于这道题目,我们考虑使用线段树合并来做. 所谓线段树合并,就是把结构相同的线段树上的节点的信息合在一起,合并的方式比较类似左 ...

  6. 【Codeforces Round #462 (Div. 1) A】 A Twisty Movement

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] ans初值值为a[1..n]中1的个数. 接下来考虑以2为结尾的最长上升子序列的个数. 枚举中间点i. 计算1..i-1中1的个数c ...

  7. ArcGIS api for javascript——用图表显示查询结果

    描述 本例展示了如何使用查询任务结果用去Google Chart API构建一个图表.当运行本例,点击一个郡县去看出现在一个无焦点的InfoWindow中的人口统计的数据的图表. 函数init创建了一 ...

  8. CCNP路由实验之六 动态路由协议之IS-IS

     CCNP路由实验之六动态路由协议之IS-IS 动态路由协议能够自己主动的发现远程网络.仅仅要网络拓扑结构发生了变化.路由器就会相互交换路由信息,不仅能够自己主动获知新添加的网络.还能够在当前网络 ...

  9. generate the call load file

    #!/usr/bin/perl -w $e911_call_percent = 0.0; $ims_node_number = 12; $local_ip = "10.86.52.2&quo ...

  10. iOS xib View宽高不能改变

    IOS - xib(Interface Builder,view) - can't change view size(view不能改变大小问题) 今天在试着swift语言写个demo,,当中遇到了这个 ...