需求:時候在製作一些特殊的介面時可能要用到異形視窗。
解決方案:制一張位元影像,在位元影像中指定一個透明色,這個透明色大多作為背景,也就是視窗中要切除的部分,即在一張位元影像中提取一個地區視窗是一個再方便不過的事情了,實現原理實際上是讀取位元影像中的每個像素和指定的透明色進行對比,如果是相同的顏色就排除,否則就合并起來。
//////////////////////////////////////////////////////////
//
// Funcution: CreateBitmapRgn
//
// Description:
// Create region window from block of bitmap specifies
//
// Parameters:
// nXDest x-coordinate of upper-left corner
// nYDest y-coordinate of upper-left corner
// nWidth x-coordinate of lower-right corner
// nHeight y-coordinate of lower-right corner
// nXSrc x-coordinate of start position
// nYSrc y-coordinate of start posttion
// clrTrans Specify the transparent color
//
// 2007-11-05 LiJun created
//
//////////////////////////////////////////////////////////
HRGN CreateBitmapRgn(
HBITMAP hBitmap,
int nXDest,
int nYDest,
int nWidth,
int nHeight,
int nXSrc,
int nYSrc,
COLORREF clrTrans
)
{
if( hBitmap == NULL )
return NULL;
HDC hMemDC;
HRGN hRgn, hPix;
HBITMAP OldBitmap;
hMemDC = CreateCompatibleDC(NULL);
hOldBitmap = SelectObject(hMemDC, hBitmap);
hRgn = CreateRectRgn(nXDest, nYDest, nXDest + nWidth, nYDest + nHeight);
for(int i=nXDest, x=nXSrc; i < nXDest+nWidth; i++, x++)
{
for(int j=nYDest, y=nYSrc; j < nYDest+nHeight; j++, y++)
{
if(GetPixel(hMemDC, x, y) == clrTrans)
{
hPix = CreateRectRgn(i, j, i+1, j+1);
CombineRgn(hRgn, hRgn, hPix, RGN_XOR);
DeleteObject(hPix);
}
}
}
SelectObject(hMemDC, hOldBitmap);
DeleteDC(hMemDC);
return hRgn;
}
從一段位元影像資料轉換到DIB位元影像控制代碼
需求:有時要顯示的一幅位元影像資料並不儲存一個工程資源裡或不是一個獨立的檔案,它可能是儲存在資料庫或一個結構儲存物件裡,所以就必需將讀出的資料轉換成一個DIB位元影像控制代碼
解決方案:Windows提供有一個API CreateDIBitmap函數它可以輕鬆的實現將一個DDB資料轉換成DIB控制代碼(為了樣本如何進行轉換,下面例子從一個檔案中讀取DDB資料然後用CreateDIBitmap函數進行轉換)
HBITMAP LoadBitmapEx(LPCTSTR lpszFile)
...{
if(lpszFile == NULL)
return NULL;
HBITMAP hBitmap;
HANDLE hf;
BITMAPFILEHEADER* pbmfh;
DWORD dwBytesRead, dwFileSize, dwFileSizeHigh;
BOOL bSuccess;
// 開啟一個bmp檔案
hf = CreateFile(lpszFile, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if( hf == INVALID_HANDLE_VALUE)
...{
TRACE("Open file filed with error %d ", GetLastError());
return NULL;
}
// 得到這個檔案大小
dwFileSize = GetFileSize(hf, &dwFileSizeHigh);
if( dwFileSizeHigh )
...{
CloseHandle(hf);
return NULL;
}
// 分配記憶體,大小為該檔案的大小
pbmfh = (BITMAPFILEHEADER*)malloc(dwFileSize);
if( !pbmfh )
...{
CloseHandle(hf);
return NULL;
}
// 讀取資料
bSuccess = ReadFile(hf, pbmfh, dwFileSize, &dwBytesRead, NULL);
CloseHandle(hf);
// 效驗檔案大小和檔案格式
if( !bSuccess || dwFileSize != dwBytesRead
|| pbmfh->bfType != 0x4D42 || pbmfh->bfSize != dwFileSize)
...{
free((void*)pbmfh);
return NULL;
}
// 進行DIB轉換
hBitmap = CreateDIBitmap(
GetWindowDC(NULL),
(BITMAPINFOHEADER*)(pbmfh + 1),
CBM_INIT,
(BYTE*)pbmfh + pbmfh->bfOffBits,
(BITMAPINFO*)(pbmfh + 1),
DIB_RGB_COLORS);
free((void*)pbmfh);
return hBitmap;
}