程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 修改一個完全顏色的CListCtrl類

修改一個完全顏色的CListCtrl類

編輯:關於VC++

在使用CListCtrl控件的過程中,我們會發現使用及其不方便,特別是在使用“report"顯示模式時, 想給指定條目添加背景顏色,CListCtrl控件所提供的設置顏色函數只能使得控件的界面變得好看一些,根本不能滿足我們的要求,我們無法把特定的一項或幾項添加上不同的顏色以示區別。 幸運的是很多VC的使用者在改造CListCtrl類,使之更加功能強大上做了很多工作,開發出了各種各樣的繼承類來實現這個功能,Sven Freitag 就是其中的一員。他開發出了CListCtrl的繼承類CColorListCtrl來實現給指定的條目加背景色的功能,並無償的在網上公布給VC的使用者,我在源代碼中收集了他的源程序,各位讀者可以先閱讀學習一下。

CColorListCtrl類示例代碼運行效果如下圖所示:

怎樣使用CColorListCtrl類:

1、把下面的文件加入你的工程中去:

color.h
color.cpp
ColorListCtrl.h
ColorListCtrl.cpp

2、在對話框頭文件中加入ColorListCtrl.h的說明,然後用CColorListCtrl代替CListCtrl聲明成員變量。

3、具體的使用方法,請看示例代碼中的ColoredListCtrlDlg.cpp文件。

CColorListCtrl類存在的不足:

在使用CColorListCtrl類的過程中,我體會到了隨意添加條目顏色的樂趣,但同時也發現它存在的一些不足之處。下面我列出color.h和color.cpp文件代碼來進行分析。color.h源代碼如下所示:

// Author: SFr [email protected]
#ifndef AFX_COLOR_H__9FC7D36B_FC88_42FD_8DAA_2F70016038BA__INCLUDED_
#define AFX_COLOR_H__9FC7D36B_FC88_42FD_8DAA_2F70016038BA__INCLUDED_
#include "windows.h"
typedef enum
{
   DEF_BACKGROUND=0, DEF_TEXT, DEF_SELBACKGROUND, DEF_SELTEXT, DEF_DESELBACKGROUND, DEF_DESELTEXT,
     BLACK,BLUE,GREEN,CYAN,RED,
     MANGENTA,YELLOW,WHITE,DARKBLUE,DARKGREEN,
     BLUEGREEN,BROWN,PURPUR,OLIV,DARKGRAY,
     LIGHTGRAY,LIGHTBLUE,DARKWHITE,MIDDLEGRAY
}
ITEM_COLOR;
typedef struct
{
   char str[50];
   ITEM_COLOR col;
}ColorList;
#define COLLIST_MAX 25
extern ColorList colList[COLLIST_MAX];
COLORREF GetColorRef(ITEM_COLOR lParam);
#endif
color.cpp源代碼如下所示:
// Author: SFr [email protected]
#include "stdafx.h"
#include "color.h"
ColorList colList[COLLIST_MAX]=
{
   {"DEF_BACKGROUND",DEF_BACKGROUND},
   {"DEF_TEXT",DEF_TEXT},
   {"DEF_SELBACKGROUND",DEF_SELBACKGROUND},
   {"DEF_SELTEXT",DEF_SELTEXT},
   {"DEF_DESELBACKGROUND",DEF_DESELBACKGROUND},
   {"DEF_DESELTEXT",DEF_DESELTEXT},
   {"BLACK",BLACK},
   {"BLUE",BLUE},
   {"GREEN",GREEN},
   {"CYAN",CYAN},
   {"RED",RED},
   {"MANGENTA",MANGENTA},
   {"YELLOW",YELLOW},
   {"WHITE",WHITE},
   {"DARKBLUE",DARKBLUE},
   {"DARKGREEN",DARKGREEN},
   {"BLUEGREEN",BLUEGREEN},
   {"BROWN",BROWN},
   {"PURPUR",PURPUR},
   {"OLIV",OLIV},
   {"DARKGRAY",DARKGRAY},
   {"LIGHTGRAY",LIGHTGRAY},
   {"LIGHTBLUE",LIGHTBLUE},
   {"DARKWHITE",DARKWHITE},
   {"MIDDLEGRAY",MIDDLEGRAY}
};
COLORREF GetColorRef(ITEM_COLOR lParam)
{
   switch (lParam)
   {
   case DEF_BACKGROUND: return ::GetSysColor(COLOR_WINDOW); break;
   case DEF_TEXT: return ::GetSysColor(COLOR_WINDOWTEXT); break;
   case DEF_SELBACKGROUND: return ::GetSysColor(COLOR_ACTIVECAPTION); break;
   case DEF_SELTEXT: return ::GetSysColor(COLOR_HIGHLIGHTTEXT); break;
   case DEF_DESELBACKGROUND: return ::GetSysColor(COLOR_INACTIVECAPTION); break;
   case DEF_DESELTEXT: return ::GetSysColor(COLOR_INACTIVECAPTIONTEXT ); break;
   case BLACK: return RGB(0,0,0); break; //black
   case BLUE: return RGB(0,0,255); break; //blue
   case GREEN: return RGB(0,255,0); break; //green
   case CYAN: return RGB(0,255,255); break; //cyan
   case RED: return RGB(255,0,0); break; //red
   case MANGENTA: return RGB(255,0,255); break; //mangenta
   case YELLOW: return RGB(255,255,0); break; //yellow
   case WHITE: return RGB(255,255,255);break; //white
   case DARKBLUE: return RGB(0,0,128); break; //dark-blue
   case DARKGREEN: return RGB(0,128,0); break; //dark-green
   case BLUEGREEN: return RGB(0,128,128); break; //blue-green
   case BROWN: return RGB(128,0,0); break; //brown
   case PURPUR: return RGB(128,0,128); break; //purpur
   case OLIV: return RGB(128,128,0); break; //oliv
   case DARKGRAY: return RGB(128,128,128);break; //dark-gray
   case LIGHTGRAY: return RGB(192,192,192);break; //light-gray
   case LIGHTBLUE: return RGB(166,202,240);break; //light-blue
   case DARKWHITE: return RGB(255,251,240);break; //dark-white
   case MIDDLEGRAY: return RGB(160,160,164);break; //middle-gray
   default: return RGB(0,128,0); break; //dark-green
   }
}

