如何優雅的寫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 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM