tags:

views:

447

answers:

3

I have a Windows Template Library CListViewCtrl in report mode (so there is a header with 2 columns) with owner data set. This control displays search results. If no results are returned I want to display a message in the listbox area that indicates that there were no results. Is there an easy way to do this? Do you know of any existing controls/sample code (I couldn't find anything).

Otherwise, if I subclass the control to provide this functionality what would be a good approach?

+3  A: 

I ended up subclassing the control and handling OnPaint like this:

class MsgListViewCtrl : public CWindowImpl< MsgListViewCtrl, WTL::CListViewCtrl >
{
    std::wstring m_message;
public:
    MsgListViewCtrl(void) {}

    BEGIN_MSG_MAP(MsgListViewCtrl)
        MSG_WM_PAINT( OnPaint )
    END_MSG_MAP()

    void Attach( HWND hwnd )
    {
        SubclassWindow( hwnd );
    }

    void SetStatusMessage( const std::wstring& msg )
    {
        m_message = msg;
    }

    void OnPaint( HDC hDc )
    {
        SetMsgHandled( FALSE );
        if( GetItemCount() == 0 )
        {
            if( !m_message.empty() )
            {
                CRect cRect, hdrRect;
                GetClientRect( &cRect );
                this->GetHeader().GetClientRect( &hdrRect );
                cRect.top += hdrRect.Height() + 5;

                PAINTSTRUCT ps;
                SIZE size;
                WTL::CDCHandle handle = this->BeginPaint( &ps );
                handle.SelectFont( this->GetFont() );
                handle.GetTextExtent( m_message.c_str(), (int)m_message.length(), &size );
                cRect.bottom = cRect.top + size.cy;
                handle.DrawText( m_message.c_str(), -1, &cRect, DT_CENTER | DT_SINGLELINE | DT_VCENTER );
                this->EndPaint( &ps );
                SetMsgHandled( TRUE );
            }
        }
    }
};

After the search runs, if there are no results, I call SetStatusMessage and the message is displayed centered under the header. That's what I wanted. I'm kind of a newbie at subclassing controls so I'm not sure if this is the best solution.

Skrymsli
This would make a nice Code Project article.
Rob
A: 

Another idea is to have another control, with the same size and position as the list control, but hidden. Could be an edit control, static text, browser control, or what have you.

Then when you don't have any search results, you put the message in this control, and un-hide it. When the user does another search that returns results, you hide this control and show the results in the list view normally.

Ryan Ginstrom
+1  A: 

If you're on Vista or later, handle the LVN_GETEMPTYMARKUP notification. For pre-Vista, you'll need to paint the message yourself.

Michael Dunn
Cool, didn't know about this new notification. It's about time, but it doesn't help in this case since we are targetting Windows 5.
Skrymsli