» » Empty ListView in Visual C++


Follow Us

Bytexis on Twitter Bytexis on Facebook Bytexis on YouTube Bytexis on Delicious Google+

Displaying an Empty ListView Message using pure WinAPI

When using a ListView control it may be useful to show the user that the control is empty, like some other applications.

Use the following code:

VOID MakeEmpty_ListView(HWND hWndListView)
{
    LONG OldListViewProc;

    // Remember old window procedure
    OldListViewProc = GetWindowLong(hWndListView, GWL_WNDPROC);
    SetWindowLong(hWndListView, GWL_USERDATA, OldListViewProc);

    // Perform the subclass
    OldListViewProc = SetWindowLong(hWndListView, GWL_WNDPROC, (LONG)Empty_ListViewProc);
}

and

//
//    Replacement window procedure for a ListView control
//
LRESULT CALLBACK Empty_ListViewProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // Get the previous window procedure so we can still call it
    LONG OldListViewProc = GetWindowLong(hWnd, GWL_USERDATA);

    switch(uMsg)
    {
        case WM_PAINT:
            {
                // If the listview is empty...
                if(ListView_GetItemCount(hWnd) <= 0)
                {
                    RECT rc = {0};
                    RECT rcHeader = {0};
                    PAINTSTRUCT ps = {0};

                    COLORREF clrText = GetSysColor(COLOR_WINDOWTEXT);
                    //COLORREF clrTextBk = GetSysColor(COLOR_WINDOW);

                    HDC hDC = BeginPaint(hWnd, &ps);
    
                    // Find the listview dimensions
                    GetClientRect(hWnd, &rc);
    
                    // Find the height of the header of the listview
                    HWND hHeader = ListView_GetHeader(hWnd);
                    if(hHeader != NULL)
                    {
                        Header_GetItemRect(hHeader, 0, &rcHeader);
                        rc.top += rcHeader.bottom;
                        rc.top += 20;
                    }
    
                    SetTextColor(hDC, clrText);
                    SetBkMode(hDC, TRANSPARENT);
                    //FillRect(hDC, &rc, (HBRUSH)clrTextBk);
                    SelectObject(hDC, (HFONT)GetStockObject(ANSI_VAR_FONT));

                    // Finally draw the text
                    DrawText(hDC, TEXT("Message here!"), -1, &rc, DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
              
                    EndPaint(hWnd, &ps);
                }
            }
            break;

        // I simply handle the messages that are sent when
        // a column is resized or the content of the listview is scrolled,
        // and then i tell windows to refresh the listview by using InvalidateRect()
        case WM_SIZE:
        case WM_HSCROLL:
        case WM_VSCROLL:
            {
                if (ListView_GetItemCount(hWnd) == 0)
                    InvalidateRect(hWnd, NULL, TRUE);
            }
            break;

        case WM_NOTIFY:
            {
                NMHDR *nmHeader = (NMHDR *)lParam;
                if ((nmHeader->code == HDN_ENDTRACKW || nmHeader->code == HDN_ENDTRACKA) && ListView_GetItemCount(hWnd) == 0)
                    InvalidateRect(hWnd, NULL, TRUE);
            }
            break;
    } // switch(uMsg)

    return CallWindowProc((WNDPROC)OldListViewProc, hWnd, uMsg, wParam, lParam);
}


Example


case WM_INITDIALOG:
                MakeEmpty_ListView(GetDlgItem(hWnd, IDC_LISTVIEW));

Share this: