zoukankan      html  css  js  c++  java
  • 如何优雅的写UI——(4)选项卡美化

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

    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(32, 32, ILC_COLOR32 | ILC_MASK, 3, 1);
        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)-1,
       BOOL bDetachable = TRUE
    );

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

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

    做好的图标就是这个样子

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

    标签在顶部/底部

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

    添加关闭页面按钮

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

    把某一页选项置顶

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

    设置选项卡样式

        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 (121, 210, 231));
        arColors.Add (RGB (190, 218, 153));
        arColors.Add (RGB (255, 170, 100));
    
        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, 3000, CMFCTabCtrl::LOCATION_TOP,0))
        {
            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(32, 32, ILC_COLOR32 | ILC_MASK, 3, 1);
        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控件",0,TRUE);
        m_tab.AddTab(m_dlg2,L"还没想好些什么控件",1,FALSE);
        m_tab.AddTab(m_dlg3,L"还有什么控件比较难写吗",2,FALSE);
    
    
        //m_tab.SetLocation (CMFCTabCtrl::LOCATION_BOTTOM);//Tab标签在底部
        m_tab.SetLocation (CMFCTabCtrl::LOCATION_TOP);//Tab标签在顶部
    
        m_tab.EnableActiveTabCloseButton();//是否添加关闭选项卡按钮
    
        m_tab.SetActiveTab(1); //激活选项卡,以当前选项卡为第一页。
    
        //m_tab.ModifyTabStyle (style);//设置CMFCTabCtrl的样式
    
        CArray<COLORREF, COLORREF> arColors;
        arColors.Add (RGB (121, 210, 231));
        arColors.Add (RGB (190, 218, 153));
        arColors.Add (RGB (255, 170, 100));
    
        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 

  • 相关阅读:
    redis之(十二)redis数据的持久化
    redis之(十一)redis实现缓存的功能
    redis之(十)redis实现消息中间件的功能
    redis之(九)redis的事务机制
    SQL关于IN和EXISTS的用法和区别的比较
    mysql explain extra理解
    mysql explain rows理解
    mysql explain中key_len值的说明
    redis常见重要性能指标数据分析和相关问题解决方案
    java.lang.UnsupportedOperationException解决方法!!!
  • 原文地址:https://www.cnblogs.com/ye-ming/p/9276997.html
Copyright © 2011-2022 走看看