📄 hdibapi.cpp
字号:
bl = ::ReadFile(file, pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER), &len, NULL);
if (!bl || len != dwBitsSize - sizeof(BITMAPFILEHEADER))
{
::GlobalUnlock((HGLOBAL) hDIB);
::GlobalFree((HGLOBAL) hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}
LPSTR WINAPI FindDIBBits (LPSTR lpbi)
{
return (lpbi + *(LPDWORD)lpbi + PaletteSize (lpbi));
}
void WINAPI InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
DWORD dwWidth,
DWORD dwHeight,
int nBPP)
{
memset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));
lpBmInfoHdr->biSize = sizeof (BITMAPINFOHEADER);
lpBmInfoHdr->biWidth = dwWidth;
lpBmInfoHdr->biHeight = dwHeight;
lpBmInfoHdr->biPlanes = 1;
if (nBPP <= 1)
nBPP = 1;
else if (nBPP <= 4)
nBPP = 4;
else if (nBPP <= 8)
nBPP = 8;
else
nBPP = 24;
lpBmInfoHdr->biBitCount = nBPP;
lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
}
HANDLE WINAPI BitmapToDIB (HBITMAP hBitmap, HPALETTE hPal)
{
BITMAP Bitmap;
BITMAPINFOHEADER bmInfoHdr;
LPBITMAPINFOHEADER lpbmInfoHdr;
LPSTR lpBits;
HDC hMemDC;
HANDLE hDIB;
HPALETTE hOldPal = NULL;
// Do some setup -- make sure the Bitmap passed in is valid,
// get info on the bitmap (like its height, width, etc.),
// then setup a BITMAPINFOHEADER.
if (!hBitmap)
return NULL;
if (!GetObject (hBitmap, sizeof (Bitmap), (LPSTR) &Bitmap))
return NULL;
InitBitmapInfoHeader (&bmInfoHdr,
Bitmap.bmWidth,
Bitmap.bmHeight,
Bitmap.bmPlanes * Bitmap.bmBitsPixel);
// Now allocate memory for the DIB. Then, set the BITMAPINFOHEADER
// into this memory, and find out where the bitmap bits go.
hDIB = GlobalAlloc (GHND, sizeof (BITMAPINFOHEADER) +
PaletteSize ((LPSTR) &bmInfoHdr) + bmInfoHdr.biSizeImage);
if (!hDIB)
return NULL;
lpbmInfoHdr = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
*lpbmInfoHdr = bmInfoHdr;
lpBits = FindDIBBits ((LPSTR) lpbmInfoHdr);
// Now, we need a DC to hold our bitmap. If the app passed us
// a palette, it should be selected into the DC.
hMemDC = GetDC (NULL);
if (hPal)
{
hOldPal = SelectPalette (hMemDC, hPal, FALSE);
RealizePalette (hMemDC);
}
// We're finally ready to get the DIB. Call the driver and let
// it party on our bitmap. It will fill in the color table,
// and bitmap bits of our global memory block.
if (!GetDIBits (hMemDC,
hBitmap,
0,
Bitmap.bmHeight,
lpBits,
(LPBITMAPINFO) lpbmInfoHdr,
DIB_RGB_COLORS))
{
GlobalUnlock (hDIB);
GlobalFree (hDIB);
hDIB = NULL;
}
else
GlobalUnlock (hDIB);
// Finally, clean up and return.
if (hOldPal)
SelectPalette (hMemDC, hOldPal, FALSE);
ReleaseDC (NULL, hMemDC);
return hDIB;
}
int WINAPI PalEntriesOnDevice (HDC hDC)
{
int nColors;
// Find out the number of palette entries on this
// defice.
nColors = GetDeviceCaps (hDC, SIZEPALETTE);
// For non-palette devices, we'll use the # of system
// colors for our palette size.
if (!nColors)
nColors = GetDeviceCaps (hDC, NUMCOLORS);
assert (nColors);
return nColors;
}
HPALETTE WINAPI GetSystemPalette (void)
{
HDC hDC;
HPALETTE hPal = NULL;
HANDLE hLogPal;
LPLOGPALETTE lpLogPal;
int i, nColors;
// Find out how many palette entries we want.
hDC = GetDC (NULL);
if (!hDC)
{
DIBError (ERR_GETDC);
return NULL;
}
nColors = PalEntriesOnDevice (hDC);
ReleaseDC (NULL, hDC);
// Allocate room for the palette and lock it.
hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
nColors * sizeof (PALETTEENTRY));
if (!hLogPal)
{
DIBError (ERR_CREATEPAL);
return NULL;
}
lpLogPal = (LPLOGPALETTE) GlobalLock (hLogPal);
lpLogPal->palVersion = PALVERSION;
lpLogPal->palNumEntries = nColors;
for (i = 0; i < nColors; i++)
{
lpLogPal->palPalEntry[i].peBlue = 0;
*((LPWORD) (&lpLogPal->palPalEntry[i].peRed)) = i;
lpLogPal->palPalEntry[i].peFlags = PC_EXPLICIT;
}
// Go ahead and create the palette. Once it's created,
// we no longer need the LOGPALETTE, so free it.
hPal = CreatePalette (lpLogPal);
GlobalUnlock (hLogPal);
GlobalFree (hLogPal);
return hPal;
}
HDIB WINAPI CopyRectToDIB(HWND hWnd, LPRECT lpRect)
{
/* check for a valid window handle */
if (!hWnd) return NULL;
RECT rectClient;
POINT pt1, pt2;
/* convert client coords to screen coords */
pt1.x = lpRect->left;
pt1.y = lpRect->top;
pt2.x = lpRect->right;
pt2.y = lpRect->bottom;
ClientToScreen(hWnd, &pt1);
ClientToScreen(hWnd, &pt2);
rectClient.left = pt1.x;
rectClient.top = pt1.y;
rectClient.right = pt2.x;
rectClient.bottom = pt2.y;
return CopyScreenToDIB(&rectClient);
}
HDIB WINAPI CopyWindowToDIB(HWND hWnd, WORD fPrintArea)
{
HDIB hDIB=NULL; // handle to DIB
/* check for a valid window handle */
if (!hWnd)
return NULL;
switch (fPrintArea)
{
case PW_WINDOW: // copy entire window
{
RECT rectWnd;
/* get the window rectangle */
GetWindowRect(hWnd, &rectWnd);
/* get the DIB of the window by calling
* CopyScreenToDIB and passing it the window rect
*/
hDIB = CopyScreenToDIB(&rectWnd);
}
break;
case PW_CLIENT: // copy client area
{
RECT rectClient;
POINT pt1, pt2;
/* get the client area dimensions */
GetClientRect(hWnd, &rectClient);
/* convert client coords to screen coords */
pt1.x = rectClient.left;
pt1.y = rectClient.top;
pt2.x = rectClient.right;
pt2.y = rectClient.bottom;
ClientToScreen(hWnd, &pt1);
ClientToScreen(hWnd, &pt2);
rectClient.left = pt1.x;
rectClient.top = pt1.y;
rectClient.right = pt2.x;
rectClient.bottom = pt2.y;
/* get the DIB of the client area by calling
* CopyScreenToDIB and passing it the client rect
*/
hDIB = CopyScreenToDIB(&rectClient);
}
break;
default: // invalid print area
return NULL;
}
/* return the handle to the DIB */
return hDIB;
}
HDIB WINAPI CopyScreenToDIB(LPRECT lpRect)
{
HBITMAP hBitmap; // handle to device-dependent bitmap
HPALETTE hPalette; // handle to palette
HDIB hDIB=NULL; // handle to DIB
/* get the device-dependent bitmap in lpRect by calling
* CopyScreenToBitmap and passing it the rectangle to grab
*/
hBitmap = CopyScreenToBitmap(lpRect);
/* check for a valid bitmap handle */
if (!hBitmap)
return NULL;
/* get the current palette */
hPalette = GetSystemPalette();
/* convert the bitmap to a DIB */
hDIB = (HDIB)BitmapToDIB(hBitmap, hPalette);
/* clean up */
DeleteObject(hBitmap);
DeleteObject(hPalette);
/* return handle to the packed-DIB */
return hDIB;
}
HBITMAP WINAPI CopyScreenToBitmap(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);
/* 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 = (HBITMAP)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 = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
/* clean up */
DeleteDC(hScrDC);
DeleteDC(hMemDC);
/* return handle to the bitmap */
return hBitmap;
}
static char *szErrors[] = {"Not a DIB file!",
"Couldn't allocate memory!",
"Error reading file!",
"Error locking memory!",
"Error opening file!",
"Error creating palette!",
"Error getting a DC!",
"Error creating MDI Child!",
"Error creating Device Dependent Bitmap",
"StretchBlt() failed!",
"StretchDIBits() failed!",
"Paint requires both DDB and DIB!",
"SetDIBitsToDevice() failed!",
"Printer: StartDoc failed!",
"Printing: GetModuleHandle() couldn't find GDI!",
"Printer: SetAbortProc failed!",
"Printer: StartPage failed!",
"Printer: NEWFRAME failed!",
"Printer: EndPage failed!",
"Printer: EndDoc failed!",
"Only one DIB can be animated at a time!",
"No timers available for animation!",
"Can't copy to clipboard -- no current DIB!",
"Clipboard is busy -- operation aborted!",
"Can't paste -- no DIBs or DDBs in clipboard!",
"SetDIBits() failed!",
"File Not Found!",
"Error writing DIB file!"
};
void WINAPI DIBError (int ErrNo)
{
if ((ErrNo < ERR_MIN) || (ErrNo >= ERR_MAX))
{
MessageBox (GetFocus (), "Undefined Error!", NULL, MB_OK | MB_ICONHAND);
}
else
{
MessageBox (GetFocus (), szErrors[ErrNo], NULL, MB_OK | MB_ICONHAND);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -