函數(shù)功能:該函數(shù)創(chuàng)建與指定的設備環(huán)境相關的設備兼容的位圖。
函數(shù)原型:HBITMAP CreateCompatibleBitmap(HDC hdc,int nWidth,int nHeight);
參數(shù):
hdc: 設備環(huán)境句柄。
nWidth:指定位圖的寬度,單位為像素。
nHeight:指定位圖的高度,單位為像素。
返回值:如果函數(shù)執(zhí)行成功,那么返回值是位圖的句柄;如果函數(shù)執(zhí)行失敗,那么返回值為NULL。若想獲取更多錯誤信息,請調(diào)用GetLastError。
備注:由CreateCompatibleBitmap函數(shù)創(chuàng)建的位圖的顏色格式與由參數(shù)hdc標識的設備的顏色格式匹配。該位圖可以選入任意一個與原設備兼容的內(nèi)存設備環(huán)境中。由于內(nèi)存設備環(huán)境允許彩色和單色兩種位圖。因此當指定的設備環(huán)境是內(nèi)存設備環(huán)境時,由CreateCompatibleBitmap函數(shù)返回的位圖格式不一定相同。然而為非內(nèi)存設備環(huán)境創(chuàng)建的兼容位圖通常擁有相同的顏色格式,并且使用與指定的設備環(huán)境一樣的色彩調(diào)色板。
速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:1.0及以上版本;頭文件:wingdi.h;庫文件:gdi32.lib。
PS:需要與CreateCompatibleDC配合使用
物理HDC 設備底層會擁有顯存等資源,但是兼容DC并沒有給圖像像素提供內(nèi)存空間,因此兼容DC總是和BITMAP配合使用,這樣一來,兼容DC就利用BITMAP的圖像像素數(shù)據(jù)空間給自己提供類似于顯存的內(nèi)存空間.
這樣有很多好處,以來我們可以在加載圖片后,在圖片上利用DC的各種繪圖功能.請看如下示例:
兼容DC在建立之初,只有1*1像素的尺寸,SelectObject選擇bitmap以后才可以進行繪圖.
內(nèi)存DC的可見區(qū)域是簡單的區(qū)域,不像物理DC可見區(qū)域可能被其他窗口覆蓋而產(chǎn)生復雜的可見區(qū)域.由于DC的任何繪圖都需要考慮在可見區(qū)域內(nèi)繪圖,絕對不能超出可見區(qū)域的范圍.因此每個GDI繪圖輸出最終都需要和構成復雜可見區(qū)域的每一個巨型區(qū)域進行剪裁輸出,因此物理DC的繪圖效果會比兼容DC速度慢一些.這也就是我們經(jīng)常用兼容DC進行雙緩存輸出的一個原因
HDC hdc=GetDC(hwnd);
HDC memdc=CreateCompatibleDC(hdc);
RECT rc;
BITMAP bmp;
HBITMAP holdbmp,hbmp=LoadBitmap(hInstDVBRes,MAKEINTRESOURCE(IDB_CLOCK));//從資源加載位圖
holdbmp=(HBITMAP)SelectObject(memdc,hbmp);//這里把hbmp的位圖選擇到兼容DC memdc,之后這個兼容DC就擁有和
//hbmp同樣大小的繪圖區(qū)域,注意超出位圖返回的GDI輸出都是無效的.
GetObject(hbmp,sizeof(BITMAP),&bmp);//這里獲取位圖的大小信息,事實上也是兼容DC繪圖輸出的范圍
SetRect(&rc,0,0,bmp.bmWidth,bmp.bmHeight);
DrawText(memdc,"Center Line Text" -1,&rc,DT_VCENTER|DT_SINGLELINE|DT_CENTER);//在兼容DC中間位置輸出字符串
//這樣以來我們就相當于把hbmp這個位圖加上了文字標注,我們可以把這個增加了文字標注的位圖保存起來.一個簡單的圖像處理基本就OK了.
SelectObject(memdc,holdbmp);//復原兼容DC數(shù)據(jù).
DeleteDC(memdc);
***********************************************************
首先現(xiàn)象是這樣的:
我的程序突然有一天,一個Create出來的窗口畫不出東西,開了天窗!跟進去一看,是調(diào)用CBitmap::CreateBitmap失?。ǚ祷刂禐镕ALSE)。用GetLastError查到的原因是“ERROR_NOT_ENOUGH_MEMORY”。
很奇怪,這個view的代碼我并沒有動??!我試著改成CBitmap::CreateCompatibleBitmap,好了!算了,不管了,就這么著吧~
誰知,過了些時日,別的窗口又開天窗了!
這次我把CreateBitmap改成CreateCompatibleBitmap,也不是每次都成功,時不時的就會創(chuàng)建失??!
查msdn,關于CreateBitmap API有如下這一段話:
The CreateBitmap function can be used to create color bitmaps.
However, for performance reasons applications should use CreateBitmap to create monochrome bitmaps and CreateCompatibleBitmap to create color bitmaps.
Whenever a color bitmap returned from CreateBitmap is selected into a device context, the system checks that the bitmap matches the format of the device context it is being selected into.
Because CreateCompatibleBitmap takes a device context, it returns a bitmap that has the same format as the specified device context.
Thus, subsequent calls to SelectObject are faster with a color bitmap from CreateCompatibleBitmap than with a color bitmap returned from CreateBitmap.
這段話看著挺繞,說CreateCompatibleBitmap API比CreateBitmap API的效率更高一些。那么,我的問題之一是:
CBitmap的這兩個屬性,是否也如API一樣,CreateCompatibleBitmap比CreateBitmap的效率高??
我的問題之二:搜了一下,我的程序里,有二十多處地方(17個窗口)調(diào)用CreateBitmap,10處地方調(diào)用CreateCompatibleBitmap,且這些占用bitmap的窗口只在最后退出的時候才銷毀。有經(jīng)驗的同仁看看,調(diào)用的地方是不是太多了?如果都換成CreateCompatibleBitmap,資源占用情況是否會有所改觀?
——————————————————————————
在Create之前,都有類似如下的代碼:
if(NULL != m_pMemBitmap)
{
m_pMemBitmap->DeleteObject();
delete m_pMemBitmap;
}
m_pMemBitmap = new CBitmap;
BOOL b = m_pMemBitmap->CreateCompatibleBitmap(pDC,rcClient.Width(),rcClient.Height());
感覺沒有什么可泄漏的。
==================>
暈,真是這樣寫的話就泄露了,而且露的很厲害
if(NULL != m_pMemBitmap)
{
m_pMemBitmap->DeleteObject();
delete m_pMemBitmap;
m_pMemBitmap = NULL;//光delete, m_pMemBitmap 是不會為NULL的
}