我从网上找到了这个在ctreectrl中加入透明背景图案的程序,加入程序后运行没有任何问题,我想把他用于clistctrl控件,把基类由ctreectrl换成clistctrl,其他未改,编译没有问题,运行时,有图标和文字的地方都显示正常,背景也能透明地显示出来,但没有图标和文字的地方却全部变黑了,背景图案不见了。不知道在onpait中,ctreectrl和clistctrl有什么不同,请高手指点?有问题的语句我已指出。为树控制设置背景图象 
 
树控制是一个不支持自绘的控件。这就为显示背景图像增加了一定的难度。但
无论如何,它是能够做到的,我们将讨论如何做。一个基本的方法是将树控制
绘制在一个内存设备上,并透明的覆盖在背景图像上,那么其结果将是背景图
像显示在控件服务区。当然,这些相关资料较少。 
树控制使用背景位图,一个好的用途是显示公司商标。还有我们必须保证使
用的位图不能影响我们的阅读。首先我们要求图像已被作为资源加入工程,我们可以使用256色的位图(16色
的应当也被支持)。如果加入的图像小于控件的面积,图像将平铺在控件服务
区。步骤1: 加入位图到资源
使用导入功能加入位图到资源编辑器。 
步骤2: 加入变量
protected:
CPalette m_pal;
CBitmap m_bitmap;
int m_cxBitmap, m_cyBitmap;步骤3: 加入设置背景图像的成员函数
我们加入了两个重载函数去设置背景图像,这两个函数应当是公共函数,第一函数参数为资源ID,第二个函数参数为资源名。 
这些函数能够被调用来改变一个已经被指定的位图。首先它们将删除GDI对象上已有的位图与调色板。然后它们加载位图,并将它们附加到CBitmap对象上。我们调用了全局函数::LoadImage()而没有调用CBitmap::LoadBitmap()。这样做的原因是我们需要访问位图的DIBSECTION,为什么要访问位图的DIBSECTION,这是因为我产需要创建一个与位图颜色相配的逻辑调色板。 如果你没有设置和使用这个逻辑调色板,那么图象看上去将非常DULL。同时为了将来使用我们也保存了位图的尺寸。如果位图是256色的或更少,我们将创建调色板。我们分配足够的空间保存位图颜色表并调用 ::GetDIBColorTable()函数从位图中获得它。我们分配的足够的内存去创建调色板并从位图颜色表中获得颜色调色板信息。调色板的版本应当是0x300。 BOOL CTreeCtrlX::SetBkImage(UINT nIDResource)
{
return SetBkImage( (LPCTSTR)nIDResource );
}BOOL CTreeCtrlX::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: 加入WM_PAINT消息响应函数
void CTreeCtrlX::OnPaint()
{
// Remove comments from next five lines if you don't need any
// specialization beyond adding a background image
// if( m_bitmap.m_hObject == NULL )
// {
// CTreeCtrl::OnPaint();
// return;
// } CPaintDC dc(this); CRect rcClip, rcClient;
dc.GetClipBox( &rcClip );
GetClientRect(&rcClient); // Create a compatible memory DC
CDC memDC;
memDC.CreateCompatibleDC( &dc ); // Select a compatible bitmap into the memory DC
CBitmap bitmap, bmpImage;
bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() );
memDC.SelectObject( &bitmap );
// First let the control do its default drawing.
CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); // Draw bitmap in the background if one has been set
if( m_bitmap.m_hObject != NULL )
{
// Now create a mask
CDC maskDC;
maskDC.CreateCompatibleDC(&dc);
CBitmap maskBitmap; // Create monochrome bitmap for the mask
maskBitmap.CreateBitmap( rcClient.Width(), rcClient.Height(),
1, 1, NULL );
maskDC.SelectObject( &maskBitmap );
memDC.SetBkColor( ::GetSysColor( COLOR_WINDOW ) ); // Create the mask from the memory DC
maskDC.BitBlt( 0, 0, rcClient.Width(), rcClient.Height(), &memDC,
rcClient.left, rcClient.top, SRCCOPY );
CDC tempDC;
tempDC.CreateCompatibleDC(&dc);
tempDC.SelectObject( &m_bitmap ); CDC imageDC;
CBitmap bmpImage;
imageDC.CreateCompatibleDC( &dc );
bmpImage.CreateCompatibleBitmap( &dc, rcClient.Width(),
rcClient.Height() );
imageDC.SelectObject( &bmpImage ); if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
{
dc.SelectPalette( &m_pal, FALSE );
dc.RealizePalette(); imageDC.SelectPalette( &m_pal, FALSE );
} // Get x and y offset
CRect rcRoot;
GetItemRect( GetRootItem(), rcRoot, FALSE );
rcRoot.left = -GetScrollPos( SB_HORZ ); // Draw bitmap in tiled manner to imageDC
for( int i = rcRoot.left; i < rcClient.right; i += m_cxBitmap )
for( int j = rcRoot.top; j < rcClient.bottom; j += m_cyBitmap )
imageDC.BitBlt( i, j, m_cxBitmap, m_cyBitmap, &tempDC,
0, 0, SRCCOPY ); // Set the background in memDC to black. Using SRCPAINT with
              //black and any other
// color results in the other color, thus making black the transparent color
memDC.SetBkColor(RGB(0,0,0));
memDC.SetTextColor(RGB(255,255,255));
memDC.BitBlt(rcClip.left, rcClip.top, rcClip.Width(),
                  rcClip.Height(), &maskDC, rcClip.left, rcClip.top, SRCAND); // Set the foreground to black. See comment above.
imageDC.SetBkColor(RGB(255,255,255)); // 问题在这三条语句上
imageDC.SetTextColor(RGB(0,0,0)); //
imageDC.BitBlt(rcClip.left, rcClip.top, rcClip.Width(),
                   rcClip.Height(), &maskDC, rcClip.left, rcClip.top, SRCAND); // // Combine the foreground with the background
imageDC.BitBlt(rcClip.left, rcClip.top, rcClip.Width(),
                   rcClip.Height(), memDC, rcClip.left, rcClip.top,SRCPAINT); // Draw the final image to the screen
dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(),
&imageDC, rcClip.left, rcClip.top, SRCCOPY );
}
else
{
dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(),
rcClip.Height(), &memDC,
rcClip.left, rcClip.top, SRCCOPY );
}
}步骤5: 处理滚动消息
void CTreeCtrlX::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( m_bitmap.m_hObject != NULL )
InvalidateRect(NULL);
CTreeCtrl::OnVScroll(nSBCode, nPos, pScrollBar);
}void CTreeCtrlX::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if( m_bitmap.m_hObject != NULL )
InvalidateRect(NULL);
CTreeCtrl::OnHScroll(nSBCode, nPos, pScrollBar);
}步骤6: 处理TVN_ITEMEXPANDING消息
void CTreeCtrlX::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; if( m_bitmap.m_hObject != NULL )
InvalidateRect(NULL); *pResult = 0;
}步骤7: 加入WM_ERASEBKGND响应函数
BOOL CTreeCtrlX::OnEraseBkgnd(CDC* pDC)
{
if( m_bitmap.m_hObject != NULL )
return TRUE;
return CTreeCtrl::OnEraseBkgnd(pDC);
}步骤8: 处理WM_QUERYNEWPALETTE & WM_PALETTECHANGED消息
BOOL CTreeCtrlX::OnQueryNewPalette()
{
CClientDC dc(th

解决方案 »

  1.   

    楼主是 猩猩我只是 猩今天太晚,明天试一试MARK
      

  2.   

    codeguru 上 Zafir Anjum 早就用 ownerdraw 的 方法解决了
    整理后的代码如下#if !defined(AFX_ODLISTCTRL_H__A16CA812_6254_4F10_9F43_CD53DF0316E1__INCLUDED_)
    #define AFX_ODLISTCTRL_H__A16CA812_6254_4F10_9F43_CD53DF0316E1__INCLUDED_#if _MSC_VER > 1000
    #pragma once
    #endif // _MSC_VER > 1000
    // ODListCtrl.h : header file
    ///////////////////////////////////////////////////////////////////////////////
    // CODListCtrl windowclass AFX_EXT_CLASS CODListCtrl : public CListCtrl
    {
    // Construction
    public:
    CODListCtrl();// Attributes
    public:// Operations
    public:// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CODListCtrl)
    protected:
    virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
    //}}AFX_VIRTUAL// Implementation
    public:
    virtual ~CODListCtrl();
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    void RepaintSelectedItems(); // Generated message map functions
    protected:
    //{{AFX_MSG(CODListCtrl)
    afx_msg void OnPaint();
    afx_msg void OnSetFocus(CWnd* pOldWnd);
    afx_msg void OnKillFocus(CWnd* pNewWnd);
    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    public:
    BOOL SetBkImage(LPCTSTR lpszResourceName);
    BOOL SetBkImage(UINT nIDResource);
    enum EHighlight {HIGHLIGHT_NORMAL, HIGHLIGHT_ALLCOLUMNS, HIGHLIGHT_ROW};
    int  m_nHighlight; // Indicate type of selection highlighting
    int m_nBack;
    CBitmap m_bitmap;
    int m_nBmpWidth, m_nBmpHeight;
    };///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}}
    // Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_ODLISTCTRL_H__A16CA812_6254_4F10_9F43_CD53DF0316E1__INCLUDED_)
      

  3.   

    // ODListCtrl.cpp : implementation file
    //#include "stdafx.h"
    #include "ODListCtrl.h"#ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif/////////////////////////////////////////////////////////////////////////////
    // CODListCtrlCODListCtrl::CODListCtrl()
    {
    m_nHighlight = HIGHLIGHT_NORMAL;
    m_nBack = 0;
    }CODListCtrl::~CODListCtrl()
    {
    }
    BEGIN_MESSAGE_MAP(CODListCtrl, CListCtrl)
    //{{AFX_MSG_MAP(CODListCtrl)
    ON_WM_PAINT()
    ON_WM_SETFOCUS()
    ON_WM_KILLFOCUS()
    ON_WM_ERASEBKGND()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////
    // CODListCtrl message handlersvoid CODListCtrl::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 rcWnd;
    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(&rcWnd);
    rcHighlight = rcBounds;
    rcHighlight.left = rcLabel.left;
    rcHighlight.right = rcWnd.right;
    break;
    default:
    rcHighlight = rcLabel;
    } // Draw bitmap in the background if one has been set
    if(m_nBack == 4 && m_bitmap.m_hObject != NULL )
    {
    CDC tempDC;
    tempDC.CreateCompatibleDC(pDC);
    tempDC.SelectObject( &m_bitmap ); CRect rcClient;
    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();

    CRect rcFirstItem;
    GetItemRect(0, rcFirstItem, LVIR_BOUNDS);
    for( int i = rcFirstItem.left; i < rcClient.right; i += m_nBmpWidth )
    for( int j = rcFirstItem.top; j < rcClient.bottom; j += m_nBmpHeight )
    pDC->BitBlt( i, j, m_nBmpWidth, m_nBmpHeight, &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
    switch(m_nBack){
    case 0:
    case 3:
    pDC->FillRect(rcHighlight, &CBrush(::GetSysColor(COLOR_WINDOW)));
    break;
    case 1:
    {
    CRect rcClient, rcRow = rcItem;
    GetClientRect(&rcClient);
    rcRow.right = rcClient.right; pDC->FillRect(rcRow, &CBrush(RGB(255,255,0)));
    }
    break;
    case 2:
    {
    CRect rcClient, rcRow = rcItem;
    GetClientRect(&rcClient);
    rcRow.right = rcClient.right; pDC->FillRect(rcRow, &CBrush(nItem%2 ? ::GetSysColor(COLOR_WINDOW) :
      RGB(255,255,0)));
    }
    break;
    } // Set clip region
    rcCol.right = rcCol.left + GetColumnWidth(0);
    CRgn rgn;
    rgn.CreateRectRgnIndirect(&rcCol);
    pDC->SelectClipRgn(&rgn);
    rgn.DeleteObject();
    if(m_nBack == 3){
    // Draw column background
    if( !bHighlight )
    pDC->FillRect(rcCol, &CBrush(RGB(255,255,0)));
    }
    // 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; if(m_nBack == 3){
    // Draw column background
    if( !bHighlight || ( bHighlight && m_nHighlight == HIGHLIGHT_NORMAL ) )
    if( (nColumn+1) % 2 )
    pDC->FillRect(rcCol, &CBrush(RGB(255,255,0)));
    }
    if(m_nBack == 4){
    // Draw the background if needed
    if( m_bitmap.m_hObject == NULL && m_nHighlight == HIGHLIGHT_NORMAL )
    pDC->FillRect(rcCol, &CBrush(::GetSysColor(COLOR_WINDOW)));
    } // Draw the background if needed
    // if( 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 );
    }
      

  4.   

    void CODListCtrl::RepaintSelectedItems()
    {
    CRect rcBounds, rcLabel; // Invalidate focused item so it can repaint 
    int nItem = GetNextItem(-1, LVNI_FOCUSED); if(nItem != -1)
    {
    GetItemRect(nItem, rcBounds, LVIR_BOUNDS);
    GetItemRect(nItem, rcLabel, LVIR_LABEL);
    rcBounds.left = rcLabel.left; InvalidateRect(rcBounds, FALSE);
    } // Invalidate selected items depending on LVS_SHOWSELALWAYS
    if(!(GetStyle() & LVS_SHOWSELALWAYS))
    {
    for(nItem = GetNextItem(-1, LVNI_SELECTED);
    nItem != -1; nItem = GetNextItem(nItem, LVNI_SELECTED))
    {
    GetItemRect(nItem, rcBounds, LVIR_BOUNDS);
    GetItemRect(nItem, rcLabel, LVIR_LABEL);
    rcBounds.left = rcLabel.left; InvalidateRect(rcBounds, FALSE);
    }
    } UpdateWindow();
    }
    void CODListCtrl::OnPaint() 
    {
    // in full row select mode, we need to extend the clipping region
    // so we can paint a selection all the way to the right
    if (m_nHighlight == HIGHLIGHT_ROW &&
    (GetStyle() & LVS_TYPEMASK) == LVS_REPORT )
    {
    CRect rcBounds;
    GetItemRect(0, rcBounds, LVIR_BOUNDS); CRect rcClient;
    GetClientRect(&rcClient);
    if(rcBounds.right < rcClient.right)
    {
    CPaintDC dc(this); CRect rcClip;
    dc.GetClipBox(rcClip); rcClip.left = min(rcBounds.right-1, rcClip.left);
    rcClip.right = rcClient.right; InvalidateRect(rcClip, FALSE);
    }
    } CListCtrl::OnPaint();
    }void CODListCtrl::OnSetFocus(CWnd* pOldWnd) 
    {
    CListCtrl::OnSetFocus(pOldWnd);

    // check if we are getting focus from label edit box
    if(pOldWnd!=NULL && pOldWnd->GetParent()==this)
    return; // repaint items that should change appearance
    if((GetStyle() & LVS_TYPEMASK)==LVS_REPORT)
    RepaintSelectedItems();
    }void CODListCtrl::OnKillFocus(CWnd* pNewWnd) 
    {
    CListCtrl::OnKillFocus(pNewWnd); // check if we are losing focus to label edit box
    if(pNewWnd != NULL && pNewWnd->GetParent() == this)
    return; // repaint items that should change appearance
    if((GetStyle() & LVS_TYPEMASK) == LVS_REPORT)
    RepaintSelectedItems();
    }BOOL  CODListCtrl::SetBkImage(UINT nIDResource)
    {
    return SetBkImage( (LPCTSTR)nIDResource );
    }BOOL CODListCtrl::SetBkImage(LPCTSTR lpszResourceName)
    {
    // If this is not the first call then Delete GDI objects
    if(m_bitmap.m_hObject != NULL) m_bitmap.DeleteObject();
    m_bitmap.LoadBitmap(lpszResourceName); BITMAP bm;
    m_bitmap.GetBitmap( &bm );
    m_nBmpWidth = bm.bmWidth;
    m_nBmpHeight = bm.bmHeight; Invalidate();
    return TRUE;
    }BOOL CODListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult) 
    {
    if(m_nBack == 4){
    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);
    }BOOL CODListCtrl::OnEraseBkgnd(CDC* pDC) 
    {
    if(m_nBack == 4 && m_bitmap.m_hObject != NULL )
    return TRUE;

    return CListCtrl::OnEraseBkgnd(pDC);
    }注意这是个用于演示的类,当 m_nBack 为 5 时 可显示透明背景图
    CODListCtrl m_lst3m_lst3.SetImageList(&m_imglst, LVSIL_SMALL);
    m_lst3.GetClientRect(&r);
    nWidth = r.Width() / 3;
    m_lst3.InsertColumn(0, "Col 1", LVCFMT_LEFT, nWidth);
    m_lst3.InsertColumn(1, "Col 2", LVCFMT_LEFT, nWidth);
    m_lst3.InsertColumn(2, "Col 3", LVCFMT_LEFT, nWidth);
    for(i = 0; i < 9; i++){
    CString str;
    str.Format("Item %d", i + 1);
    m_lst3.InsertItem(i, str, i % 8);
    str.Format("Sub %d1", i + 1);
    m_lst3.SetItemText(i, 1, str);
    str.Format("Sub %d2", i + 1);
    m_lst3.SetItemText(i, 2, str);
    }
    m_lst3.SetExtendedStyle(LVS_EX_FULLROWSELECT);
    m_lst3.SetBkImage(IDB_MISCLISTCTRL2_BITMAP1);
    m_lst3.m_nBack = 5;此外 CListCtrl::SetBkImage在xp common controls V6下也能显示背景图
      

  5.   

    to zwvista(球迷程序员) :
    谢谢你的程序,不知你的程序运行过没有?我试了一下,在ICON方式下是不行的.
    我很久以前,在这个坛子也问过相同的问题,有幸得到了MS专家的回答,他说clistctrl在ICON方式下的自画是无效的,在MASN上也有说.我现在已经找不到那个贴子了,手头上也没有MSDN,所以也找不到相关的说明.我刚才在程序中跟踪了一下,发现程序并没有执行void CODListCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct),这个你可以试一下,除了ICON方式以外的其他方式应该是可以的,但我没有试,因为我要的就是ICON方式.
      

  6.   

    http://www.vckbase.com/document/viewdoc.asp?id=355
      

  7.   

    to codeproject(快乐的小熊):
    我想要的不是ctreectrl而是clistctrl
      

  8.   

    我记得 ListCtrl 没有必要利用自绘吧?在 SetBkImage 后这样调用就可以了: SetBkColor(CLR_NONE);
    SetTextBkColor(CLR_NONE);
      

  9.   

    其中 SetTextBkColor 在文档中并没有说明允许 CLR_NONE 参数,但是我试验过是可以的。
      

  10.   

    现在上班正写代码,晚上回去测试一下就知道了。Mark。
      

  11.   

    To small_wei:
      你问的是哪个 MS专家,“有幸得到了MS专家的回答,他说clistctrl在ICON方式下的自画是无效的,在MASN上也有说.” 他要不就是水平太差,要不就是不想告诉你。
      我就做过在 ICON方式下面自己画 CListCtrl 的Item, 效果和 ACDSee 的图片预览窗口一样(你要的就这效果?),连文本都是自己画的。
      误人子弟!
      

  12.   

    to Happy197212(Wright):
    你是用NM_CUSTOMDRAW  还是用DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct),我用DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)来做,我跟踪了一下,发现程序的确没有进行DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)中.用NM_CUSTOMDRAW 我没有试过.你能不能给个例子呢,十分感谢.
      

  13.   

    用NM_CUSTOMDRAW ,你去www.codeprojec.com去找吧,例子很多。
       说实话,来这儿我是聊天的, 问问题我很少会在这儿。
      

  14.   

    我找到有关MS专家的回答了
    http://expert.csdn.net/Expert/topic/649/649062.xml?temp=.0342676
      

  15.   

    不要冒目相信所谓"专家"的话, 说实话他们也是从我们这样的人中招去的,水平高低不同。
        你好好到下面看看:http://www.codeproject.com/listctrl/
         你想把CListCtrl 做成什么样都行,这可是有代码的。多看几个, 你也是专家.
      

  16.   

    用NM_CUSTOMDRAW ,自己搞定了,明天结贴,感谢Happy197212(Wright) 的帮助
      

  17.   

    好象是没有强制更新的原因。在对clistctrl进行了任何操作后都应该强制刷新一次clistctrl