Click here to Skip to main content
15,887,676 members
Articles / Desktop Programming / MFC

Indicating an empty ListView

Rate me:
Please Sign up or sign in to vote.
3.94/5 (9 votes)
11 Jan 2000CPOL 161.3K   56   23
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)


Written By
Italy Italy
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
Generaluseful idea Pin
BillW3324-Sep-10 4:56
professionalBillW3324-Sep-10 4:56 
GeneralA non MFC version Pin
ineox24-Mar-10 2:37
ineox24-Mar-10 2:37 
GeneralError Pin
Adi Narayana22-May-06 21:30
Adi Narayana22-May-06 21:30 
GeneralBugs Pin
Tim L18-Nov-05 9:24
Tim L18-Nov-05 9:24 
GeneralUsing the default listview font and colors Pin
javrillon23-Jul-04 6:38
javrillon23-Jul-04 6:38 
QuestionHow to use in a DLL Pin
David Pritchard22-May-03 3:37
David Pritchard22-May-03 3:37 
Generallistview adding mutiple colored row selection Pin
2-Apr-02 9:16
suss2-Apr-02 9:16 
GeneralPerhaps a better way... Pin
David Fleming7-Mar-02 11:19
David Fleming7-Mar-02 11:19 
After looking over the comments from others and giving it some thought (as well as some fiddling with my own code), I think I have found a better way.

I think it is better to perform this sort of thing in response to a WM_ERASEBKGND message (rather than WM_PAINT).

Also, if you are using Callbacks, you have to account for that as one of the messages mentions.

Considering those things, here's my take on it:

Add a function to handle the WM_ERASEBKGND message as follows:

BOOL CCallbackListCtrl::OnEraseBkgnd(CDC* pDC)
{
	if(GetItemCount() <= 0)
	{
		int nSavedDC = pDC->SaveDC(); //save the current DC state

		//Set up variables
		COLORREF clrText = ::GetSysColor(COLOR_WINDOWTEXT);	//system text color
		COLORREF clrBack = ::GetSysColor(COLOR_WINDOW);		//system background color
		CRect rc;
		GetClientRect(&rc);	//get client area of the ListCtrl

		//If there is a header, we need to account for the space it occupies
		CHeaderCtrl* pHC = GetHeaderCtrl();
		if(pHC != NULL)
		{
			CRect rcH;
			pHC->GetItemRect(0, &rcH);
			rc.top += rcH.bottom;
		}

        //Here is the string we want to display (or you can use a StringTable entry
        CString strText = "There are no items to display.";

        //Now we actually display the text
        pDC->SetTextColor(clrText);	//set the text color
        pDC->SetBkColor(clrBack);	//set the background color
        pDC->FillRect(rc, &CBrush(clrBack));	//fill the client area rect
        pDC->SelectStockObject(ANSI_VAR_FONT);	//select a font
        pDC->DrawText(strText, -1, rc, 
                      DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP); //and draw the text

        // Restore dc
        pDC->RestoreDC(nSavedDC);
        ReleaseDC(pDC);
    }
    else
    {
	//If there are items in the ListCtrl, we need to call the base class function
	CListCtrl::OnEraseBkgnd(pDC);
    }
    return true;
}


That should do it. It works well for me (even when using Callbacks).
GeneralRe: Perhaps a better way... Pin
Atlantys19-Sep-02 6:46
Atlantys19-Sep-02 6:46 
GeneralRe: Perhaps a better way... Pin
Stlan7-Oct-03 3:27
Stlan7-Oct-03 3:27 
GeneralRe: Perhaps a better way... Pin
David Fleming7-Oct-03 6:18
David Fleming7-Oct-03 6:18 
GeneralRe: Perhaps a better way... Pin
Stlan7-Oct-03 19:20
Stlan7-Oct-03 19:20 
GeneralRe: Perhaps a better way... Pin
Ron Olson16-Jun-04 5:31
Ron Olson16-Jun-04 5:31 
GeneralRe: Perhaps a better way... Pin
David Fleming16-Jun-04 6:13
David Fleming16-Jun-04 6:13 
GeneralRe: Perhaps a better way... Pin
Ron Olson16-Jun-04 16:02
Ron Olson16-Jun-04 16:02 
Generaltoo complicated Pin
2-Mar-02 2:22
suss2-Mar-02 2:22 
GeneralRe: too complicated Pin
Martijn18-Sep-03 2:28
Martijn18-Sep-03 2:28 
GeneralI can't get this code to work Pin
DanYELL24-Aug-01 14:48
DanYELL24-Aug-01 14:48 
Generalgot it working for a ClistView Pin
x23-Oct-00 15:21
x23-Oct-00 15:21 
QuestionHow does control get painted when the row count > 0??? Pin
Caleb15-Aug-00 15:58
Caleb15-Aug-00 15:58 
AnswerFound better example at Codeguru Pin
Caleb15-Aug-00 17:41
Caleb15-Aug-00 17:41 
GeneralSuggestion for Call Back List Control Type Pin
asadsfsdf7-Jun-00 10:47
asadsfsdf7-Jun-00 10:47 
GeneralDisabled ListCtrl Pin
Leo Davidson13-Jan-00 7:15
Leo Davidson13-Jan-00 7:15 

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

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