久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

MFC雙緩沖解決閃爍問題 (zhuanzai)

 看風景D人 2014-06-15

最近在寫一個圖像編輯軟件,,環(huán)境是MFC,,但是MFC的視圖刷新機制使得圖像閃爍得非常厲害(圖像縮放時尤其明顯),,在網上查了一些資料,最好的方法是用雙緩沖的方式顯示,,這里總結一下,。

  雙緩沖的原理可以這樣形象的理解:把電腦屏幕看作一塊黑板。首先我們在內存環(huán)境中建立一個“虛擬“的黑板,,然后在這塊黑板上繪制復雜的圖形,,等圖形全部繪制完畢的時候,再一次性的把內存中繪制好的圖形“拷貝”到另一塊黑板(屏幕)上,。采取這種方法可以提高繪圖速度,,極大的改善繪圖效果。 

主要實現(xiàn)代碼如下:

1 CDC MemDC; //首先定義一個內存顯示設備對象
2 CBitmap MemBitmap;//定義一個位圖對象 
3 MemDC.CreateCompatibleDC(NULL);  //創(chuàng)建兼容設備dc
4 MemBitmap.CreateCompatibleBitmap(pDC,W,H);  
5 CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); 
6 MemDC.FillSolidRect(0,0,W,H,RGB(255,255,255));//填充初始顏色
7 cimg.DrawToHDC(MemDC.GetSafeHdc(),CRect(0,0,W,H));//繪圖到內存顯示設備
8          
9 pDC->BitBlt(rect.left,rect.top,W,H,&MemDC,0,0,SRCCOPY); //繪圖到真實顯示設備 

  主要思路就是先創(chuàng)建一個虛擬dc和一張?zhí)摂M位圖,,用于將圖像輸出到虛擬設備上,,內容在虛擬設備揮好后再輸出到真實dc上顯示出來,這樣在要輸出的時候才輸出,,提高了繪圖效率,。在這種方式下,所有需要顯示的函數(shù)都可以先會在內存虛擬dc上,,虛擬dc可以作為一個全局的變量或者類的成員變量存在,,方便調用。

  另外還需重載背景刷新函數(shù)OnEraseBkgnd(view類的函數(shù)),,其的主要作用是刷新背景,,刷新次數(shù)頻繁了就出現(xiàn)了閃爍,因此在需要的時候調用這個函數(shù),,其他時候直接return ture即可,。

  其實基本思路還是暫停MFC自帶的刷新機制,控制圖像的刷新,,在你想要刷新的時候刷新即可,。

  另外有個參考資料如下,,不懂實際操作時候可以參考,。

  1 內存DC和內存位圖

 2 (一)實驗目的:
 3      學會使用內存DC解決重畫問題
 4 
 5 (二)實驗內容:
 6 
 7   當Windows系統(tǒng)需要重畫窗口時,會向窗口發(fā)送一條WM_PAINT消息,,應用程序需要在WM_PAINT消息響應函數(shù)(或View類中的OnDraw)中重畫整個窗口(即重新顯示窗口中的信息),。
 8   可以把所有繪圖的工作放到OnDraw、OnPaint等函數(shù)中作,,但這樣作可能會出現(xiàn)三個缺點:速度慢,、屏幕閃爍、不方便,。
 9   所以,,對于需要較復雜繪圖的程序,一般方法是在內存中保存窗口內容的一個拷貝(內存DC)來實現(xiàn)重畫。每次收到WM_PAINT消息時,,將內存DC的內容復制到屏幕上,。
10 
11 1、重建一個工程,,在View類的頭文件中向View類添加成員變量:指向內存DC的指針和指向內存位圖的指針
12     CDC* m_pMemDC;
13     CBitmap* m_pBitmap;
14 2,、在View類的構造函數(shù)中添加代碼創(chuàng)建CDC和CBitmap對象
15     m_pMemDC=new CDC();
16     m_pBitmap=new CBitmap();
17 3、在View類的析構函數(shù)中添加代碼銷毀CDC和CBitmap對象
18     delete m_pMemDC;
19     delete m_pBitmap;
20 4,、用Class Wizard為View類添加一個WM_CREATE消息處理函數(shù)OnCreate(LPCREATESTRUCT lpCreateStruct),,在處理函數(shù)中添加代碼創(chuàng)建內存DC和位圖
21     //得到屏幕尺寸
22     int maxX=GetSystemMetrics(SM_CXSCREEN);
23     int maxY=GetSystemMetrics(SM_CYSCREEN);
24     //創(chuàng)建內存DC和位圖
25     CDC* pDC=GetDC();
26     m_pMemDC->CreateCompatibleDC(pDC);
27     m_pBitmap->CreateCompatibleBitmap(pDC,maxX,maxY);
28     m_pMemDC->SelectObject(m_pBitmap);
29     ReleaseDC(pDC);
30     //初始化內存DC為全白
31     CBrush brush;
32     brush.CreateStockObject(WHITE_BRUSH);
33     CBrush* poldbrush=m_pMemDC->SelectObject(&brush);
34     m_pMemDC->PatBlt(0,0,maxX,maxY,PATCOPY);
35     m_pMemDC->SelectObject(poldbrush);
36 5、在OnDraw中添加重畫代碼
37     CRect rect;
38     GetClientRect(rect);
39     pDC->BitBlt(0,0,rect.Width(),rect.Height(),m_pMemDC,0,0,SRCCOPY);
40 6,、用Class Wizard為View類添加一個WM_LBUTTONDOWN消息處理函數(shù),,用于響應鼠標左鍵單擊消息。
41 7,、在該鼠標消息處理函數(shù)中,,添加繪圖代碼
42     m_pMemDC->TextOut(point.x,point.y,"Test");
43     Invalidate(FALSE);
44 8、編譯運行程序,,在鼠標左鍵點擊的地方都會顯示出“Test”,。最小化窗口,再恢復窗口,,可以發(fā)現(xiàn)前面顯示的“Test”仍然保留,。
45 
46 說明:
47   Invalidate函數(shù)刷新整個窗口,如果每次繪圖修改的區(qū)域較小,,可以使用InvalidateRect函數(shù)代替Invalidate函數(shù)以加快顯示速度,。例如鼠標消息處理函數(shù)中的繪圖代碼可以改為如下代碼:
48     CString str="Test";
49     CRect rect(point.x,point.y,point.x,point.y);
50     m_pMemDC->DrawText(str,&rect,DT_CALCRECT|DT_LEFT); //得到要繪制的文本在屏幕上的尺寸
51     m_pMemDC->DrawText(str,&rect,DT_LEFT);
52     InvalidateRect(rect,FALSE); //只刷新需要繪制文本的區(qū)域
53   如果繪圖次數(shù)很頻繁,位圖很大,,用這種方法可以明顯改善繪圖性能,。
54   Invalidate(TRUE)先清除DC再重畫,Invalidate(FALSE)直接在原圖上畫,,性能更好,,兩者可以視情況選用。

    本站是提供個人知識管理的網絡存儲空間,,所有內容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多