📄 dib.c
字号:
/*************************************************************************
/* The following functions were adapted from Microsoft examples sources
/*************************************************************************/
/*************************************************************************
*
* CopyScreenToBitmap()
*
* Parameter:
*
* LPRECT lpRect - specifies the window
*
* Return Value:
*
* HDIB - identifies the device-dependent bitmap
*
* Description:
*
* This function copies the specified part of the screen to a device-
* dependent bitmap.
*
* History: Date Author Reason
* 9/15/91 Patrick Schreiber Created
* 9/25/91 Patrick Schreiber Added header and comments
*
************************************************************************/
HBITMAP CopyScreenToBitmap(HWND win, LPRECT lpRect)
{
HDC hScrDC, hMemDC; /* screen DC and memory DC */
HBITMAP hBitmap, hOldBitmap; /* handles to deice-dependent bitmaps */
int nX, nY, nX2, nY2; /* coordinates of rectangle to grab */
int nWidth, nHeight; /* DIB width and height */
int xScrn, yScrn; /* screen resolution */
/* check for an empty rectangle */
if (IsRectEmpty(lpRect))
return NULL;
/* create a DC for the screen and create */
/* a memory DC compatible to screen DC */
/* hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); */
/* hMemDC = CreateCompatibleDC(hScrDC); */
hScrDC = GetDC(win);
hMemDC = CreateCompatibleDC (hScrDC);
/* get points of rectangle to grab */
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
/* get screen resolution */
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
/* make sure bitmap rectangle is visible */
if (nX < 0)
nX = 0;
if (nY < 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// create a bitmap compatible with the screen DC
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// select new bitmap into memory DC
hOldBitmap = SelectObject(hMemDC, hBitmap);
// bitblt screen DC to memory DC
BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);
// select old bitmap back into memory DC and get handle to
// bitmap of the screen
hBitmap = SelectObject(hMemDC, hOldBitmap);
// clean up
ReleaseDC(win, hScrDC);
DeleteDC(hMemDC);
// return handle to the bitmap
return hBitmap;
}
HBITMAP
DIBToBitmap(hDIB)
HBITMAP hDIB;
{
LPSTR lpDIBHdr, lpDIBBits; // pointer to DIB header, pointer to DIB bits
HBITMAP hBitmap; // handle to device-dependent bitmap
HDC hDC; // handle to DC
if (!hDIB)
return NULL;
/* lock memory block and get a pointer to it */
lpDIBHdr = GlobalLock(hDIB);
lpDIBBits = lpDIBHdr + *(LPDWORD)lpDIBHdr + PaletteSize(lpDIBHdr);
/* get a DC */
hDC = GetDC(NULL);
if (!hDC)
{
GlobalUnlock(hDIB);
return NULL;
}
/* create bitmap from DIB info. and bits */
hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT,
lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS);
ReleaseDC(NULL, hDC);
GlobalUnlock(hDIB);
return hBitmap;
}
/****************************************************************************
* *
* FUNCTION : DibFromBitmap() *
* *
* PURPOSE : Will create a global memory block in DIB format that *
* represents the Device-dependent bitmap (DDB) passed in. *
* *
* RETURNS : A handle to the DIB *
* *
****************************************************************************/
HANDLE
DDBtoDIB(hbm, biBits, hPal)
HBITMAP hbm;
WORD biBits;
HPALETTE hPal;
{
BITMAP bm;
BITMAPINFOHEADER bi;
BITMAPINFOHEADER FAR *lpbi;
DWORD dwLen;
HANDLE hdib;
HANDLE h;
HDC hdc;
HPALETTE oldPal;
if (!hbm)
return NULL;
GetObject(hbm,sizeof(bm),(LPSTR)&bm);
if (biBits == 0)
biBits = bm.bmPlanes * bm.bmBitsPixel;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = biBits;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwLen = bi.biSize + PaletteSize(&bi);
hdc = GetDC(NULL);
oldPal = SelectPalette(hdc, hPal, FALSE);
RealizePalette(hdc);
hdib = GlobalAlloc(GHND,dwLen);
if (!hdib)
{
SelectPalette(hdc, oldPal, FALSE);
ReleaseDC(NULL, hdc);
return NULL;
}
lpbi = (VOID FAR *)GlobalLock(hdib);
*lpbi = bi;
/* call GetDIBits with a NULL lpBits param, so it will calculate the
* biSizeImage field for us
*/
GetDIBits(hdc, hbm, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
GlobalUnlock(hdib);
/* If the driver did not fill in the biSizeImage field, make one up */
if (bi.biSizeImage == 0)
bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
/* realloc the buffer big enough to hold all the bits */
dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
if (h = GlobalReAlloc(hdib,dwLen,0))
hdib = h;
else
{
GlobalFree(hdib);
hdib = NULL;
SelectPalette(hdc, oldPal, FALSE);
ReleaseDC(NULL,hdc);
return hdib;
}
/* call GetDIBits with a NON-NULL lpBits param, and actualy get the
* bits this time
*/
lpbi = (VOID FAR *)GlobalLock(hdib);
if (GetDIBits( hdc,
hbm,
0L,
(DWORD)bi.biHeight,
(LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
(LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS) == 0)
{
GlobalUnlock(hdib);
hdib = NULL;
SelectPalette(hdc, oldPal, FALSE);
ReleaseDC(NULL,hdc);
return NULL;
}
bi = *lpbi;
GlobalUnlock(hdib);
SelectPalette(hdc, oldPal, FALSE);
ReleaseDC(NULL,hdc);
return hdib;
}
/*************************************************************************
*
* Function: ReadDIBRsrc (int)
*
* Purpose: Reads in the specified DIB file into a global chunk of
* memory.
*
* Returns: A handle to a dib (hDIB) if successful.
* NULL if an error occurs.
*
* Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything
* from the end of the BITMAPFILEHEADER structure on is
* returned in the global memory handle.
*
*
* NOTE: The DIB API were not written to handle OS/2 DIBs, so this
* function will reject any file that is not a Windows DIB.
*
* History: Date Author Reason
* 9/15/91 Mark Bader Based on DIBVIEW
* 6/25/92 Mark Bader Added check for OS/2 DIB
* 7/21/92 Mark Bader Added code to deal with bfOffBits
* field in BITMAPFILEHEADER
* 9/11/92 Mark Bader Fixed Realloc Code to free original mem
* 1/25/94 Hung Nguyen Changed file APIs to Win32 APIs
*
*************************************************************************/
HANDLE ReadDIBRsrc(HINSTANCE hInst, HRSRC hRsrc )
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
UINT nNumColors; /* Number of colors in table */
HANDLE hDIB;
HANDLE hDIBtmp; /* Used for GlobalRealloc() //MPB */
LPBITMAPINFOHEADER lpbi;
DWORD offBits;
LPSTR rsrcptr, beginrsrc;
HGLOBAL hg;
/* get length of DIB in bytes for use when reading */
hg = LoadResource(hInst, hRsrc);
if(hg == NULL)
return NULL;
beginrsrc = rsrcptr = LockResource(hg);
dwBitsSize = SizeofResource(hInst, hRsrc);
/* Allocate memory for header & color table. We'll enlarge this */
/* memory as needed. */
hDIB = GlobalAlloc(GMEM_MOVEABLE, (DWORD)(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)));
if (!hDIB)
goto ErrExitRsrc;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
if (!lpbi)
{
GlobalFree(hDIB);
goto ErrExitRsrc;
}
/* read the BITMAPFILEHEADER from our file */
memcpy(&bmfHeader, rsrcptr, sizeof (BITMAPFILEHEADER));
rsrcptr += sizeof (BITMAPFILEHEADER);
if (bmfHeader.bfType != 0x4d42) /* 'BM' */
goto ErrExit;
/* read the BITMAPINFOHEADER */
memcpy(lpbi, rsrcptr, sizeof(BITMAPINFOHEADER));
rsrcptr += sizeof (BITMAPINFOHEADER);
/* Check to see that it's a Windows DIB -- an OS/2 DIB would cause */
/* strange problems with the rest of the DIB API since the fields */
/* in the header are different and the color table entries are */
/* smaller. */
/* */
/* If it's not a Windows DIB (e.g. if biSize is wrong), return NULL. */
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
goto ErrExit;
/* Now determine the size of the color table and read it. Since the */
/* bitmap bits are offset in the file by bfOffBits, we need to do some */
/* special processing here to make sure the bits directly follow */
/* the color table (because that's the format we are susposed to pass */
/* back) */
if (!(nNumColors = (UINT)lpbi->biClrUsed))
{
/* no color table for 24-bit, default size otherwise */
if (lpbi->biBitCount != 24)
nNumColors = 1 << lpbi->biBitCount; /* standard size table */
}
/* fill in some default values if they are zero */
if (lpbi->biClrUsed == 0)
lpbi->biClrUsed = nNumColors;
if (lpbi->biSizeImage == 0)
{
lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) +
31) & ~31) >> 3) * lpbi->biHeight;
}
/* get a proper-sized buffer for header, color table and bits */
GlobalUnlock(hDIB);
hDIBtmp = GlobalReAlloc(hDIB, lpbi->biSize + nNumColors *
sizeof(RGBQUAD) + lpbi->biSizeImage, 0);
if (!hDIBtmp) /* can't resize buffer for loading */
goto ErrExitNoUnlock; /* MPB */
else
hDIB = hDIBtmp;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/* read the color table */
memcpy((LPSTR)(lpbi) + lpbi->biSize, rsrcptr, nNumColors * sizeof(RGBQUAD));
rsrcptr += nNumColors * sizeof(RGBQUAD);
/* offset to the bits from start of DIB header */
offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD);
/* If the bfOffBits field is non-zero, then the bits might *not* be */
/* directly following the color table in the file. Use the value in */
/* bfOffBits to seek the bits. */
if (bmfHeader.bfOffBits != 0L)
rsrcptr = beginrsrc + bmfHeader.bfOffBits;
memcpy((LPSTR)lpbi + offBits, rsrcptr, lpbi->biSizeImage);
goto OKExit;
ErrExit:
GlobalUnlock(hDIB);
ErrExitNoUnlock:
GlobalFree(hDIB);
ErrExitRsrc:
FreeResource(hg);
return NULL;
OKExit:
FreeResource(hg);
GlobalUnlock(hDIB);
return hDIB;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -