程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 如何在樹型控件中使用背景位圖

如何在樹型控件中使用背景位圖

編輯:關於VC++

一、引言:

對於TREWVIEW控件的背景位圖的實現,目前介紹的文章比較少,有人雖然實現了,但是在點擊TREE時,背景閃動比較厲害。本人在參照別人代碼的基礎上,把它總結一下,同時解決了這個背景閃爍的問題。目前FLASHGET1.3版也實現了TREEVIEW的背景位圖。大家可以參照一下。

本文程序運行效果如下圖:

二、原理:

因為WINDOWS標准TREEVIEW控件不支持背景位圖,所以如果需要設置背景位圖就需要先讓其在內存CDC對象上對TREEVIEW缺省繪圖,然後在選擇背景位圖,與缺省位圖合成,即采用貼圖的方式,把標准的TREEVIEW窗口貼在底圖上。這個操作在內存中完成。

同時為了避免閃爍,必須重載OnItemexpanding和OnItemexpanded這兩個函數。SetRedraw函數主要保證其不要在子樹彈出時重畫,而是子樹已經擴展後重畫。

三、實現步驟:

3.1 加入成員函數

BOOL CMyTreeCtrl::SetBKImage(LPCTSTR LpszResource)
{
  if( m_bitmap.m_hObject != NULL )
    m_bitmap.DeleteObject();

  HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),
      LpszResource, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);
  if( hbmp == NULL )
    return FALSE;
  m_bitmap.Attach( hbmp );
  return TRUE;
}

3.2 為WM_PAINT加入消息句柄

void CMyTreeCtrl::OnPaint()
{
  CPaintDC dc(this);

  CRect rcclient;
  GetClientRect(&rcclient);
  CDC memdc;
  memdc.CreateCompatibleDC(&dc);
  CBitmap bitmap;
  bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
  memdc.SelectObject( &bitmap );
  CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);
  CDC maskdc;
  maskdc.CreateCompatibleDC(&dc);
  CBitmap maskbitmap;
  maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
  maskdc.SelectObject( &maskbitmap );
  maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc,
    rcclient.left, rcclient.top, SRCCOPY);
  CBrush brush;
  brush.CreatePatternBrush(&m_bitmap);
  dc.FillRect(rcclient, &brush);

  memdc.SetBkColor(RGB(0,0,0));
  memdc.SetTextColor(RGB(255,255,255));
  memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),
        &maskdc, rcclient.left, rcclient.top, SRCAND);
  dc.SetBkColor(RGB(255,255,255));
  dc.SetTextColor(RGB(0,0,0));
  dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),
       &maskdc, rcclient.left, rcclient.top, SRCAND);

  dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),
       &memdc, rcclient.left, rcclient.top,SRCPAINT);
  brush.DeleteObject();
}

3.3 處理tvn_itemexpanding

void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  SetRedraw(FALSE);
  *pResult = 0;
}

3.4 處理tvn_itemexpanded

void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
  NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  Invalidate();
  SetRedraw(TRUE);
  *pResult = 0;
}

3.5 加入WM_ERASEBKGND消息處理函數

既然我們在OnPaint()函數中處理位圖並返回TRUE以保證默認的窗口進程不擦除背景,加入這個消息句柄可以避免額外的對客戶區的刷新以減少閃爍。

BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC)
{
  return TRUE;
}

(完)

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved