讓ListBox控制項每一行顯示不同的顏色

來源:互聯網
上載者:User

最近用MFC做個小項目,想要讓ListBox中的每一行都根據自訂的顏色來顯示不同的顏色。剛開始把MFC想的太簡單了,拖了一個ListBox控制項然後綁定了一個變數m_ListBox。

在主對話方塊的OnInitDialog()函數中我調用了下面的代碼

m_ListBox.AddString(_T("這是一個小測試!"));m_ListBox.SetItemData(0,RGB(0,0,255));
運行後發現顯示的仍是預設的黑色。

後來查閱相關資料,才發現微軟將這些控制項的字型和顏色等屬性都是設定為預設的,普通的屬性設定函數根本沒用。要想在ListBox或者ListCtrl等控制項中繪製你想要的圖形或者設定你想要的屬性,那麼必須採用自繪的方式。

介面方面的編程有時就是一層窗戶紙,捅破了就好。下面是實現的具體過程:

1.拖一個ListBox控制項設定一下屬性。其中Owner draw屬性要設定成Variable,Has strings要勾選


2.自訂一個派生自CListBox的類CColorListBox。重載下面兩個虛函數

virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
然後定義一個介面用來讓我們調用,根據傳入的字串和RGB值讓ListBox的每一行根據我們自訂的顏色來顯示

public:int AddString(LPCTSTR lpszItem, COLORREF itemColor = RGB(255,0,0));

下面是上面3個函數的具體定義


/////////////////////////////////////////////////////////********************************************************************//**//* Function name : AddString*//* Description   : Add string to the listbox and save color info.*//**//********************************************************************/int CColorListBox::AddString(LPCTSTR lpszItem, COLORREF itemColor){// Add the string to the list boxint nIndex = CListBox::AddString(lpszItem);   // save color dataif (nIndex >= 0)SetItemData(nIndex, itemColor);return nIndex;}/********************************************************************//**//* Function name : DrawItem*//* Description   : Called by the framework when a visual aspect of*//*   an owner-draw list box changes.*//**//********************************************************************/void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {    // Losing focus ?    if (lpDrawItemStruct->itemID == -1) {DrawFocusRect(lpDrawItemStruct->hDC, &lpDrawItemStruct->rcItem);return;    }CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);COLORREF clrOld;CString sText;// get color info from item dataCOLORREF clrNew = (COLORREF)(lpDrawItemStruct->itemData);// item selected ?if ((lpDrawItemStruct->itemState & ODS_SELECTED) && (lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE))){CBrush brush(::GetSysColor(COLOR_HIGHLIGHT));pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);}// item deselected ?if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&(lpDrawItemStruct->itemAction & ODA_SELECT)){CBrush brush(::GetSysColor(COLOR_WINDOW));pDC->FillRect(&lpDrawItemStruct->rcItem, &brush);} // item has focus ?if ((lpDrawItemStruct->itemAction & ODA_FOCUS) && (lpDrawItemStruct->itemState & ODS_FOCUS)){pDC->DrawFocusRect(&lpDrawItemStruct->rcItem); }// lost focus ?if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&!(lpDrawItemStruct->itemState & ODS_FOCUS)){pDC->DrawFocusRect(&lpDrawItemStruct->rcItem); }// set the background mode to TRANSPARENTint nBkMode = pDC->SetBkMode(TRANSPARENT);if (lpDrawItemStruct->itemState & ODS_SELECTED)clrOld = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));else if (lpDrawItemStruct->itemState & ODS_DISABLED)clrOld = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));elseclrOld = pDC->SetTextColor(clrNew);// get item textGetText(lpDrawItemStruct->itemID, sText);CRect rect = lpDrawItemStruct->rcItem;// text formatUINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;if (GetStyle() & LBS_USETABSTOPS)nFormat |= DT_EXPANDTABS;// draw the textpDC->DrawText(sText, -1, &rect, nFormat);// restore old valuespDC->SetTextColor(clrOld); pDC->SetBkMode(nBkMode);}void CColorListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_CYMENUCHECK);}

3.現在我們可以測試一下。拖一個ListBox控制項,然後定義一個CColorListBox 類型的變數m_ListBox。你可以直接在下面所對應的位置手動添加如下代碼,也可以通過MFC ClassWizard自動添加。

在主對話方塊標頭檔中標頭檔中添加

// Dialog Data//{{AFX_DATA(CLogSystemTestDlg)         ........CColorListBoxm_ListBox;//}}AFX_DATA

在主對話方塊的代碼檔案中的DoDataExchange()函數中添加代碼

DDX_Control(pDX, IDC_LIST1, m_ListBox);
目的是將變數m_ListBox和IDC_LIST1標識的清單控制項綁定,具體代碼如下

void CTestDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CLogSystemTestDlg)DDX_Control(pDX, IDC_LIST1, m_ListBox);//}}AFX_DATA_MAP}

在主對話方塊的代碼檔案中的OnInitDIalog()函數中添加測試代碼

BOOL CLogSystemTestDlg::OnInitDialog(){CDialog::OnInitDialog();...........// TODO: Add extra initialization herem_ListBox.AddString("空山新雨後",RGB(255,0,0));m_ListBox.AddString("天氣晚來秋",RGB(0,255,0));m_ListBox.AddString("明月松間照",RGB(0,0,255));m_ListBox.AddString("清泉石上流",RGB(255,0,255));return TRUE;  // return TRUE  unless you set the focus to a control}


編譯運行後效果如下所示


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.