VC 雙快取技術 滾動條

2021-05-22 02:05:33 字數 4236 閱讀 3375

vc中的繪圖有個比較棘手的問題是閃爍,雙快取是解決此類問題的一種方法,但是在系統繪圖中,由於可能要載入滾動條,響應滑鼠拖動等事件,導致傳統的雙快取方法不一定適用,本文提出了一種解決方法能夠用統一的框架內實現滾動條,滑鼠圖型拖動,視口轉換以及雙快取繪圖.

關鍵字:雙快取,滾動條,滑鼠拖動,vc,視口轉換

炫麗的軟體效果能增強使用者體驗,用繪圖方法展示動人效果就成為了必不可少的乙個環節,vc提供了非常豐富的繪圖api函式庫,例如gdi+介面,但是用過這些介面函式的開發人員應該知道,有個非常頭疼的問題是閃爍.如何解決這個問題,雙快取是乙個非常好的辦法.

1.雙快取原理介紹

在vc中進行繪圖過程處理時,如果圖形重新整理很快,經常出現圖形閃爍的現象。利用先在記憶體繪製,然後拷貝到螢幕的辦法可以消除螢幕閃爍,具體的方法是先在記憶體中建立乙個與裝置相容的記憶體裝置上下文,也就是開闢一快記憶體區來作為顯示區域,然後在這個記憶體區進行繪製圖形。在繪製完成後利用bitblt函式把記憶體的圖形直接拷貝到螢幕上即可。

2.雙快取繪圖實現

前面簡單的介紹了vc下雙快取的原理,在實現這一環節,我們的主要工作是將上面的想法實現.當面我們所用到的mfc應用程式是基於對話方塊,所以**我們當前要放在onpaint函式裡.

void ctestscrolldlg::onpaint()

這裡面有一點要著重講一下.幾個變數的定義:

1.neclipserect這是個矩形框,crect型別,用於表示乙個橢圓的四個值

2.m_nhscrollpos是個int型別,用之於水平滾動條,表現當前x軸座標值.

3.m_nvscrollpos是個int型別,用之於垂直滾動條,表現當前的y軸座標值

在本程式中,由於繪圖的面積可能會比較大,我們採用了滾動條機制.下面列出來滾動條**.

void ctestscrolldlg::onhscroll(uint nsbcode, uint npos, cscrollbar* pscrollbar)  

setscrollinfo(sb_horz,&scrollinfo,sif_all);  

scrollwindow(10,0);  

break;  

case sb_lineright:  

scrollinfo.npos += 1;  

if (scrollinfo.npos>scrollinfo.nmax)     

setscrollinfo(sb_horz,&scrollinfo,sif_all);  

scrollwindow(-10,0);  

break;  

case sb_pageleft:  

scrollinfo.npos -= 5;  

if (scrollinfo.npos)   

setscrollinfo(sb_horz,&scrollinfo,sif_all);  

scrollwindow(10*5,0);  

break;  

case sb_pageright:  

scrollinfo.npos += 5;  

if (scrollinfo.npos>scrollinfo.nmax)     

setscrollinfo(sb_horz,&scrollinfo,sif_all);  

scrollwindow(-10*5,0);  

break;  

case sb_thumbposition:  

break;  

case sb_thumbtrack:  

scrollwindow((scrollinfo.npos-npos)*10,0);  

scrollinfo.npos = npos;  

setscrollinfo(sb_horz,&scrollinfo,sif_all);  

break;  

case sb_endscroll:  

break;  

}  m_nhscrollpos = scrollinfo.npos*10;

cdialog::onhscroll(nsbcode, npos, pscrollbar); }

void ctestscrolldlg::onvscroll(uint nsbcode, uint npos, cscrollbar* pscrollbar)  

setscrollinfo(sb_vert,&scrollinfo,sif_all);  

scrollwindow(0,10);  

break;  

case sb_linedown:  

scrollinfo.npos += 1;  

if (scrollinfo.npos>scrollinfo.nmax)     

setscrollinfo(sb_vert,&scrollinfo,sif_all);  

scrollwindow(0,-10);  

break;  

case sb_pageup:  

scrollinfo.npos -= 5;  

if (scrollinfo.npos)   

setscrollinfo(sb_vert,&scrollinfo,sif_all);  

scrollwindow(0,10*5);  

break;  

case sb_pagedown:  

scrollinfo.npos += 5;  

if (scrollinfo.npos>scrollinfo.nmax)     

setscrollinfo(sb_vert,&scrollinfo,sif_all);  

scrollwindow(0,-10*5);  

break;  

case sb_endscroll:  

// messagebox("sb_endscroll");  

break;  

case sb_thumbposition:  

// scrollwindow(0,(scrollinfo.npos-npos)*10);  

// scrollinfo.npos = npos;  

// setscrollinfo(sb_vert,&scrollinfo,sif_all);  

break;  

case sb_thumbtrack:  

scrollwindow(0,(scrollinfo.npos-npos)*10);  

scrollinfo.npos = npos;  

setscrollinfo(sb_vert,&scrollinfo,sif_all);  

break;   }

m_nvscrollpos = scrollinfo.npos*10;

cdialog::onvscroll(nsbcode, npos, pscrollbar); }

這段**通用性比較強,可以直接粘到應用程式中使用.但是只要注意,由於在我們的應用程式中執行到了視口切換的概念,這是本地座標系跟世界座標系之間的切換,前面提到了二個變數用來標記當前座標系的視口值.具體原理若不理解,請參考視口轉換的原理.

3.滑鼠拖動事件實現

前面的**執行出來的效果,是乙個對話方塊,然後在(0,0,200,200)的位置上出現乙個橢圓,下面的工作,是想通過滑鼠拖動這個橢圓,即實現滑鼠的智慧型拖動.下面我們在對話方塊中新增滑鼠拖動事件.

void ctestscrolldlg::onmousemove(uint nflags, cpoint point)

cdialog::onmousemove(nflags, point); }

這裡面有個變數m_norgpoint,是個類變數,用之於記錄上一次的座標值.

4.再閃爍問題解決

不過我們執行這個效果圖後,會發現又出現了閃爍,這個是什麼問題呢,我們不是已經新增了雙快取了嗎.

其實這個問題的產生的原因是因為我們在滑鼠拖動時,也進行了invalidate函式,而這個時候是不需要進行背景重繪,這個問題的解決是通過新增onerasebkgnd函式.

在當前對話方塊中通過新增函式嚮導裡,在filter裡選擇window.然後先中erasebkgnd事件.

bool ctestscrolldlg::onerasebkgnd(cdc* pdc)

再執行一下,就會發現閃爍不見了.

5.總結

雙快取繪圖的問題幾乎困擾過每乙個開發者,雖然參考網上資訊,能解決這一問題,但是在新增滑鼠事件,新增滾動條事件,如何通過視口切換的方法,顯示一張大圖,目前並沒有統一的解決辦法,在實際工作,在統一解決這個問題時,也花了一些功夫,在解決後,整理了一下思路,以供開發人員參考.

用vc 做滾動條控制項

首先用應用嚮導產生一名為scro 的基於對話方塊的應用,再利用對話方塊編輯器加入兩個一樣的水平滾動條,兩個滾動條的 id分別取 idc scr1 和idc scr2 結果如下圖,將其作為本文的示例。對話方塊編輯器雖然允許將滾動條控制項加進對話方塊中,而且,類嚮導允許加入資料成員,但要使這兩個水平滾動...

python橫向滾動條 控制滾動條

調過js指令碼控制 python 1.coding utf 8 2.from selenium import webdriver 3.import time 5.driver webdriver.firefox 6.driver.get 7.搜尋 8.driver.find element by i...

IE6雙滾動條處理

如果想要解決這個問題,你需要選擇乙個最適合自己的解決方案.方案 1 在css定義中貼上下面的 html 這會強制預設出現垂直滾動條,這樣一來,從某些理由上來講,便消去了ie對水平滾動條的需求.優點 完全解決了這個問題,允許你保持完整的xhtml doctype.缺點 即使不需要垂直滾動條的時候也強制...