日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

双缓冲法解决重绘和闪屏问题

發(fā)布時(shí)間:2025/3/20 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 双缓冲法解决重绘和闪屏问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

重繪導(dǎo)致原因:UpdateData、Invalidate、InvalidateRect和UpdateWindow函數(shù)。

1.?UpdateData重繪控件函數(shù)

?UpdateData(TRUE)——刷新控件的值到對(duì)應(yīng)的變量。(外部輸入值交給內(nèi)部變量)

?即:控件的值—>變量。 ?

UpdateData(FALSE) —— 拷貝變量值到控件顯示。(變量的最終運(yùn)算結(jié)果值交給外部輸出顯示)

?即:變量值—>控件顯示。?

2. Invalidate()

? ? ? 該函數(shù)的作用是使整個(gè)窗口客戶區(qū)無效。窗口的客戶區(qū)無效意味著需要重繪,例如,如果一個(gè)被其它窗口遮住的窗口變成了前臺(tái)窗口,那么原來被遮住的部分就是無效的,需要重繪。這時(shí)Windows會(huì)在應(yīng)用程序的消息隊(duì)列中放置WM_PAINT消息。MFC為窗口類提供了WM_PAINT的消息處理函數(shù)OnPaint,OnPaint負(fù)責(zé)重繪窗口。視圖類有一些例外,在視圖類的OnPaint函數(shù)中調(diào)用了OnDraw函數(shù),實(shí)際的重繪工作由OnDraw來完成。參數(shù)bErase為TRUE時(shí),重繪區(qū)域內(nèi)的背景將被擦除,否則,背景將保持不變。?

3. InvalidateRect

? ? 用InvalidateRect函數(shù)只重繪部分區(qū)域,而且不重繪背景(第二個(gè)參數(shù)用FALSE)就可以解決大部分的屏閃問題。

? ? 比如:CRect rect(10,47,10+120,47+70);
? ? InvalidateRect(rect,FALSE);

?4.?UpdateWindow函數(shù)
UpdateWindow( )的作用是使窗口立即重繪。調(diào)用Invalidate等函數(shù)后窗口不會(huì)立即重繪,這是由于WM_PAINT消息的優(yōu)先級(jí)很低,它需要等消息隊(duì)列中的其它消息發(fā)送完后才能被處理。調(diào)用UpdateWindow函數(shù)可使WM_PAINT被直接發(fā)送到目標(biāo)窗口,從而導(dǎo)致窗口立即重繪。注意:函數(shù)繞過應(yīng)用程序的消息隊(duì)列,直接發(fā)送WM_PAINT消息給指定窗口的窗口過程,如果更新區(qū)域?yàn)榭?#xff0c;則不發(fā)送消息。

?

解決方法:

? ? ? ?雙緩沖是一種基本的技術(shù)。我們知道,如果窗體在響應(yīng)WM_PAINT消息的時(shí)候要進(jìn)行復(fù)雜的圖形處理,那么窗體在重繪時(shí)由于過頻的刷新而引起閃爍現(xiàn)象。解決這一問題的有效方法就是雙緩沖技術(shù)。

? ? ? 因?yàn)榇绑w在刷新時(shí),總要有一個(gè)擦除原來圖象的過程,它利用背景色填充窗體繪圖區(qū),然后在調(diào)用新的繪圖代碼進(jìn)行重繪,這樣一擦一寫造成了圖象顏色的反差。當(dāng)WM_PAINT的響應(yīng)很頻繁的時(shí)候,這種反差也就越發(fā)明顯。于是我們就看到了閃爍現(xiàn)象。(

? ? ? ? ? ? ? ? ? ? ? 當(dāng)窗口由于任何原因需要重繪時(shí),
總是先用背景色將顯示區(qū)清除,然后才調(diào)用OnPaint,而背景色往往與繪圖內(nèi)容
反差很大,這樣在短時(shí)間內(nèi)背景色與顯示圖形的交替出現(xiàn),使得顯示窗口看起來
在閃。如果將背景刷設(shè)置成NULL,這樣無論怎樣重繪圖形都不會(huì)閃了。
當(dāng)然,這樣做會(huì)使得窗口的顯示亂成一團(tuán),因?yàn)橹乩L時(shí)沒有背景色對(duì)原來
繪制的圖形進(jìn)行清除,而又疊加上了新的圖形。) 我們會(huì)很自然的想到,避免背景色的填充是最直接的辦法。但是那樣的話,窗體上會(huì)變的一團(tuán)糟。因?yàn)槊看卫L制圖象的時(shí)候都沒有將原來的圖象清除,造成了圖象的殘留,于是窗體重繪時(shí),畫面往往會(huì)變的亂七八糟。所以單純的禁止背景重繪是不夠的。我們還要進(jìn)行重新繪圖,但要求速度很快,于是我們想到了使用BitBlt函數(shù)。它可以支持圖形塊的復(fù)制,速度很快。我們可以先在內(nèi)存中作圖,然后用此函數(shù)將做好的圖復(fù)制到前臺(tái),同時(shí)禁止背景刷新,這樣就消除了閃爍。以上也就是雙緩沖繪圖的基本的思路。

  BitBlt函數(shù)執(zhí)行顏色數(shù)據(jù)的位塊傳送,從指定的源設(shè)備描述表向給定的一個(gè)目的設(shè)備描述表傳送對(duì)應(yīng)于一個(gè)象素矩形的顏色數(shù)據(jù)。

BOOL BitBlt(HDC hdcDest,
  int nXDest,
  int nYDest,
  int nWidth,
  int nHeight,
  HDC hdcSrc,
  int nXSrc,
  int nYSrc,
  DWORD dwRop);

?

hdcDest:指向目標(biāo)設(shè)備環(huán)境的句柄。 nXDest:指定目標(biāo)矩形區(qū)域左上角的X軸邏輯坐標(biāo)。 nYDest:指定目標(biāo)矩形區(qū)域左上角的Y軸邏輯坐標(biāo)。 nWidth:指定源和目標(biāo)矩形區(qū)域的邏輯寬度。 nHeight:指定源和目標(biāo)矩形區(qū)域的邏輯高度。 hdcSrc:指向源設(shè)備環(huán)境的句柄。 nXSrc:指定源矩形區(qū)域左上角的X軸邏輯坐標(biāo)。 nYSrc:指定源矩形區(qū)域左上角的Y軸邏輯坐標(biāo)。 dwRop:指定光柵操作代碼。這些代碼將定義源矩形區(qū)域的顏色數(shù)據(jù),如何與目標(biāo)矩形區(qū)域的顏色數(shù)據(jù)組合以完成最后的顏色。 BLACKNESS:表示使用與物理調(diào)色板的索引0相關(guān)的色彩來填充目標(biāo)矩形區(qū)域,(對(duì)缺省的物理調(diào)色板而言,該顏色為黑色)。 DSTINVERT:表示使目標(biāo)矩形區(qū)域顏色取反。 MERGECOPY:表示使用布爾型的AND(與)操作符將源矩形區(qū)域的顏色與特定模式組合一起。 MERGEPAINT:通過使用布爾型的OR(或)操作符將反向的源矩形區(qū)域的顏色與目標(biāo)矩形區(qū)域的顏色合并。 NOTSRCCOPY:將源矩形區(qū)域顏色取反,于拷貝到目標(biāo)矩形區(qū)域。 NOTSRCERASE:使用布爾類型的OR(或)操作符組合源和目標(biāo)矩形區(qū)域的顏色值,然后將合成的顏色取反。 PATCOPY:將特定的模式拷貝到目標(biāo)位圖上。 PATPAINT:通過使用布爾OR(或)操作符將源矩形區(qū)域取反后的顏色值與特定模式的顏色合并。然后使用OR(或)操作符將該操作的結(jié)果與目標(biāo)矩形區(qū)域內(nèi)的顏色合并。 PATINVERT:通過使用XOR(異或)操作符將源和目標(biāo)矩形區(qū)域內(nèi)的顏色合并。 SRCAND:通過使用AND(與)操作符來將源和目標(biāo)矩形區(qū)域內(nèi)的顏色合并。 SRCCOPY:將源矩形區(qū)域直接拷貝到目標(biāo)矩形區(qū)域。 SRCERASE:通過使用AND(與)操作符將目標(biāo)矩形區(qū)域顏色取反后與源矩形區(qū)域的顏色值合并。 SRCINVERT:通過使用布爾型的XOR(異或)操作符將源和目標(biāo)矩形區(qū)域的顏色合并。 SRCPAINT:通過使用布爾型的OR(或)操作符將源和目標(biāo)矩形區(qū)域的顏色合并。 WHITENESS:使用與物理調(diào)色板中索引1有關(guān)的顏色填充目標(biāo)矩形區(qū)域。(對(duì)于缺省物理調(diào)色板來說,這個(gè)顏色就是白色)。

具體實(shí)現(xiàn):在窗口類中定義成員變量與成員函數(shù):

CBrush m_brush;CDC m_memDC;//畫在內(nèi)存上CBitmap m_Bmp;CWnd *m_pDrawWnd;void InitialDBB();void DrawOnMem(double *pdData, unsigned long DataLen);void DrawOnStaticArea(double *pdData, unsigned long DataLen);在該類的初始化函數(shù)中添加BOOL CdaexpDlg::OnInitDialog(){ 。。。。。。 m_brush.CreateSolidBrush(RGB(25,200,25));m_pDrawWnd=GetDlgItem(IDC_PICTURE);InitialDBB(); 。。。。。。 }在重繪函數(shù)中添加void CdaexpDlg::OnPaint() { 。。。 //已經(jīng)有圖像保存在緩沖區(qū)了PAINTSTRUCT ps;CRect rt;m_pDrawWnd->GetClientRect(&rt); CDC* pDC=m_pDrawWnd->BeginPaint(&ps);pDC->BitBlt(0, 0, rt.Width(), rt.Height(), &m_memDC, 0, 0, SRCCOPY); m_pDrawWnd->EndPaint(&ps);。。。 }/******************************************************************************************************初始化內(nèi)存和畫布 *******************************************************************************************************/void CdaexpDlg::InitialDBB() {CRect rt;m_pDrawWnd->GetClientRect(&rt);CDC* sDC = m_pDrawWnd->GetDC();// 為屏幕DC創(chuàng)建兼容的內(nèi)存DCif(!m_memDC.CreateCompatibleDC(sDC))//{ ::PostQuitMessage(0);} m_nHeight = rt.bottom - rt.top;m_nWidth = rt.right - rt.left;// 創(chuàng)建位圖,不能是m_memDC,否則無顏色m_Bmp.CreateCompatibleBitmap(sDC, rt.Width(), rt.Height());//m_memDC// 相當(dāng)于選擇畫布,m_pDrawWnd->::SelectObject(m_memDC.GetSafeHdc(), m_Bmp); m_pDrawWnd->ReleaseDC(sDC); }/******************************************************************************************************繪制輸出波形至內(nèi)存 *******************************************************************************************************/ void CdaexpDlg::DrawOnMem( ) {unsigned long i; //---------------------------------------------------//獲取繪圖區(qū)域CRect rect;m_pDrawWnd->GetClientRect(&rect);//----------------------------------------------------//將背景涂黑COLORREF crl = RGB(0,0,0);m_memDC.FillSolidRect(rect, crl); //----------------------------------------------------//設(shè)置畫筆為黑色CPen pen(PS_SOLID,1,RGB(25,200,25));m_memDC.SelectObject(&pen);// ======================================================// = 畫出波形m_memDC.MoveTo( , );m_memDC.LineTo( , );}/******************************************************************************************************將內(nèi)存內(nèi)的波形繪制到界面 *******************************************************************************************************/ void CdaexpDlg::DrawOnStaticArea( ) {CWnd* pWnd = GetDlgItem(IDC_PICTURE);//獲得靜態(tài)文本框的窗口對(duì)象CRect rect;pWnd->GetClientRect(&rect); CDC* pDC = pWnd->GetDC();DrawOnMem( );// 一次性的將內(nèi)存設(shè)備環(huán)境上繪制完畢的圖形"貼"到屏幕上pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_memDC, 0, 0, SRCCOPY);pWnd->ReleaseDC(pDC); }

  如何提高繪圖的效率
????電力系統(tǒng)的網(wǎng)絡(luò)圖形的CAD軟件,在一個(gè)窗口中往往要顯示成千上萬個(gè)電力元件,而每個(gè)元件又是由點(diǎn)、線、圓等基本圖形構(gòu)成。如果真要在一次重繪過程重畫這么多元件,可想而知這個(gè)過程是非常漫長(zhǎng)的。如果加上了圖形的瀏覽功能,鼠標(biāo)拖動(dòng)圖形滾動(dòng)時(shí)需要進(jìn)行大量的重繪,速度會(huì)慢得讓用戶將無法忍受。怎么辦?只有再研究研究MFC的繪圖過程了。
????實(shí)際上,在OnDraw(CDC?*pDC)中繪制的圖并不是所有都顯示了的,例如:你
在OnDraw中畫了兩個(gè)矩形,在一次重繪中雖然兩個(gè)矩形的繪制函數(shù)都有執(zhí)行,但是很有可能只有一個(gè)顯示了,這是因?yàn)镸FC本身為了提高重繪的效率設(shè)置了裁剪區(qū)。裁剪區(qū)的作用就是:只有在這個(gè)區(qū)內(nèi)的繪圖過程才會(huì)真正有效,在區(qū)外的是無效的,即使在區(qū)外執(zhí)行了繪圖函數(shù)也是不會(huì)顯示的。因?yàn)槎鄶?shù)情況下窗口重繪的產(chǎn)生大多是因?yàn)榇翱诓糠直徽趽趸蛘叽翱谟袧L動(dòng)發(fā)生,改變的區(qū)域并不是整個(gè)圖形而只有一小部分,這一部分需要改變的就是pDC中的裁剪區(qū)了。因?yàn)轱@示(往內(nèi)存或者顯存都叫顯示)比繪圖過程的計(jì)算要費(fèi)時(shí)得多,有了裁剪區(qū)后顯示的就只是應(yīng)該顯示的部分,大大提高了顯示效率。但是這個(gè)裁剪區(qū)是MFC設(shè)置的,它已經(jīng)為我們提高了顯示效率,在進(jìn)行復(fù)雜圖形的繪制時(shí)如何進(jìn)一步提高效率呢?那就只有去掉在裁剪區(qū)外的繪圖過程了。可以先用pDC->GetClipBox()得到裁剪區(qū),然后在繪圖時(shí)判斷你的圖形是否在這個(gè)區(qū)內(nèi),如果在就畫,不在就不畫。
如果你的繪圖過程不復(fù)雜,這樣做可能對(duì)你的繪圖效率不會(huì)有提高。

總結(jié)

以上是生活随笔為你收集整理的双缓冲法解决重绘和闪屏问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 2020av视频| 无码人妻aⅴ一区二区三区69岛 | 黄色网址链接 | 中文字幕在线免费观看 | 黄色大片一级片 | 这里只有精品在线播放 | 中文字幕第八页 | 亚洲欧美日韩在线一区二区 | 久久中文字幕无码 | 久久免费精品视频 | 日本xxxx裸体xxxx出水 | 91青青视频| 欧美日韩一区二区视频观看 | 婷婷综合另类小说色区 | 99毛片| 国产亚洲欧美日韩精品 | 色播在线 | 亚洲字幕av一区二区三区四区 | 少妇人妻偷人精品视频蜜桃 | 亚洲免费观看高清完整 | 黄av网| 尤物影院在线观看 | 亚洲一线二线在线观看 | 手机在线看片日韩 | 中文久久乱码一区二区 | 天堂网站| 嫩草影院懂你的 | 一区二区成人网 | 国产高清视频在线观看 | 狠狠爱亚洲 | 老司机福利av | 午夜蜜桃视频 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 精品无码久久久久久久久果冻 | 色屁屁www影院免费观看入口 | 国产一级片网址 | 天堂中文字幕在线观看 | 美女啪啪av | 日韩一区二区a片免费观看 伊人网综合在线 | 久久久久99精品国产片 | av官网在线观看 | 美女扒开腿让男生桶 | 久久久久久网站 | 操操操操操操操操操 | mm131美女大尺度私密照尤果 | 探花国产精品一区二区 | 午夜视频一区二区三区 | 亚洲黄色a| 国产5区| 午夜影院啊啊啊 | 97超在线 | 国产亚洲高清视频 | 青青草www| 欧美永久 | 少妇人妻偷人精品无码视频新浪 | 欧美日韩成人一区二区在线观看 | 亚洲av成人无码久久精品 | 亚洲一区二区日韩欧美 | 免费性视频 | 谁有免费黄色网址 | 欧美黑人性猛交xxxx | 日本动漫艳母 | 日日骑夜夜操 | 国产精品亚洲欧美在线播放 | 沈樵精品国产成av片 | www.日韩高清 | 婷婷在线播放 | 成人久久久精品乱码一区二区三区 | 黄色高清片 | 国产精品18久久久久久vr下载 | 卡一卡二视频 | a级片一区二区 | 午夜日韩在线观看 | 一级黄色短片 | 婷婷在线网 | 天堂av2021 | 最近最新mv字幕观看 | 菲律宾黄色片 | 欧美永久视频 | 亚洲精品在线视频免费观看 | 成人福利一区二区 | 国产黄色大片网站 | 国产睡熟迷奷系列精品视频 | 免费无码肉片在线观看 | 被警察猛c猛男男男 | 中国精品毛片 | 新中文字幕 | 色很久| 国产古装艳史毛片hd | 久久在现 | 六月丁香综合网 | 国产精品一卡二卡三卡 | 国产成人亚洲精品自产在线 | 青青青国产精品一区二区 | 亚洲中文无码久久 | 国产精品久久无码一三区 | 中文国语毛片高清视频 | 午夜精品一区二区三区免费视频 | 99国产精品无码 |