?? dibprcs.cpp
字號:
// 如果調色板不為空,則將調色板選入設備上下文
if(hPalette != NULL) {
::SelectPalette(pDC->GetSafeHdc(), hPalette, TRUE);
}
// 設置顯示模式
pDC->SetStretchBltMode(COLORONCOLOR);
// 在設備的origin位置上畫出大小為size的圖象
::StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y,size.cx,size.cy,
0, 0, lpBMIH->biWidth, lpBMIH->biHeight,
lpImage, (LPBITMAPINFO) lpBMIH, DIB_RGB_COLORS, SRCCOPY);
// 返回
return TRUE;
}
/*************************************************************************
*
* \函數名稱:
* ConvertDDBToDIB()
*
* \輸入參數:
* HBITMAP hBitmap - 指向源數據的BITMAP句柄
* CDib* pDibDst - 指向轉換目標的CDib對象指針
*
* \返回值:
* BOOL - 如果操作成功,則返回TRUE
*
* \說明:
* 該函數將源BITMAP類pDibSrc中的數據拷貝到pDibDst中,并對相應的數據成員賦值
*
*************************************************************************
*/
BOOL ConvertDDBToDIB(HBITMAP hBitmap, CDib* pDibDest, HPALETTE hPal)
{
// 聲明一個BITMAP結構
BITMAP bm;
// 設備上下文
HDC hDC;
// 象素位數
WORD biBitCount;
// 調色板表項數
int nColorTableEntries;
// 如果hBitmap句柄無效,則返回
if(!hBitmap){
return FALSE;
}
// 填充圖象數據到bm中,其中最后一個參數表示接收這個指定的對象的指針
if(!GetObject(hBitmap,sizeof(BITMAP),(LPBYTE)&bm)){
return FALSE;
}
// 計算象素位數
biBitCount=bm.bmPlanes*bm.bmBitsPixel;
if(biBitCount<=1)
biBitCount=1;
else if(biBitCount<=4)
biBitCount=4;
else if(biBitCount<=8)
biBitCount=8;
else
biBitCount=24;
// 計算調色板的尺寸
// 如果biClrUsed為零,則用到的顏色數為2的biBitCount次方
switch(biBitCount) {
case 1:
nColorTableEntries = 2;
break;
case 4:
nColorTableEntries = 16;
break;
case 8:
nColorTableEntries = 256;
break;
case 16:
case 24:
case 32:
nColorTableEntries = 0;
break;
default:
ASSERT(FALSE);
}
ASSERT((nColorTableEntries >= 0) && (nColorTableEntries <= 256));
// 分配DIB信息頭和調色板的內存
LPBITMAPINFOHEADER lpBMIH = (LPBITMAPINFOHEADER) new char
[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * nColorTableEntries];
lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
lpBMIH->biWidth = bm.bmWidth;
lpBMIH->biHeight = bm.bmHeight;
lpBMIH->biPlanes = 1;
lpBMIH->biBitCount = biBitCount;
lpBMIH->biCompression = BI_RGB;
lpBMIH->biSizeImage = 0;
lpBMIH->biXPelsPerMeter = 0;
lpBMIH->biYPelsPerMeter = 0;
lpBMIH->biClrUsed = nColorTableEntries;
lpBMIH->biClrImportant = nColorTableEntries;
// 獲得設備上下文句柄
hDC=GetDC(NULL);
// select and realize our palette
// 如果沒有指定調色板,則從系統中獲得當前的系統調色板
if(hPal==NULL){
hPal = GetSystemPalette();
}
hPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
// 調用GetDIBits填充信息頭,并獲得圖象數據的尺寸。注意這里圖象數據指針為NULL
GetDIBits( hDC, hBitmap, 0, (UINT)lpBMIH->biHeight, NULL, (LPBITMAPINFO)lpBMIH, DIB_RGB_COLORS);
// 如果沒有正確的獲得圖象數據尺寸,則重新計算
if( lpBMIH->biSizeImage == 0 ){
lpBMIH->biSizeImage=(((bm.bmWidth*biBitCount) + 31) / 32 * 4)*bm.bmHeight;
}
// 分配存放圖象數據的內存
LPBYTE lpImage = (LPBYTE) new char[lpBMIH->biSizeImage];
// 調用GetDIBits加載圖象數據,注意這里給出了圖象數據指針
// 如果加載圖象數據不成功,則釋放已經分配的內存,并返回FALSE
if( GetDIBits( hDC, hBitmap, 0, (UINT)lpBMIH->biHeight, (LPBYTE)lpImage,
(LPBITMAPINFO)lpBMIH, DIB_RGB_COLORS) == 0 ){
//clean up and return NULL
delete []lpImage;
delete []lpBMIH;
SelectPalette( hDC, hPal, TRUE );
RealizePalette( hDC );
ReleaseDC( NULL, hDC );
return FALSE;
}
// 將指針保存在CDib對象的數據成員中
pDibDest->m_lpBMIH = lpBMIH;
pDibDest->m_lpImage = lpImage;
pDibDest->m_nBmihAlloc = pDibDest->m_nImageAlloc = pDibDest->crtAlloc;
// 刪除臨時變量
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return TRUE;
}
/*************************************************************************
*
* \函數名稱:
* CopyDIB()
*
* \輸入參數:
* CDib* pDibSrc - 指向源數據的CDib對象指針
* CDib* pDibDst - 指向拷貝目標的CDib對象指針
*
* \返回值:
* BOOL - 如果操作成功,則返回TRUE
*
* \說明:
* 該函數將源CDib類pDibSrc中的數據拷貝到pDibDst中,并對相應的數據成員賦值
*
*************************************************************************
*/
BOOL CopyDIB(CDib* pDibSrc, CDib* pDibDst)
{
// 將目的CDib對象清空
pDibDst->Empty();
// 計算信息頭加上調色板的大小,并分配相應的內存
int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * pDibSrc->m_nColorTableEntries;
pDibDst->m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSizeHdr];
pDibDst->m_nBmihAlloc = pDibDst->m_nImageAlloc = pDibDst->crtAlloc;
try{
// 拷貝信息頭和調色板
memcpy(pDibDst->m_lpBMIH,pDibSrc->m_lpBMIH,nSizeHdr);
// 如果結構的長度不對,則進行錯誤處理
if(pDibDst->m_lpBMIH->biSize != sizeof(BITMAPINFOHEADER)) {
TRACE("Not a valid Windows bitmap -- probably an OS/2 bitmap\n");
throw new CException;
}
// 保存圖象數據內存大小到CDib對象的數據成員中
pDibDst->m_dwSizeImage = pDibDst->m_lpBMIH->biSizeImage;
// 如果圖象數據內存大小為0,則重新計算
if(pDibDst->m_dwSizeImage == 0) {
DWORD dwBytes = ((DWORD) pDibDst->m_lpBMIH->biWidth * pDibDst->m_lpBMIH->biBitCount) / 32;
if(((DWORD) pDibDst->m_lpBMIH->biWidth * pDibDst->m_lpBMIH->biBitCount) % 32) {
dwBytes++;
}
dwBytes *= 4;
pDibDst->m_dwSizeImage = dwBytes * pDibDst->m_lpBMIH->biHeight;
}
// 設置DIB中的調色板指針
pDibDst->m_lpvColorTable = (LPBYTE) pDibDst->m_lpBMIH + sizeof(BITMAPINFOHEADER);
// 計算調色板的表項數
pDibDst->ComputePaletteSize(pDibDst->m_lpBMIH->biBitCount);
// 如果DIB中存在調色板,則創建一個Windows調色板
pDibDst->MakePalette();
// 分配圖象數據內存,并拷貝圖象數據
pDibDst->m_lpImage = (LPBYTE) new char[pDibDst->m_dwSizeImage];
memcpy(pDibDst->m_lpImage, pDibSrc->m_lpImage,pDibDst->m_dwSizeImage);
}
catch(CException* pe)
{
AfxMessageBox("Copy DIB error");
pDibDst->Empty();
pe->Delete();
return FALSE;
}
return TRUE;
}
/*************************************************************************
*
* \函數名稱:
* CopyScreenToDIB
*
* \輸入參數:
* LPRECT lpRect - 需要拷貝的屏幕區域
* CDib* pDibDest - 指向目標CDib對象的指針
*
* \返回值:
* BOOL - 如果操作成功,則返回TRUE
*
* \說明:
* 該函數將指定矩形位置內的屏幕內容拷貝到DIB中源CDib類pDibSrc中的數據拷貝到pDibDst中
*
*************************************************************************
*/
BOOL CopyScreenToDIB(LPRECT lpRect, CDib* pDibDest)
{
// 屏幕設備上下文和內存設備上下文句柄
HDC hScrDC, hMemDC;
// 聲明BITMAP臨時句柄和以前的BITMAP句柄
HBITMAP hBitmap, hOldBitmap;
// 調色板句柄
HPALETTE hPalette;
// 獲取矩形區域的坐標
int nX, nY, nX2, nY2;
// DIB圖象的高度和寬度
int nWidth, nHeight;
// 屏幕分辨率
int xScrn, yScrn;
// 如果給定的矩形區域為空,則不進行進一步的處理
if (IsRectEmpty(lpRect))
return FALSE;
// 得到一個屏幕設備上下文
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
// 創建與屏幕設備兼容的內存設備上下文
hMemDC = CreateCompatibleDC(hScrDC);
// 得到矩形的區域坐標
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// 得到屏幕的分辨率,以便后面的判斷處理
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
// 判斷矩形區域是否超出屏幕
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
// 計算DIB圖象的高度和寬度
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 創建一個與屏幕設備上下文兼容的DDB位圖
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// 將DDB位圖選入內存設備上下文
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 將屏幕中指定區域的圖象傳輸到內存設備上下文中
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);
// 然后將以前的圖象選入,并得到屏幕區域的DDB圖象句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
// 將臨時的設備上下文刪除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 得到當前系統調色板
hPalette = GetSystemPalette();
// 將DDB圖象轉換為DIB圖象
pDibDest->ConvertFromDDB(hBitmap,hPalette);
// 刪除臨時對象
DeleteObject(hPalette);
DeleteObject(hBitmap);
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -