CListCtrl 是在 Windows Common Control  的 List-View 基础上的吧. List-View 有个消息可以设置背景图片: LVM_SETBKIMAGE. 这个消息牵涉到一个结构:typedef struct tagLVBKIMAGE
{
    ULONG ulFlags;
    HBITMAP hbm;
    LPTSTR pszImage;
    UINT cchImageMax;
    int xOffsetPercent;
    int yOffsetPercent;
} LVBKIMAGE, FAR *LPLVBKIMAGE;另外有个帮助宏:BOOL ListView_SetBkImage(
    HWND hwndLV,
    LPLVBKIMAGE plvbki;
);各位大侠, 谁能告诉我怎么设置背景图象? 谁给出满意的答案, 我马上给分, 只给一个!

解决方案 »

  1.   

    最好是能给出用 API 的方法 就是怎么使用 LVM_SETBKIMAGE 消息.
    这方面的关键在于, 怎么设置 LVBKIMAGE 结构, 此结构各成员含义如何?期盼回复!
      

  2.   

    to :
    回复人: rushing(勇敢的心) :
    -------------------------------------
    我就是费尽心思尝试去做了, MSDN 相关章节看了 N 遍, 却不得其要领. 兄台若知道, 还请指点一二, 谢谢
      

  3.   

    extern CListCtrl* pmyListCtrl;
    LVBKIMAGE bki;// If no background image is set for the list view control use
    // the Microsoft homepage image as the background image.
    if (pmyListCtrl->GetBkImage(&bki) && (bki.ulFlags == LVBKIF_SOURCE_NONE))
    {
       pmyListCtrl->SetBkImage(
       TEXT("http://www.microsoft.com/library/images/gifs/homepage/microsoft.gif"),
          TRUE);
    }
      

  4.   

    看看MSDN的例子,或者到www.microsoft.com去下载例子。
    要不这里:
    www.codeproject.com
    www.codeguru.com
      

  5.   

    See the sample below, just what u really want : http://codeguru.earthweb.com/listview/background_image.shtmlEnjoy!
      

  6.   

    用256位BMP图设置背景详细步骤,这个不和修改背景颜色一样
    1、建立控件时设置LVS_OWNERDRAWFIXED
    cs.style |=  LVS_OWNERDRAWFIXED;2、加入成员变量
    protected:
    CPalette m_pal;
    CBitmap m_bitmap;
    int m_cxBitmap, b_cyBitmap;3、加入两个成员函数
    BOOL CMyListCtrl::SetBkImage(UINT nIDResource)
    {
    return SetBkImage( (LPCTSTR)nIDResource );
    }BOOL CMyListCtrl::SetBkImage(LPCTSTR lpszResourceName)
    { // If this is not the first call then Delete GDI objects
    if( m_bitmap.m_hObject != NULL )
    m_bitmap.DeleteObject();
    if( m_pal.m_hObject != NULL )
    m_pal.DeleteObject();


    HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(), 
    lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION ); if( hBmp == NULL ) 
    return FALSE; m_bitmap.Attach( hBmp );
    BITMAP bm;
    m_bitmap.GetBitmap( &bm );
    m_cxBitmap = bm.bmWidth;
    m_cyBitmap = bm.bmHeight;
    // Create a logical palette for the bitmap
    DIBSECTION ds;
    BITMAPINFOHEADER &bmInfo = ds.dsBmih;
    m_bitmap.GetObject( sizeof(ds), &ds ); int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount; // Create a halftone palette if colors > 256. 
    CClientDC dc(NULL); // Desktop DC
    if( nColors > 256 )
    m_pal.CreateHalftonePalette( &dc );
    else
    {
    // Create the palette RGBQUAD *pRGB = new RGBQUAD[nColors];
    CDC memDC;
    memDC.CreateCompatibleDC(&dc); memDC.SelectObject( &m_bitmap );
    ::GetDIBColorTable( memDC, 0, nColors, pRGB ); UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
    LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300;
    pLP->palNumEntries = nColors; for( int i=0; i < nColors; i++)
    {
    pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
    pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
    pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
    pLP->palPalEntry[i].peFlags = 0;
    } m_pal.CreatePalette( pLP ); delete[] pLP;
    delete[] pRGB;
    }
    Invalidate(); return TRUE;
    }
    4、修改DrawItem
    void CMyListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rcItem(lpDrawItemStruct->rcItem);
    int nItem = lpDrawItemStruct->itemID;
    CImageList* pImageList; // Save dc state
    int nSavedDC = pDC->SaveDC();
    // Get item image and state info
    LV_ITEM lvi;
    lvi.mask = LVIF_IMAGE | LVIF_STATE;
    lvi.iItem = nItem;
    lvi.iSubItem = 0;
    lvi.stateMask = 0xFFFF; // get all state flags
    GetItem(&lvi); // Should the item be highlighted
    BOOL bHighlight = ((lvi.state & LVIS_DROPHILITED)
    || ( (lvi.state & LVIS_SELECTED)
    && ((GetFocus() == this)
    || (GetStyle() & LVS_SHOWSELALWAYS)
    )
    )
    );
    // Get rectangles for drawing
    CRect rcBounds, rcLabel, rcIcon;
    GetItemRect(nItem, rcBounds, LVIR_BOUNDS);
    GetItemRect(nItem, rcLabel, LVIR_LABEL);
    GetItemRect(nItem, rcIcon, LVIR_ICON);
    CRect rcCol( rcBounds ); 
    CString sLabel = GetItemText( nItem, 0 ); // Labels are offset by a certain amount  
    // This offset is related to the width of a space character
    int offset = pDC->GetTextExtent(_T(" "), 1 ).cx*2; CRect rcHighlight;
    CRect rcClient;
    int nExt;
    switch( m_nHighlight )
    {
    case 0: 
    nExt = pDC->GetOutputTextExtent(sLabel).cx + offset;
    rcHighlight = rcLabel;
    if( rcLabel.left + nExt < rcLabel.right )
    rcHighlight.right = rcLabel.left + nExt;
    break;
    case 1:
    rcHighlight = rcBounds;
    rcHighlight.left = rcLabel.left;
    break;
    case 2:
    GetClientRect(&rcClient);
    rcHighlight = rcBounds;
    rcHighlight.left = rcLabel.left;
    rcHighlight.right = rcClient.right;
    break;
    default:
    rcHighlight = rcLabel;
    } // Draw bitmap in the background if one has been set
    if( m_bitmap.m_hObject != NULL )
    {
    CDC tempDC;
    tempDC.CreateCompatibleDC(pDC);
    tempDC.SelectObject( &m_bitmap ); GetClientRect(&rcClient); CRgn rgnBitmap;
    CRect rcTmpBmp( rcItem );

    rcTmpBmp.right = rcClient.right; // We also need to check whether it is the last item
    // The update region has to be extended to the bottom if it is
    if( nItem == GetItemCount() - 1 )
    rcTmpBmp.bottom = rcClient.bottom; rgnBitmap.CreateRectRgnIndirect(&rcTmpBmp);
    pDC->SelectClipRgn(&rgnBitmap);
    rgnBitmap.DeleteObject();

    if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
    {
    pDC->SelectPalette( &m_pal, FALSE );
    pDC->RealizePalette();
    } CRect rcFirstItem;
    GetItemRect(0, rcFirstItem, LVIR_BOUNDS);
    for( int i = rcFirstItem.left; i < rcClient.right; i += m_cxBitmap )
    for( int j = rcFirstItem.top; j < rcClient.bottom; j += m_cyBitmap )
    pDC->BitBlt( i, j, m_cxBitmap, m_cyBitmap, &tempDC, 
    0, 0, SRCCOPY );
    } // Draw the background color
    if( bHighlight )
    {
    pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
    pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT)); pDC->FillRect(rcHighlight, &CBrush(::GetSysColor(COLOR_HIGHLIGHT)));
    }
    else if( m_bitmap.m_hObject == NULL )
    pDC->FillRect(rcHighlight, &CBrush(::GetSysColor(COLOR_WINDOW))); // Set clip region
    rcCol.right = rcCol.left + GetColumnWidth(0);
    CRgn rgn;
    rgn.CreateRectRgnIndirect(&rcCol);
    pDC->SelectClipRgn(&rgn);
    rgn.DeleteObject(); // Draw state icon
    if (lvi.state & LVIS_STATEIMAGEMASK)
    {
    int nImage = ((lvi.state & LVIS_STATEIMAGEMASK)>>12) - 1;
    pImageList = GetImageList(LVSIL_STATE);
    if (pImageList)
    {
    pImageList->Draw(pDC, nImage,
    CPoint(rcCol.left, rcCol.top), ILD_TRANSPARENT);
    }
    }

    // Draw normal and overlay icon
    pImageList = GetImageList(LVSIL_SMALL);
    if (pImageList)
    {
    UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
    pImageList->Draw(pDC, lvi.iImage, 
    CPoint(rcIcon.left, rcIcon.top),
    (bHighlight?ILD_BLEND50:0) | ILD_TRANSPARENT | nOvlImageMask );
    }

    // Draw item label - Column 0
    rcLabel.left += offset/2;
    rcLabel.right -= offset; pDC->DrawText(sLabel,-1,rcLabel,DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_NOCLIP 
    | DT_VCENTER | DT_END_ELLIPSIS);
    // Draw labels for remaining columns
    LV_COLUMN lvc;
    lvc.mask = LVCF_FMT | LVCF_WIDTH; if( m_nHighlight == 0 ) // Highlight only first column
    {
    pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
    pDC->SetBkColor(::GetSysColor(COLOR_WINDOW));
    }

    rcBounds.right = rcHighlight.right > rcBounds.right ? rcHighlight.right :
    rcBounds.right;
    rgn.CreateRectRgnIndirect(&rcBounds);
    pDC->SelectClipRgn(&rgn);
       
    for(int nColumn = 1; GetColumn(nColumn, &lvc); nColumn++)
    {
    rcCol.left = rcCol.right;
    rcCol.right += lvc.cx; // Draw the background if needed
    if( m_bitmap.m_hObject == NULL && m_nHighlight == HIGHLIGHT_NORMAL )
    pDC->FillRect(rcCol, &CBrush(::GetSysColor(COLOR_WINDOW))); sLabel = GetItemText(nItem, nColumn);
    if (sLabel.GetLength() == 0)
    continue;
    // Get the text justification
    UINT nJustify = DT_LEFT;
    switch(lvc.fmt & LVCFMT_JUSTIFYMASK)
    {
    case LVCFMT_RIGHT:
    nJustify = DT_RIGHT;
    break;
    case LVCFMT_CENTER:
    nJustify = DT_CENTER;
    break;
    default:
    break;
    } rcLabel = rcCol;
    rcLabel.left += offset;
    rcLabel.right -= offset; pDC->DrawText(sLabel, -1, rcLabel, nJustify | DT_SINGLELINE 
    | DT_NOPREFIX | DT_VCENTER | DT_END_ELLIPSIS);
    } // Draw focus rectangle if item has focus
    if (lvi.state & LVIS_FOCUSED && (GetFocus() == this))
    pDC->DrawFocusRect(rcHighlight);
    // Restore dc
    pDC->RestoreDC( nSavedDC );
    }
      

  7.   

    5、加入WM_ERASEBKGND
    BOOL CMyListCtrl::OnEraseBkgnd(CDC* pDC) 
    {
    if( m_bitmap.m_hObject != NULL )
    return TRUE;
    return CListCtrl::OnEraseBkgnd(pDC);
    }
    6、重载OnNotify()并且得到列的缩放
    BOOL CMyListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
    {
    HD_NOTIFY *pHDN = (HD_NOTIFY*)lParam; // This code is for using bitmap in the background
    // Invalidate the right side of the control when a column is resized
    if(pHDN->hdr.code == HDN_ITEMCHANGINGW || pHDN->hdr.code == HDN_ITEMCHANGINGA)
    {
    if( m_bitmap.m_hObject != NULL )
    {
    CRect rcClient;
    GetClientRect( &rcClient );
    DWORD dwPos = GetMessagePos();
    CPoint pt( LOWORD(dwPos), HIWORD(dwPos) );
    ScreenToClient( &pt );
    rcClient.left = pt.x;
    InvalidateRect( &rcClient );
    }
    }
    return CListCtrl::OnNotify(wParam, lParam, pResult);
    }
    7、WM_QUERYNEWPALETTE & WM_PALETTECHANGED
    BOOL CMyListCtrl::OnQueryNewPalette() 
    {
    CClientDC dc(this);
    if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
    {
    dc.SelectPalette( &m_pal, FALSE );
    BOOL result = dc.RealizePalette();
    if( result )
    Invalidate();
    return result;
    }

    return CListCtrl::OnQueryNewPalette();
    }void CMyListCtrl::OnPaletteChanged(CWnd* pFocusWnd) 
    {
    CListCtrl::OnPaletteChanged(pFocusWnd);

    if( pFocusWnd == this )
    return; OnQueryNewPalette();
    }
    8、
    void CListViewDlg::OnPaletteChanged(CWnd* pFocusWnd) 
    {
    CDialog::OnPaletteChanged(pFocusWnd);

    m_listctrl.SendMessage( WM_PALETTECHANGED, (WPARAM)pFocusWnd->m_hWnd );
    }BOOL CListViewDlg::OnQueryNewPalette() 
    {
    CDialog::OnQueryNewPalette(); return m_listctrl.SendMessage( WM_QUERYNEWPALETTE );
    }
      

  8.   

    回复人: Sustain(支点) ( ) 信誉:100  
    --------------------------------------
    兄台使用的是 MFC . 我没测试. 我更希望有 API 的, 不过我突然想到跟踪 MFC 源码.......跟踪之下, 发现也极简单, 用了一小段, 成了!呵呵, 给分. 回复人: rushing(勇敢的心) ( 
    --------------------------------
    看了一个源码, 挺不错的, 在基层没提供接口的情况下, 写自绘制代码以实现画背景. 还有兄台直接将代码贴了出来. 
    下面贴出我代码.
    listview  是已经创建成功 List-View 控件的句柄 LVBKIMAGE lv;
    ZeroMemory(&lv, sizeof(lv));
    lv.ulFlags = LVBKIF_SOURCE_URL | LVBKIF_STYLE_TILE;
    lv.pszImage = "C:\\wlp.jpg";
    lv.xOffsetPercent = 0;
    lv.yOffsetPercent = 0; ListView_SetBkImage(listview,  &lv);