Click here to Skip to main content
11,413,961 members (76,648 online)
Click here to Skip to main content

Indicating an empty ListView

, 11 Jan 2000 CPOL
Rate this:
Please Sign up or sign in to vote.
Instead of presenting a blank screen if your list control is empty, why not try this?

Sample Image - EmptyLV.gif

When using a ListView it may be useful to inform the user that the control is empty, like Microsoft Outlook does. Doing this is pretty straightforward. Just derive your own ListView control from CListCtrl and add a WM_PAINT event handler to your derived class.

class CEmptyListCtrl : public CListCtrl
{
// Construction
public:

// Overrides
protected:
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CEmptyListCtrl)
	//}}AFX_VIRTUAL

// Implementation
public:

// Generated message map functions
protected:
	//{{AFX_MSG(CEmptyListCtrl)
	afx_msg void OnPaint();
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

Then, in OnPaint member function, implement the code necessary to handle the empty condition.

void CEmptyListCtrl::OnPaint() 
{
    Default();
    if (GetItemCount() <= 0)
    {
        COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);
        COLORREF clrTextBk = ::GetSysColor(COLOR_WINDOW);

        CDC* pDC = GetDC();
        // Save dc state
        int nSavedDC = pDC->SaveDC();

        CRect rc;
        GetWindowRect(&rc);
        ScreenToClient(&rc);

        CHeaderCtrl* pHC;
        pHC = GetHeaderCtrl();
        if (pHC != NULL)
        {
            CRect rcH;
            pHC->GetItemRect(0, &rcH);
            rc.top += rcH.bottom;
        }
        rc.top += 10;

        CString strText((LPCSTR)IDS_NOITEMS); // The message you want!

        pDC->SetTextColor(clrText);
        pDC->SetBkColor(clrTextBk);
        pDC->FillRect(rc, &CBrush(clrTextBk));
        pDC->SelectStockObject(ANSI_VAR_FONT);
        pDC->DrawText(strText, -1, rc, 
                      DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);

        // Restore dc
        pDC->RestoreDC(nSavedDC);
        ReleaseDC(pDC);
    }
    // Do not call CListCtrl::OnPaint() for painting messages
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

GHINI Mauro

Italy Italy
No Biography provided

Comments and Discussions

 
Generaluseful idea Pin
CIDev, 24-Sep-10 5:56
memberCIDev24-Sep-10 5:56 
GeneralA non MFC version Pin
ineox, 24-Mar-10 3:37
memberineox24-Mar-10 3:37 
GeneralError Pin
Adi Narayana, 22-May-06 22:30
memberAdi Narayana22-May-06 22:30 
GeneralBugs Pin
Tim L, 18-Nov-05 10:24
memberTim L18-Nov-05 10:24 
GeneralUsing the default listview font and colors Pin
javrillon, 23-Jul-04 7:38
memberjavrillon23-Jul-04 7:38 
Suggestion to draw the 'empty' message with default listview font and color:

Save the font and color in the prepaint stage of OnNMCustomdraw, and use those to draw the text in OnPaint.

It works, but I'm not 100% sure that the GDI objects saved during the prepaint stage will always be valid when used in OnPaint. Could someone tell me if I can safely assume they will?

// CMyListCtrl.h

class CMyListCtrl : public CListCtrl
{
public:
   CMyListCtrl();
private:
   HFONT m_hFont;
   HBRUSH m_hBrush;
   COLORREF m_crTextColor;
   COLORREF m_crBkColor;
protected:
   DECLARE_MESSAGE_MAP()
   afx_msg void OnNMCustomdraw(
      NMHDR *pNMHDR, LRESULT *pResult);
   afx_msg void OnPaint();
};

// CMyListCtrl.cpp

BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
   ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, OnNMCustomdraw)
   ON_WM_PAINT()
END_MESSAGE_MAP()

CMyListCtrl::CMyListCtrl()
   : m_hFont(NULL)
   , m_hBrush(NULL)
   , m_crTextColor(RGB(0,0,0))
   , m_crBkColor(RGB(0,0,0))
{
}

void CMyListCtrl::OnNMCustomdraw(
   NMHDR *pNMHDR, LRESULT *pResult)
{
   LPNMCUSTOMDRAW pNMCD = (LPNMCUSTOMDRAW)pNMHDR;
   switch (pNMCD->dwDrawStage)
   {
   case CDDS_PREPAINT:
      // Save font, brush, text and background color.
      m_hFont = (HFONT)GetCurrentObject(
         pNMCD->hdc, OBJ_FONT);
      m_hBrush = (HBRUSH)GetCurrentObject(
         pNMCD->hdc, OBJ_BRUSH);
      m_crTextColor = GetTextColor(pNMCD->hdc);
      m_crBkColor = GetBkColor(pNMCD->hdc);
      break;
   }
   *pResult = CDRF_DODEFAULT;
}

void CMyListCtrl::OnPaint()
{
   Default();
   if (GetItemCount() <= 0)
   {
      // Compute the rectangle for the text
      CRect rect; GetClientRect(rect);
      CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
      if (pHeaderCtrl)
      {
         CRect rectHeader;
         pHeaderCtrl->GetWindowRect(rectHeader);
         rect.top += rectHeader.Height();
      }
      // Add spacing
      DWORD dwItemSpacing =
         ListView_GetItemSpacing(m_hWnd, TRUE);
      rect.top += HIWORD(dwItemSpacing);

      // Draw text, use font and brush saved during
      // the PREPAINT custom draw stage, assuming
      // they are still valid GDI objects.
      ASSERT(m_hFont != NULL && m_hBrush != NULL);
      HDC hdc = ::GetDC(m_hWnd);
      int nSavedDC = ::SaveDC(hdc);
      SetTextColor(hdc, m_crTextColor);
      SetBkColor(hdc, m_crBkColor);
      SelectObject(hdc, m_hFont);
      FillRect(hdc, rect, m_hBrush);
      DrawText(hdc,
         _T("There are no items to show in this view."),
         -1, rect,
         DT_SINGLELINE|DT_CENTER|DT_TOP|DT_NOPREFIX);
      RestoreDC(hdc, nSavedDC);
      ::ReleaseDC(m_hWnd, hdc);
   }
}

QuestionHow to use in a DLL Pin
LordLiverpool, 22-May-03 4:37
memberLordLiverpool22-May-03 4:37 
Generallistview adding mutiple colored row selection Pin
Anonymous, 2-Apr-02 10:16
memberAnonymous2-Apr-02 10:16 
GeneralPerhaps a better way... Pin
David Fleming, 7-Mar-02 12:19
memberDavid Fleming7-Mar-02 12:19 
GeneralRe: Perhaps a better way... Pin
Atlantys, 19-Sep-02 7:46
memberAtlantys19-Sep-02 7:46 
GeneralRe: Perhaps a better way... Pin
Stlan, 7-Oct-03 4:27
memberStlan7-Oct-03 4:27 
GeneralRe: Perhaps a better way... Pin
David Fleming, 7-Oct-03 7:18
memberDavid Fleming7-Oct-03 7:18 
GeneralRe: Perhaps a better way... Pin
Stlan, 7-Oct-03 20:20
memberStlan7-Oct-03 20:20 
GeneralRe: Perhaps a better way... Pin
Ron Olson, 16-Jun-04 6:31
sussRon Olson16-Jun-04 6:31 
GeneralRe: Perhaps a better way... Pin
David Fleming, 16-Jun-04 7:13
memberDavid Fleming16-Jun-04 7:13 
GeneralRe: Perhaps a better way... Pin
Ron Olson, 16-Jun-04 17:02
memberRon Olson16-Jun-04 17:02 
Generaltoo complicated Pin
Anonymous, 2-Mar-02 3:22
memberAnonymous2-Mar-02 3:22 
GeneralRe: too complicated Pin
Martijn, 18-Sep-03 3:28
memberMartijn18-Sep-03 3:28 
GeneralI can't get this code to work Pin
DanYELL, 24-Aug-01 15:48
memberDanYELL24-Aug-01 15:48 
Generalgot it working for a ClistView Pin
X, 23-Oct-00 16:21
sussX23-Oct-00 16:21 
QuestionHow does control get painted when the row count > 0??? Pin
Caleb, 15-Aug-00 16:58
sussCaleb15-Aug-00 16:58 
AnswerFound better example at Codeguru Pin
Caleb, 15-Aug-00 18:41
sussCaleb15-Aug-00 18:41 
GeneralSuggestion for Call Back List Control Type Pin
Murugan N.V., 7-Jun-00 11:47
sussMurugan N.V.7-Jun-00 11:47 
GeneralDisabled ListCtrl Pin
Leo Davidson, 13-Jan-00 8:15
sussLeo Davidson13-Jan-00 8:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150427.2 | Last Updated 12 Jan 2000
Article Copyright 2000 by GHINI Mauro
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid