GDI对象和CDC的使用方法(防止资源泄漏)
1:CDC方面:
???????CDC有三種使用方式
???????一種是獲得,包括GETDC和GETWINDOWDC,這種CDC是引用,使用完了一定要ReleaseDC,不釋放就會這個引用過來的CDC資源泄漏,千萬不能用DeleteDC,會導(dǎo)致報錯或程序崩潰。
???????還有一種就是創(chuàng)建,一般是CreateDC,CreateCompatibleDC等,這是創(chuàng)建一個新的DC,使用完了要DeleteDC,如果是NEW的還需要DELETE。如果不是指針,而是一個CDC對象(CDC?_dc;),那在使用后也可以不DeleteDC,因為CDC對象的析構(gòu)函數(shù)會調(diào)用DeleteDC。
??????最后一種是臨時的CDC對象,(CDC* pDC?=?CDC::FromHandle(lpDrawItemStruct->hDC);),這種CDC在我們重載控件的DrawItem函數(shù)中經(jīng)常用到,這類CDC是由系統(tǒng)在空閑時自動釋放(沒有測試過是否可以手動釋放,有興趣的朋友可以自己試試)。
2:下面說下GDI對象
??????我的帖子舉例的情況是不會造成內(nèi)存泄漏的,SelectObject返回的指針是一個臨時對象的指針,這個指針是保存在系統(tǒng)的一個MAP里的,對于MAP里的不使用的對象,系統(tǒng)會在空閑時自動釋放。
那個例子的結(jié)果就是,把新的圖片放到了那個CDC里面,CDC里面的默認(rèn)或是原來的圖片被替換刪除了,再想用的時候就沒有了。舉例
1
2
3
4
pDC->TextOut("11");
pDC->SelectObject(&cpen);
pDC->TextOut("22");
???????cpen一個粗線條的筆,正常的想法是11是系統(tǒng)默認(rèn)粗細的筆,22是粗線條,因為你沒有選回系統(tǒng)默認(rèn)的CPEN(?pDC->SelectObject(?pOldPen?);),當(dāng)你第二次執(zhí)行這段代碼的時候,11和22都是粗線條的,因為默認(rèn)的筆已經(jīng)被你改變了。
3:舉例一:
void?CMyView::OnPaint(?CDC*?pDC?)
??{
??CBitmap?bmp;
??CBitmap*?pOldBmp;
??bmp.LoadBitmap(IDB_MYBMP);
??pOldBmp?=?pDC->SelectObject(?&bmp?);
??…
??if(?Something()?){
??return;
??}
??pDC->SelectObject(?pOldBmp?);
??return;
??}
??????此段代碼最大的問題就是在第一個return語句,如果在這種情況下,就執(zhí)行選回原來的畫刷,導(dǎo)致資源不釋放,
4:舉例二:
HBRUSH CCCIMSystemDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
?HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
?// TODO:??在此更改 DC 的任何屬性
?pDC->SetBkMode(TRANSPARENT);
HBRUSH B=CreateSolidBrush(RGB(204,204,255));
?
?return (HBRUSH)B;
?// TODO:??如果默認(rèn)的不是所需畫筆,則返回另一個畫筆
?return hbr;
}
???????此段代碼主要是修改對話框以及控件的背景顏色,但是長時間運行將會發(fā)現(xiàn)大量資源泄漏。原因是每次進入此函數(shù)都會創(chuàng)建新的HBRUSH B而此對象有作為此函數(shù)的返回,即資源不會得到釋放,
原文:https://blog.csdn.net/lixianjun913/article/details/9664163?
?
總結(jié)
以上是生活随笔為你收集整理的GDI对象和CDC的使用方法(防止资源泄漏)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何更好阅读源代码 .
- 下一篇: 视频解码优化