我需要建一个ListBox来显示报警信息,一行一条报警信息。根据报警优先级的不同,用不同颜色显示各行。不知怎么做? 是用CListBox 或CListCtrl 的DrawItem()吗?难道需要我自己用label凑个ListBox吗?

解决方案 »

  1.   

    不是啊,
    DrawItem函数里面可以对DRAWITEMSTRUCT的hdc SetBKColor
      

  2.   

    下面是用模板封装的一个colored list view 的源代码,供参考:
    /////////////////////////////////////////////////////////////////////////////
    // CColoredListViewCtrl - A ListView control with individual item colourstemplate <class T, class TBase = CListViewCtrl, class TWinTraits = CControlWinTraits>
    class ATL_NO_VTABLE CColoredListViewImpl : 
       public CWindowImpl< T, TBase, TWinTraits >,
       public CCustomDraw< T >
    {
    public:
       DECLARE_WND_SUPERCLASS(NULL, TBase::GetWndClassName())   typedef struct LVCOLORPARAM {
          COLORREF clrText;
          COLORREF clrBackground;
          HFONT    hFont;
          LPARAM   lParam;
       };
       int m_nColumns;   // Operations   BOOL SubclassWindow(HWND hWnd)
       {
          ATLASSERT(m_hWnd==NULL);
          ATLASSERT(::IsWindow(hWnd));
    #ifdef _DEBUG
          // Check class
          TCHAR szBuffer[16];
          if( ::GetClassName(m_hWnd, szBuffer, sizeof(szBuffer)/sizeof(TCHAR)) ) {
             ATLASSERT(::lstrcmpi(szBuffer, TBase::GetWndClassName())==0);
          }
    #endif
          BOOL bRet = CWindowImpl< T, TBase, TWinTraits >::SubclassWindow(hWnd);
          if( bRet ) _Init();
          return bRet;
       }   int InsertItem(UINT nMask, int nItem, LPCTSTR lpszItem, UINT nState, UINT nStateMask, int nImage=-1, LPARAM lParam=0)
       {
          ATLASSERT(::IsWindow(m_hWnd));
          // You must have initialized columns before calling this!
          // And you are not allowed to add columns once the list is populated!
          CHeaderCtrl ctrlHeader = GetHeader();
          if( m_nColumns==0 ) m_nColumns = ctrlHeader.GetItemCount();
          ATLASSERT(m_nColumns > 0);
          ATLASSERT(ctrlHeader.GetItemCount()==m_nColumns);
          // Create a place-holder of property controls for each subitem...
          LVCOLORPARAM* pParams;
          ATLTRY( pParams = new LVCOLORPARAM[m_nColumns] );
          ATLASSERT(pParams);
          if( pParams==NULL ) return -1;
          ::FillMemory(pParams, sizeof(LVCOLORPARAM) * m_nColumns, -1);
          // Finally create the listview item itself...
          if( nItem==-1 ) nItem = GetItemCount();
          nMask |= LVIF_PARAM;
          pParams[0].lParam = lParam;
          return TBase::InsertItem(nMask, nItem, lpszItem, nState, nStateMask, nImage, (LPARAM) pParams);
       }
       int InsertItem(int nItem, LPCTSTR lpszItem, int nImage)
       {
          ATLASSERT(::IsWindow(m_hWnd));
          return InsertItem(LVIF_TEXT|LVIF_IMAGE, nItem, lpszItem, 0, 0, nImage, 0);
       }
       DWORD_PTR GetItemData(int nItem) const
       {
          ATLASSERT(::IsWindow(m_hWnd));
          LVITEM lvi = { 0 };
          lvi.iItem = nItem;
          lvi.mask = LVIF_PARAM;
          if( GetItem(&lvi)==-1 ) return 0;
          LVCOLORPARAM* pParams = (LVCOLORPARAM*) lvi.lParam;
          return (DWORD_PTR) pParams[0].lParam;
       }
       BOOL SetItemColors(int nItem, int nSubItem, COLORREF clrText, COLORREF clrBk)
       {
          ATLASSERT(::IsWindow(m_hWnd));
          LVITEM lvi = { 0 };
          lvi.iItem = nItem;
          lvi.mask = LVIF_PARAM;
          if( GetItem(&lvi)==-1 ) return FALSE;
          LVCOLORPARAM* pParams = (LVCOLORPARAM*) lvi.lParam;
          ATLASSERT(nSubItem>=0 && nSubItem<GetHeader().GetItemCount());
          pParams[ nSubItem ].clrText = clrText;
          pParams[ nSubItem ].clrBackground = clrBk;
          // Repaint
          RedrawItems(nItem, nItem);
          return TRUE;
       }   // Unsupported ListView methods   BOOL SetItemData(int nItem, DWORD_PTR dwData)
       {
          ATLASSERT(false); // not supported
          return FALSE;
       }
       int AddItem(int nItem, int nSubItem, LPCTSTR strItem, int nImageIndex = -1)
       {
          ATLASSERT(false); // not supported
          return -1;
       }   // Implementation   void _Init()
       {
          ATLASSERT(::IsWindow(m_hWnd));
          m_nColumns = 0;
       }   // Message map and handlers   BEGIN_MSG_MAP(CColoredListViewImpl)
          MESSAGE_HANDLER(WM_CREATE, OnCreate)
          REFLECTED_NOTIFY_CODE_HANDLER(LVN_DELETEITEM, OnDeleteItem)
          CHAIN_MSG_MAP_ALT( CCustomDraw< T >, 1 )
          // Because WTL 3.1 does not support subitem custom drawing.
          // Should be forward-compatible with new versions...
          REFLECTED_NOTIFY_CODE_HANDLER(NM_CUSTOMDRAW, OnNotifyCustomDraw)
          DEFAULT_REFLECTION_HANDLER()
       END_MSG_MAP()   LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
       {
          LRESULT lRes = DefWindowProc(uMsg, wParam, lParam);
          _Init();
          return lRes;
       }
       LRESULT OnDeleteItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
       {
          ATLASSERT(m_nColumns>0);
          LPNMLISTVIEW pnmlv = (LPNMLISTVIEW) pnmh;
          ATLASSERT(pnmlv->lParam);
          LVCOLORPARAM* pParams = reinterpret_cast<LVCOLORPARAM*>(pnmlv->lParam);
          delete [] pParams;
          return 0;
       }
       LRESULT OnNotifyCustomDraw(int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
       {
          T* pT = static_cast<T*>(this);
          pT->SetMsgHandled(FALSE);
          LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW) pnmh;
          DWORD dwRet = 0;
          switch( lpNMCustomDraw->dwDrawStage ) {
          case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
             dwRet = pT->OnSubItemPrePaint(idCtrl, lpNMCustomDraw);
             pT->SetMsgHandled(TRUE);
             return dwRet;
          }
          bHandled = FALSE;
          return dwRet;
       }   // Custom painting   DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
       {
          return CDRF_NOTIFYITEMDRAW;   // We need per-item notifications
       }
       DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW /*lpNMCustomDraw*/)
       {
          return CDRF_NOTIFYSUBITEMDRAW; // We need per-subitem notifications
       }
       DWORD OnSubItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
       {
          LPNMLVCUSTOMDRAW lpNMLVCD = (LPNMLVCUSTOMDRAW) lpNMCustomDraw;
          ATLASSERT(lpNMLVCD->nmcd.lItemlParam);
          LVCOLORPARAM* pParams = reinterpret_cast<LVCOLORPARAM*>(lpNMLVCD->nmcd.lItemlParam);     
          const LVCOLORPARAM& param = pParams[ lpNMLVCD->iSubItem ];
          if( param.clrText!=-1 ) lpNMLVCD->clrText = param.clrText;
          if( param.clrBackground!=-1 ) lpNMLVCD->clrTextBk = param.clrBackground;
          return CDRF_NEWFONT; // We changed the colors
       }
    };class CColoredListViewCtrl : public CColoredListViewImpl<CColoredListViewCtrl>
    {
    public:
       DECLARE_WND_SUPERCLASS(_T("WTL_ColoredListView"), GetWndClassName())  
    };