解決列表框更新資料的時候的閃爍問題(VC防止視窗及其控制項(如CListCtrl)閃爍的簡單方法(一組有用的宏) )

來源:互聯網
上載者:User
 VC防止視窗及其控制項(如CListCtrl)閃爍的簡單方法(一組有用的宏)         本文主要是通過網上一篇文章提供的解決辦法,整理了一組宏來實現防閃爍的。本文的重點是展示這個宏及其使用方法。 解決方案的原理請參考: http://www.cndes.cn/Designs/Program/200608052716.html

 針對上文中提到的 “有效進行搽除" 方法整理如下:
        原文作者的思路是複寫WM_ERASEBKGND訊息處理函數OnEraseBkgnd,
 只對空白地區使用指定背景色重繪。而對已經有控制項的地區,不做重繪,從而
 避免視窗及其控制項閃爍。

      上述方法確實有效,但在有很多控制項的情況下,計算一個視窗中需要擦除並重繪的”空白地區“
是一件很麻煩的事情。為了方便這種方法的實際應用,我寫了一組宏來完成”計算空白地區“的功能:
/***********************************************************************************************************/
/************************************************************************/
/* 宏功能: 介面重新整理時僅重新整理指定控制項以外的空白地區;可有效避免視窗閃爍
/* 使用於: WM_ERASEBKGND 訊息處理函數 OnEraseBkgnd();
/************************************************************************/
#define ERASE_BKGND_BEGIN /
    CRect bgRect;/
    GetWindowRect(&bgRect);/
    CRgn bgRgn;/
    bgRgn.CreateRectRgnIndirect(bgRect);
//#define ERASE_BKGND_BEGIN

// Marco parameter 'IDC' specifies the identifier of the control
#define ADD_NOERASE_CONTROL(IDC)/
{/
    CRect controlRect;/
    GetDlgItem(IDC)->GetWindowRect(&controlRect);/
    CRgn controlRgn;/
    controlRgn.CreateRectRgnIndirect(controlRect);/
    if(bgRgn.CombineRgn(&bgRgn, &controlRgn, RGN_XOR)==ERROR)/
        return false;/
}

// Marco parameter 'noEraseRect' specifies a screen coordinates based RECT,
// which needn't erase.
#define ADD_NOERASE_RECT(noEraseRect)/
{/
    CRgn noEraseRgn;/
    noEraseRgn.CreateRectRgnIndirect(noEraseRect);/
    if(bgRgn.CombineRgn(&bgRgn, &noEraseRgn, RGN_XOR)==ERROR)/
        return false;/
}

// Marco parameter 'pDC' is a kind of (CDC *) type.
// Marco parameter 'clBrushColor' specifies the color to brush the area.
#define ERASE_BKGND_END(pDC, clBrushColor)/
    CBrush brush;/
    brush.CreateSolidBrush(clBrushColor);/
    CPoint saveOrg = (pDC)->GetWindowOrg();/
    (pDC)->SetWindowOrg(bgRect.TopLeft());/
    (pDC)->FillRgn(&bgRgn, &brush);/
    (pDC)->SetWindowOrg(saveOrg);/
    brush.DeleteObject();/
//#define ERASE_BKGND_END
/***********************************************************************************************************/
說明:
1)宏 ERASE_BKGND_BEGIN  和   ERASE_BKGND_END(pDC, clBrushColor) 搭配使用。
2)宏 ADD_NOERASE_CONTROL(IDC)  和 ADD_NOERASE_RECT(noEraseRect) 根據需要放在上面兩個宏的中間,用來添加不需要重繪背景的地區(正是這些地區導致了閃爍),使用次數不限。其中參數noEraseRect是一個螢幕座標系的RECT類型或CRect類型。

使用舉例1:
在當前表單的類中重寫WM_ERASEBKGND訊息處理函數如下:
BOOL CMyWnd::OnEraseBkgnd(CDC* pDC)
{
    ERASE_BKGND_BEGIN;
    ADD_NOERASE_RGN(IDC_BUTTON2);
    ADD_NOERASE_RGN(IDC_BUTTON1);
    ADD_NOERASE_RGN(IDC_LIST_STAT);
    ERASE_BKGND_END(pDC, GetSysColor(COLOR_3DFACE));
    return false;
}
上面的IDC_BUTTON2,IDC_BUTTON1,IDC_LIST_STAT即表單上的控制項。
 你可以指定其他已存在的控制項。
 這樣,視窗在擦除背景時,將只對上述控制項以後的”空白地區“使用系統色重繪,有效避免了閃爍。

備忘:
    重載WM_ERASEBKGND訊息處理函數OnEraseBkgnd的方法,
     選擇View->ClassWizard->classinfo選項卡:message filter下拉框:
     選擇window,然後再選擇message maps選項卡,在messages下拉框應該可以找到
     wm_erasebkgnd.雙擊添加.

使用舉例2:防止CListCtrl在拉動視窗時閃爍。
/*
* No further full-erasing is required,
* to prevent screen flashing caused by background erase and view repaint.
* Only erase the blank area.
*/
BOOL CExListCtrl::OnEraseBkgnd(CDC* pDC)
{
//compute the holding-data-items area of this list control
CRect rect;
CPoint dataRgnTopLeftPoint;
CPoint dataRgnBottomRightPoint;
GetItemPosition(0 , &dataRgnTopLeftPoint);
GetItemPosition(GetItemCount() , &dataRgnBottomRightPoint);
if(!GetHeaderCtrl()->GetItemRect(GetHeaderCtrl()->GetItemCount()-1, rect))
return CListCtrl::OnEraseBkgnd(pDC);
dataRgnBottomRightPoint.x = rect.right;

rect.SetRect(dataRgnTopLeftPoint, (CPoint)(dataRgnBottomRightPoint - CPoint(2,2)));
ClientToScreen(dataRgnRect);

//compute and erase the blank area. Using the Marco.
ERASE_BKGND_BEGIN;
ADD_NOERASE_RECT(dataRgnRect);
ERASE_BKGND_END(pDC, GetBkColor());

return false;
}

說明:CListCtrl在拉動的時候,會前以背景色重刷背景,再在上面繪製有資料的Items,
      而沒有資料的地區則保持背景色。因此,如果在BOOL CExListCtrl::OnEraseBkgnd(CDC* pDC)
      函數中簡單的return false,那麼沒有資料的地區將顯示不正常。
          故舉例2中先計算出有資料的items的地區,這是不需要以背景重刷的地區。
      再使用本文的宏,就可以有效避免CListCtrl在拉動時候的閃爍。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.