使用CustomDraw來自繪CListCtrl控件

轉自:http://www.cnblogs.com/caojianzhao/archive/2011/11/06/2238312.html


Custom Draw 基礎
  我將會盡我所能把Custom Draw的處理描述清楚,而不是簡單的引用MSDN的文檔。這些例子都需要你的程序有一個ListCtrl在對話框上,並且這個ListCtrl處於Report和多列模式。
Custom draw可以被想象成一個輕量級的,容易使用的重繪方法(重繪方法還有幾種,例如Owner Draw等)。這種容易來自於我們只需要處理一個消息(NM_CUSTOMDRAW),就可以讓Windows爲你幹活了,你就不用被逼去處理"重繪過程"中所有的髒活了。
Custom Draw 的消息映射入口
  Custom draw 是一個類似於回調的處理過程,Windows在繪製List Ctrl的某個時間點上通過 Notification 消息通知你的程序,你可以選擇忽略所有的通知(這樣你就會看到標準的ListCtrl),或者處理某部分的繪製(實現簡單的效果),甚至整個的控件都由你來繪製(就象使用Owner-Drawing一樣)。這個機制的真正賣點是:你只需要實現一些你需要的,其餘的可以讓Windows爲你代勞。
開始使用Custom draw
首先添加一個消息映射:
1.在xxxx.cpp文件中的BEGIN_MESSAGE_MAP下添加,其中IDC_LIST1是CListCtrl控件的ID
ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, OnCustomdrawList)//cjz

複製代碼
BEGIN_MESSAGE_MAP(CDemoListDlg, CDialog)
    //{{AFX_MSG_MAP(CDemoListDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_NOTIFY(NM_CUSTOMDRAW, IDC_LIST1, OnCustomdrawList)//cjz
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
複製代碼
2.在xxxx.h文件類的聲明內添加
public:
    afx_msg void OnCustomdrawList(NMHDR*, LRESULT*);//cjz

3.在xxxx.cpp中寫函數實現

複製代碼
 1 voidCRollMainView::OnCustomdrawList(NMHDR *pNMHDR, LRESULT *pResult)
 2 {
 3     //////////////////////////////////////////////////////
 4     NMLVCUSTOMDRAW* pLVCD = reinterpret_cast<NMLVCUSTOMDRAW*>( pNMHDR );
 5 
 6     // Take the default processing unless we 
 7 
 8 // set this to something else below.
 9 
10     *pResult = CDRF_DODEFAULT;
11 
12     // First thing - check the draw stage. If it's the control's prepaint
13 
14 // stage, then tell Windows we want messages for every item.
15 
16 
17     if ( CDDS_PREPAINT == pLVCD->nmcd.dwDrawStage )
18     {
19         *pResult = CDRF_NOTIFYITEMDRAW;
20     }
21     else if ( CDDS_ITEMPREPAINT == pLVCD->nmcd.dwDrawStage )
22     {
23         COLORREF crText,crBk;
24      //奇偶判斷
25         if ( (pLVCD->nmcd.dwItemSpec % 2) == 0 ){
26             crText = RGB(0,0,0);//RGB(32,32,255);
27             crBk =RGB(229,232,239);
28         }
29         else if ( (pLVCD->nmcd.dwItemSpec % 2) == 1 ){
30             crText = RGB(0,0,0);
31             crBk = RGB(240,247,249);
32         }
33         else{
34             crText = RGB(0,0,0);
35             crBk = RGB(0,0,126);
36         }
37         
38         // Store the color back in the NMLVCUSTOMDRAW struct.
39 
40         pLVCD->clrText = crText;
41         pLVCD->clrTextBk = crBk;
42         //設置選擇項的顏色
43         if( this->m_ctrlList.GetItemState(pLVCD->nmcd.dwItemSpec, CDIS_SELECTED) ){
44             crBk =RGB(75, 149, 229);//itunes//RGB(10, 36, 106);//RGB(0, 0, 64);
45             crText = RGB(255,255,255);
46             pLVCD->clrText = crText;
47             pLVCD->clrTextBk = crBk;
48             *pResult = CDRF_NEWFONT;
49         }
50         if(LVIS_SELECTED == m_ctrlList.GetItemState(pLVCD->nmcd.dwItemSpec,LVIS_SELECTED))
51         {
52             //清除選擇狀態,如果不清除的話,還是會顯示出藍色的高亮條
53             BOOL b = m_ctrlList.SetItemState(pLVCD->nmcd.dwItemSpec,0,LVIS_SELECTED); 
54             pLVCD->clrText = crText;
55             pLVCD->clrTextBk = crBk;
56 
57             *pResult = CDRF_NEWFONT;
58             return;
59         }
60         *pResult = CDRF_NEWFONT;
61         //*pResult = CDRF_DODEFAULT;
62     }
63 }
複製代碼

經過以上三步就完成了Custom draw消息的添加,可以實現一些簡單的美化效果。

一些需要注意的細節

  如果你有一個從ClistCtr派生的類,你想爲它添加custom draw,你就可以使用ON_NOTIFY_REFLECT來代替。如下:

ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW, OnCustomdraw )

OnCustomdraw的原形和上面的函數一致,但它是聲明在你的派生類裏的。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章