在windows系列上做程式設計,gdi是乙個很重要的技術點,有很多程式在執行多次後出現異常,除了眾所周知的記憶體洩露以外,gdi資源洩露也是乙個很直接的原因.今天就把我自己在程式設計中總結的一些經驗給大家分享,歡迎高手補充.
1.create出來的gdi物件,一定要用deleteobject來釋放,釋放順序是先create的後釋放,後create的先釋放.
這裡的create指的是以它為開頭的gdi函式,比如,createdibitmap,createfont等等,最後都要呼叫deleteobject來釋放.
2.create出來的dc要用deletedc來釋放,get到的要用releasedc釋放.
3.確保釋放dc的時候dc中的各gdi物件都不是你自己建立的;確保個gdi物件在釋放的時候不被任何dc選中使用.
假如我們要使用gdi函式畫圖,正確的步驟應該如下:
a.建立乙個記憶體相容dc(createcompatibledc)
b.建立乙個記憶體相容bitmap(createcompatiblebitmap)
c.關聯建立的記憶體相容dc和bitmap(selectobject)
d.畫圖
e.bitblt到目的dc上
f.斷開記憶體相容dc和bitmap關聯(selectobject)
g.銷毀記憶體相容bitmap
h.銷毀記憶體相容dc
由於selectobject在選入乙個新的gdi物件的時候會返回乙個原來的gdi物件(假如成功的話),所以需要在步驟c的時候儲存返回值,在步驟f的時候當作入口引數使用.還有,步驟g和步驟h實際上順序可以隨意,因為他們兩個此刻已經沒有關係了,但是為了結構清晰,我建議按照"先create的後釋放,後create的先釋放"的原則進行.
關於步驟f,可能會有爭議,因為即使省略這一步,步驟g和步驟h看起來照樣可以返回乙個成功的值.但實際上可能並沒有執行成功,至少boundschecker會報告有錯,錯誤資訊大致是說,在釋放dc的時候還包含有非預設的gdi物件,在釋放gdi物件的時候又說這個gdi物件還被乙個dc在使用.所以,我建議保留步驟f.
4.關於98下使用createcompatiblebitmap
按照msdn的說法,建立出來的size不能超過16m.實際情況是這樣嗎?非也~!從我自己做的測試結果來看(win98se-sc),這個值在2044*2043和2044*2044之間,然而,後來在另外乙個98系統上這個值也不行,後來我乾脆把上限給成了2000*2000.很幸運,到現在還沒有出問題,但我不能保證這個數字就是正確的.還有一點,假如寬或高有乙個超過32768,哪怕另外乙個值是1,也會建立失敗,有興趣的可以自己做個測試.如果要想保證這個函式在98下永遠成功,可以試試下面的**:
float factor = 10.f;
while(!bitmap.createcompatiblebitmap(&dc ,nwidth*factor ,nheight*factor))
這樣至少可以保證寬和高是成比例的:)
5.關於在印表機上使用bitblt
有時候在記憶體相容dc裡面已經做好圖了,但在使用bitblt的時候卻會失敗.這個時候,首先確認建立的記憶體相容dc和bitmap是不是使用印表機的dc,如果確認無誤,還是執行bitblt失敗,那80%可能是記憶體相容bitmap太大了,請按如下方法再試試:
建立另外乙個記憶體相容dc2和乙個比較小的記憶體相容biimap2,大概是1000*1000吧,我是這樣用的:)然後把dc裡面的內容分成塊(1000*1000),把每一塊bitblt到dc2上面,再從dc2裡面bitblt到列印dc上.有人可能會有這樣的疑問:那為什麼不直接把dc裡面的內容分幾次bitblt到印表機上呢?有區別嗎?答案是肯定的,如果dc裡面的bitmap太大,哪怕你想bitblt乙個10*10的區域到印表機上都會失敗.
《完》
防止 gdi 洩露
gdi使用的幾個注意點 1 create出來的gdi物件,要用deleteobject釋放,create出來的dc,要用deletedc釋放,getdc得出的dc,用releasedc釋放。2 先create後delete,create1,create2,delete2,delete1的順序。3 畫...
GDI洩露心得
最近,剛剛開始做c 我主要負責頁面上的東西。做完後發現gdi洩露很嚴重。經過總結,主要是以下幾點地方要注意。1.getdc 出來的dc,一定要用releasedc 處理。2.hbitmap要用deleteobject 處理。前天對modifystyle為什麼會出現上述問題的原因查明。modifyst...
記憶體洩露問題
下面是乙個影象去霧的程式,主函式簡略如下,看一下下面的 有何問題。int main cvreleasecapture capture cvdestroywindow result return 0 大致說一下一些fast dahaze是乙個去霧類,負責影象處理,儲存等。程式看起來很簡單,主迴圈裡面做...