Board index » cppbuilder » ListView Background Image

ListView Background Image

The following code courtesy of Damon Chandler adds a background image
to a ListView , which works fine if the ListView is placed directly on
a Form  .
(note * : there must be at least 1 item in the ListView for the image
to be drawn)

However if I place the ListView on a Panel or TabSheet the image fails
to be drawn. Anyone know why not ?

//in header
MESSAGE void __fastcall WMNotify(TMessage &Msg);
BEGIN_MESSAGE_MAP
    MESSAGE_HANDLER(WM_NOTIFY, TMessage, WMNotify)
END_MESSAGE_MAP(TForm)  

//in source
__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
    SNDMSG(ListView1->Handle, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);

Quote
}

//---------------------------------------------------------------------------
void __fastcall TileBlt(HDC HDestDC, int left, int top, int w, int h,
    HDC HSourceDC)
{
    for (int y = top; y < 1000; y = y + h)
        for (int x = left; x < 1000; x = x + w)
            ::BitBlt(HDestDC, x, y, w, h, HSourceDC, 0, 0, SRCCOPY);
Quote
}

//---------------------------------------------------------------------------
void __fastcall TForm1::WMNotify(TMessage &Msg)
{
    LPNMHDR lpnmh = reinterpret_cast<LPNMHDR>(Msg.LParam);
    if (lpnmh->hwndFrom == ListView1->Handle &&
        lpnmh->code == NM_CUSTOMDRAW)
    {
        LPNMLVCUSTOMDRAW lplvcd =
            reinterpret_cast<LPNMLVCUSTOMDRAW>(Msg.LParam);
        switch (lplvcd->nmcd.dwDrawStage)
        {
            case CDDS_PREPAINT:
            {
                RECT R;
                ListView_GetItemRect(ListView1->Handle, 0,
                                     &R, LVIR_BOUNDS);

                int w = Image1->Picture->Bitmap->Width;
                int h = Image1->Picture->Bitmap->Height;
                TileBlt(lplvcd->nmcd.hdc, R.left, R.top,
                        w, h, Image1->Canvas->Handle);
            }
        }
        Msg.Result = CDRF_DODEFAULT;
        return;
    }
    TForm::Dispatch(&Msg);

Quote
}

//---------------------------------------------------------------------------

Wayne Gill
wgw...@bigpond.com
wgw...@crosswinds.net
wgw...@crosswinds.net

 

Re:ListView Background Image


Because you're catching the message on the form level, that's why.  The
message is sent to the listview's parent, not the window itself.  Thus, if
the listview is on a Panel, you have to catch the message from inside the
panel, not the form.  Likewise, if the listview is on the form itself, then
the form is the parent andthe message is caught there.

You can subclass the listview's parent using it's WindowProc property:

TWndMethod OldWindowProc;

__fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
    OldWindowProc = ListView1->Parent->WindowProc;
    ListView1->Parent->WindowProc = MyWindowProc;
    SNDMSG(ListView1->Handle, LVM_SETTEXTBKCOLOR, 0, CLR_NONE);

Quote
}

void __fastcall TForm1::MyWindowProc(TMessage &Message)
{
    if(Message.Msg == WM_NOTIFY)
    {
        // your code here ...
    }
    OldWindowProc(Message);

Quote
}

Gambit

Wayne Gill <wgw...@crosswinds.net > wrote in message
news:t=9VO8nz1gE30njE+z+235dekPxf@4ax.com...

Quote
> However if I place the ListView on a Panel or TabSheet the image fails
> to be drawn. Anyone know why not ?

Re:ListView Background Image


Thanks Remy,
I thought it had something to do with that , I didn't have a clue what
to do about it though .

Cheers

Quote
>Because you're catching the message on the form level, that's why.  The
>message is sent to the listview's parent, not the window itself.  Thus, if
>the listview is on a Panel, you have to catch the message from inside the
>panel, not the form.  Likewise, if the listview is on the form itself, then
>the form is the parent andthe message is caught there.
>..........
>..........

Wayne Gill
wgw...@bigpond.com
wgw...@crosswinds.net
wgw...@crosswinds.net

Other Threads