天天看點

VB的Autoredraw、refresh等等功能分析彙總及“記憶體作圖”

vb的(圖檔框等控件的)autoredraw、refresh、cls等等屬性和方法,與(圖檔框等控件的)picture屬性、image屬性之間,以及與vb一般的圖形方法及api繪圖函數等等之間,存在比較複雜的關系。通過學習了各種資料和示範程式,基本上搞清楚了。結論如下所示(不涉及更深層的機制)。請大家指正。

首先,有三種相關的“圖形”概念:1.螢幕(窗體、圖檔框等等,甚至電腦桌面)上面顯示的圖形,也就是能夠看到的圖形,2.(圖檔框等控件的)image屬性裡面的圖形,3.(圖檔框等控件的)picture屬性裡面的圖形。這三種圖形彼此相關,各種指令對它們有不同的作用。

第二,螢幕(窗體、圖檔框等等,甚至電腦桌面)上顯示的所有内容(不含控件)(也就是上面所說的第1種“圖形”),按來源可以分為:backcolor底色、背景色,加載或指派的圖檔(也就是picture屬性),用circle、line等方法或api函數作的圖形。而作的圖形,根據(不同條件下)是否可以被cls、是否可以被refresh、能否導出到圖檔檔案等等,可以分為“臨時圖形”和“持久圖形”。從下到上,依次是底色、加載或指派的圖檔、作的圖形。

下面看各種操作對各種圖形的影響。

1.當(窗體、圖檔框等的)autoredraw=false時,使用各種方法或操作,所影響的對象和效果如下:

螢幕圖形 image屬性 picture屬性
circle方法,line方法, 顯示所作的圖形 不變 不變
Bitblt、TransparentBlt等api函數 顯示所作的圖形 不變 不變

cls方法

*遮擋或縮小螢幕然後再露出,與cls等效,但隻表現在被遮擋的那一部分。

用image屬性來代替螢幕圖形,也就是擦掉了螢幕上的“臨時圖形”。此時與refresh等效。 不變 不變

refresh方法

*運作中設定autoredraw從false改為true,與refresh等效?(效果不确定?)

用image屬性來代替螢幕圖形,也就是擦掉了螢幕上的“臨時圖形”。此時與cls等效。 不變 不變

2.當(窗體、圖檔框等的)autoredraw=true時,使用各種方法或操作,所影響的對象和效果如下:

螢幕圖形 image屬性 picture屬性

circle方法,

line方法,

顯示所作的圖形 和螢幕一樣 不變

Bitblt、TransparentBlt

等api函數

不變。

直到refresh才會把image屬性的圖形一次性顯示到螢幕上。

*或者用一下circle等方法,相當于refresh。

*或者,遮擋或縮小螢幕然後再露出,也與refresh等效,但隻表現在被遮擋的那一部分。

*或者,用一個語句調用一下image屬性,也與refresh等效。

記錄所作的圖形,不過看不見 不變
cls方法 清除所有circle等方法和api函數的作圖,隻保留底色和加載的圖檔。 和螢幕一樣。(可能有api作圖沒有顯示到螢幕的,也一起清除。) 不變
refresh方法 用image屬性來代替螢幕圖形,把image裡面(如有)api作圖都顯示出來。 不變 不變

3.還有些操作不受目前的autoredraw屬性影響,所影響的對象和效果如下:

螢幕圖形 image屬性 picture屬性
設定backcolor 更新backcolor,并清除所有circle、line方法或api函數等作的圖形,但如果有加載的圖檔,圖檔不會被清除(圖檔在backcolor上面)。 和螢幕一樣 不變

loadpicture("檔案名")

*用指派的方法,與此等效

清除所有circle、line方法或api函數等作的圖形,清除現有的圖檔,加載新圖檔,保留backcolor。 和螢幕一樣 等于這個加載或指派的圖檔

loadpicture()

删除圖檔

清除所有circle、line方法或api函數等作的圖形,清除現有的圖檔,保留backcolor。 和螢幕一樣 變為空

窗體加載等事件,也與refresh等效。

另外,用Savepicture分别導出picture屬性和image屬性到bmp檔案,可以看到,用image屬性導出的bmp圖檔大小和(圖檔框的)顯示區域大小一緻,而且包含“持久圖形”(其中api作圖的可能沒有顯示在螢幕上),也包含底色(圖形小于顯示區域的話可以看到底色)。而用picture屬性導出的bmp圖檔大小等于它加載或指派的圖檔大小,與顯示區域的大小無關,而且不包含各種作圖和底色。如果picture屬性為空(未加載、未指派,或已被删除),則Savepicture會出錯。

根據上面的了解,是以,若幹應用如下:

1.如果隻需要螢幕上顯示,那麼就設autoredraw=false,然後circle或者api等畫圖。用cls或refresh擦除,然後可以重新畫。

2.如果要作為“持久圖形”,用circle等作圖的話,先設true,然後作圖,然後設false。這樣cls就不能擦除。被覆寫後可以refresh再出現。

3.如果要作為“持久圖形”,用api等作圖的話,先設true,然後作圖,(階段性)完成後調用上面所說的refresh等方法顯示到螢幕上。全部完成之後再refresh,然後把autoredraw改為false以保護圖形。——在refresh之前,其實已經可以直接用image屬性和Savepicture方法輸出到檔案,但輸出語句也會“觸發”顯示到螢幕上。

4.要把“持久圖形”導出到檔案,用image屬性、Savepicture方法。(隻是螢幕上顯示的“臨時圖形”,是不能導出的,除非用截屏、抓圖。)

5.要清除所有作圖,但保留加載的圖檔,隻要重新設定backcolor(即使backcolor完全被圖檔擋住了,看不見)。或者把autoredraw設為true,然後cls。(如果把image屬性指派給picture屬性,它就變成圖檔了,不會被cls清除。)

6.要清除所有作圖,連同加載的圖檔一起删除,隻要加載一個空圖檔(沒有具體的圖檔參數),但背景色是不能删除的。

關于“記憶體作圖”:

用autoredraw和refresh組合,可以實作api作圖時實際上的緩沖效果,使得螢幕上不會(因為圖形在很短時間内變化大而)“閃爍”。這種機制其實相當于“記憶體畫圖”然後顯示,是以不必為了避免閃爍而建立記憶體裝置場景和記憶體位圖了。據說是VB獨有的?

繼續閱讀