由上述源代碼可以看出,CColorListCtrl類給我們提供的可供填充的顏色數量十分有限,只有BLACK,BLUE,GREEN,CYAN,RED,MANGENTA,YELLOW,WHITE,DARKBLUE,DARKGREEN,BLUEGREEN,BROWN,PURPUR,OLIV,DARKGRAY,LIGHTGRAY,LIGHTBLUE,DARKWHITE,MIDDLEGRAY等幾種,完全不能滿足我們隨時定制自己所需顏色的要求,因此我對這個類進行了一些修改,以使得能隨心所欲的填充任何顏色。

對CColorListCtrl類修改的地方如下所示:

1、完全去掉color.h和color.cpp源文件,只把ColorListCtrl.h和ColorListCtrl.cpp源文件導入自己的工程中;

2、把ColorListCtrl.h頭文件中的#include"color.h"去掉;

3、在類CMyLParam的定義和函數說明中進行如下修改:

源代碼:

ITEM_COLOR  *m_pBackColor;
  ITEM_COLOR  *m_pTextColor; 
  
  m_pBackColor=new ITEM_COLOR[column_count];
  m_pTextColor=new ITEM_COLOR[column_count];
  BOOL SetBackColor(ITEM_COLOR color, int iSub)
  {
    if (iSub<m_column_count) {
       m_pBackColor[iSub] = color;
       return TRUE;
    } else return FALSE;
  }
  BOOL SetTextColor(ITEM_COLOR color, int iSub)
  {
     if (iSub<m_column_count) {
       m_pTextColor[iSub] = color;
       return TRUE;
     } else return FALSE; }
  COLORREF GetBackColor(int iSub)
  {
     if (iSub<m_column_count)
        return GetColorRef(m_pBackColor[iSub]);
     else
        return GetColorRef(DEF_BACKGROUND);}
  COLORREF GetTextColor(int iSub)
  {
     if (iSub<m_column_count)
        return GetColorRef(m_pTextColor[iSub]);
     else
        return GetColorRef(DEF_TEXT);
  }    

修改後的代碼:

COLORREF  *m_pBackColor;
  COLORREF  *m_pTextColor;
  
  m_pBackColor=new COLORREF[column_count];
  m_pTextColor=new COLORREF[column_count]; 
  BOOL SetBackColor(COLORREF color, int iSub) {
    if (iSub<m_column_count) {
      m_pBackColor[iSub] = color;
      return TRUE;
    } else return FALSE; }
  BOOL SetTextColor(COLORREF color, int iSub)
  {
    if (iSub<m_column_count) {
      m_pTextColor[iSub] = color;
      return TRUE;
    } else return FALSE; }
  COLORREF GetBackColor(int iSub)
  {
      if (iSub<m_column_count)
         return m_pBackColor[iSub];
      else
         return ::GetSysColor(COLOR_WINDOW);}
  COLORREF GetTextColor(int iSub)
  {
    if (iSub<m_column_count)
       return m_pTextColor[iSub];
    else
       return ::GetSysColor(COLOR_WINDOWTEXT);}

4、在類CColorListCtrl的定義和函數說明中進行如下修改: 源代碼:

BOOL SetItemTextColor(ITEM_COLOR color, int Index, int iSub);
  BOOL SetItemBackgndColor(ITEM_COLOR color, int Index, int iSub);
  BOOL CColorListCtrl::SetItemBackgndColor(ITEM_COLOR color, int Index, int iSub)  
  BOOL CColorListCtrl::SetItemTextColor(ITEM_COLOR color, int Index, int iSub)   

修改後的代碼:

BOOL SetItemTextColor(COLORREF color, int Index, int iSub);
  BOOL SetItemBackgndColor(COLORREF color, int Index, int iSub);
  BOOL CColorListCtrl::SetItemBackgndColor(COLORREF color, int Index, int iSub)
  BOOL CColorListCtrl::SetItemTextColor(COLORREF color, int Index, int iSub)   

刪除的源代碼:

// only for TEST
       if (ret_index<3)
       {
         p->SetBackColor(ITEM_COLOR(ret_index+BLUE),0);
         p->SetTextColor(ITEM_COLOR(ret_index+RED ),0);
       }
       else
       if (ret_index<=6)
       {
         p->SetBackColor(ITEM_COLOR(ret_index+BLUE),1);
         p->SetTextColor(ITEM_COLOR(ret_index+RED ),1);
       }
       else
       {
         p->SetBackColor(ITEM_COLOR((ret_index+BLUE)&0xF),2);
         p->SetTextColor(ITEM_COLOR((ret_index+RED )&0xF),2);
       }
       // end: only for TEST
 

5、替換如下所示的代碼:

DEF_BACKGROUND替換成::GetSysColor(COLOR_WINDOW);
  DEF_TEXT替換成::GetSysColor(COLOR_WINDOWTEXT);
  GetColorRef(DEF_DESELTEXT)替換成::GetSysColor(COLOR_HIGHLIGHTTEXT);
  GetColorRef(DEF_SELBACKGROUND)替換成::GetSysColor(COLOR_ACTIVECAPTION);
  GetColorRef(DEF_SELTEXT)替換成::GetSysColor(COLOR_HIGHLIGHTTEXT);
  GetColorRef(DEF_DESELBACKGROUND)替換成::GetSysColor(COLOR_INACTIVECAPTION);
  pDC->SetTextColor(pMyLParam->GetTextColor(DEF_DESELTEXT))替換成pDC->SetTextColor(pMyLParam->GetTextColor(5)); 

修改後的示例程序如下圖所示,基本功能與原來的程序一樣。

本來我還計劃把對CListCtrl類的排序功能加入其中,可是到實現的時候才發現異常復雜,因為在CListCtrl控件的“More Style”屬性中已選中“Owner draw fixed”選項,對CListCtrl控件顏色的修改實際上是通過自畫來實現的,導致了CListCtrl控件某些函數的不可使用,例如InsertItem()等等,我嘗試做了一下排序,總是會出現一些無法理解的錯誤,照我的理解只能把項全部存進列表中,然後對列表進行排序,再清空CListCtrl控件的所有項羅列出已排序的項。如果哪位高手有獨到的解決方法,請不吝指教!

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved