📄 subject_16821.htm
字号:
<br>内容:LPSTR FindDIBBits(LPSTR lpDIB); 你用这个函数吧!给点分吧!谢谢<BR>/* PortTool v2.2 dibutil.h */ <BR><BR>#include "stdafx.h" <BR><BR>/* DIB constants */ <BR>#define PALVERSION 0x300 <BR><BR>/* DIB macros */ <BR>#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER)) <BR>#define RECTWIDTH(lpRect) ((lpRect)->right - (lpRect)->left) <BR>#define RECTHEIGHT(lpRect) ((lpRect)->bottom - (lpRect)->top) <BR><BR>/* Handle to a DIB */ <BR>#define HDIB HANDLE <BR><BR><BR>/* Print Area selection */ <BR>#define PW_WINDOW 1 <BR>#define PW_CLIENT 2 <BR><BR><BR>/* Print Options selection */ <BR>#define PW_BESTFIT 1 <BR>#define PW_STRETCHTOPAGE 2 <BR>#define PW_SCALE 3 <BR><BR>/* DIB Macros*/ <BR><BR>// WIDTHBYTES performs DWORD-aligning of DIB scanlines. The "bits" <BR>// parameter is the bit count for the scanline (biWidth * biBitCount), <BR>// and this macro returns the number of DWORD-aligned bytes needed <BR>// to hold those bits. <BR><BR>#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) <BR><BR>/* Error constants */ <BR>enum { <BR> ERR_MIN = 0, // All error #s >= this value <BR> ERR_NOT_DIB = 0, // Tried to load a file, NOT a DIB! <BR> ERR_MEMORY, // Not enough memory! <BR> ERR_READ, // Error reading file! <BR> ERR_LOCK, // Error on a GlobalLock()! <BR> ERR_OPEN, // Error opening a file! <BR> ERR_CREATEPAL, // Error creating palette. <BR> ERR_GETDC, // Couldn't get a DC. <BR> ERR_CREATEDDB, // Error create a DDB. <BR> ERR_STRETCHBLT, // StretchBlt() returned failure. <BR> ERR_STRETCHDIBITS, // StretchDIBits() returned failure. <BR> ERR_SETDIBITSTODEVICE, // SetDIBitsToDevice() failed. <BR> ERR_STARTDOC, // Error calling StartDoc(). <BR> ERR_NOGDIMODULE, // Couldn't find GDI module in memory. <BR> ERR_SETABORTPROC, // Error calling SetAbortProc(). <BR> ERR_STARTPAGE, // Error calling StartPage(). <BR> ERR_NEWFRAME, // Error calling NEWFRAME escape. <BR> ERR_ENDPAGE, // Error calling EndPage(). <BR> ERR_ENDDOC, // Error calling EndDoc(). <BR> ERR_SETDIBITS, // Error calling SetDIBits(). <BR> ERR_FILENOTFOUND, // Error opening file in GetDib() <BR> ERR_INVALIDHANDLE, // Invalid Handle <BR> ERR_DIBFUNCTION, // Error on call to DIB function <BR> ERR_MAX // All error #s < this value <BR> }; <BR><BR>/* function prototypes */ <BR>HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap); <BR>HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal); <BR>HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal); <BR>WORD DIBNumColors(VOID FAR * pv);<BR>WORD PaletteSize(LPSTR lpDIB);<BR>HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount); <BR>LPSTR FindDIBBits(LPSTR lpDIB); <BR>DWORD DIBWidth(LPSTR lpDIB);<BR>DWORD DIBHeight(LPSTR lpDIB);<BR>WORD DIBNumColors(LPSTR lpDIB);<BR>HPALETTE CreateDIBPalette(HDIB hDIB);<BR>HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal);<BR><BR>int PalEntriesOnDevice(HDC hDC);<BR>HPALETTE GetSystemPalette(void);<BR>HDIB ChangeDIBFormat(HDIB hDIB, WORD wBitCount, DWORD dwCompression);<BR>HDIB ChangeBitmapFormat(HBITMAP hBitmap, WORD wBitCount, DWORD dwCompression, <BR> HPALETTE hPal);<BR>BOOL SaveDIB(HDIB hDib, LPSTR lpFileName); <BR>/////////////////////////////////////////////////////<BR>HDIB WINAPI ReadDIBFile(CFile& file);<BR>BOOL WINAPI PaintDIB(HDC hDC,<BR> LPRECT lpDCRect,<BR> HDIB hDIB,<BR> LPRECT lpDIBRect,<BR> CPalette* pPal);<BR> BOOL WINAPI PaintDIBEx(HDC hDC,<BR> LPRECT lpDCRect,<BR> HDIB hDIB,<BR> LPRECT lpDIBRect,<BR> HPALETTE pPal);<BR>CString StrChange(CString str);<BR>CString StrChangeEnd(CString str);<BR>BOOL WINAPI PaintDIBExEx(HDC hDC,<BR> LPRECT lpDCRect,<BR> HDIB hDIB,<BR> //LPRECT lpDIBRect,<BR> HPALETTE pPal);<BR>HPALETTE GetPrintPalette(HDC hDC);<BR><BR>CString ChangeCByteArrayToStr(CByteArray array);<BR>void ChangeStrToCByteArray(CString str,CByteArray array);<BR>BOOL SaveDIBEx(HDIB hDib, CString lpFileName); <BR>//********************************************************************** <BR>// <BR>// dibutil.cpp ( stripped down version from WIN32CAP sample ) <BR>// <BR>// Source file for Device-Independent Bitmap (DIB) API. <BR>// <BR>// Written by Microsoft Product Support Services, Developer Support. <BR>// Copyright (C) 1991-1996 Microsoft Corporation. All rights reserved. <BR>//********************************************************************** <BR><BR>#include "stdafx.h" <BR>#include "dibutil.h" <BR><BR>/**************************************************************************** <BR> * * <BR> * FUNCTION : DibNumColors(VOID FAR * pv) * <BR> * * <BR> * PURPOSE : Determines the number of colors in the DIB by looking at * <BR> * the BitCount filed in the info block. * <BR> * * <BR> * RETURNS : The number of colors in the DIB. * <BR> * * <BR> ****************************************************************************/ <BR>WORD DIBNumColors(VOID FAR * pv) <BR>{ <BR> INT bits; <BR> LPBITMAPINFOHEADER lpbi; <BR> LPBITMAPCOREHEADER lpbc; <BR><BR> lpbi = ((LPBITMAPINFOHEADER)pv); <BR> lpbc = ((LPBITMAPCOREHEADER)pv); <BR><BR> /* With the BITMAPINFO format headers, the size of the palette <BR> * is in biClrUsed, whereas in the BITMAPCORE - style headers, it <BR> * is dependent on the bits per pixel ( = 2 raised to the power of <BR> * bits/pixel). <BR> */ <BR> if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){ <BR> if (lpbi->biClrUsed != 0) <BR> return (WORD)lpbi->biClrUsed; <BR> bits = lpbi->biBitCount; <BR> } <BR> else <BR> bits = lpbc->bcBitCount; <BR><BR> switch (bits){ <BR> case 1: <BR> return 2; <BR> case 4: <BR> return 16; <BR> case 8: <BR> return 256; <BR> default: <BR> return 0; <BR> } <BR>} <BR><BR>/************************************************************************* <BR> * <BR> * PaletteSize() <BR> * <BR> * Parameter: <BR> * <BR> * LPSTR lpDIB - pointer to packed-DIB memory block <BR> * <BR> * Return Value: <BR> * <BR> * WORD - size of the color palette of the DIB <BR> * <BR> * Description: <BR> * <BR> * This function gets the size required to store the DIB's palette by <BR> * multiplying the number of colors by the size of an RGBQUAD (for a <BR> * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an OS/2- <BR> * style DIB). <BR> * <BR> ************************************************************************/ <BR><BR>WORD PaletteSize(LPSTR lpDIB) <BR>{ <BR> // calculate the size required by the palette <BR> if (IS_WIN30_DIB (lpDIB)) <BR> return (DIBNumColors(lpDIB) * sizeof(RGBQUAD)); <BR> else <BR> return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE)); <BR>} <BR><BR>/************************************************************************* <BR> * <BR> * CreateDIB() <BR> * <BR> * Parameters: <BR> * <BR> * DWORD dwWidth - Width for new bitmap, in pixels <BR> * DWORD dwHeight - Height for new bitmap <BR> * WORD wBitCount - Bit Count for new DIB (1, 4, 8, or 24) <BR> * <BR> * Return Value: <BR> * <BR> * HDIB - Handle to new DIB <BR> * <BR> * Description: <BR> * <BR> * This function allocates memory for and initializes a new DIB by <BR> * filling in the BITMAPINFOHEADER, allocating memory for the color <BR> * table, and allocating memory for the bitmap bits. As with all <BR> * HDIBs, the header, colortable and bits are all in one contiguous <BR> * memory block. This function is similar to the CreateBitmap() <BR> * Windows API. <BR> * <BR> * The colortable and bitmap bits are left uninitialized (zeroed) in the <BR> * returned HDIB. <BR> * <BR> * <BR> ************************************************************************/ <BR><BR>HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) <BR>{ <BR> BITMAPINFOHEADER bi; // bitmap header <BR> LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER <BR> DWORD dwLen; // size of memory block <BR> HDIB hDIB; <BR> DWORD dwBytesPerLine; // Number of bytes per scanline <BR><BR><BR> // Make sure bits per pixel is valid <BR><BR> if (wBitCount <= 1) <BR> wBitCount = 1; <BR> else if (wBitCount <= 4) <BR> wBitCount = 4; <BR> else if (wBitCount <= 8) <BR> wBitCount = 8; <BR> else if (wBitCount <= 24) <BR> wBitCount = 24; <BR> else <BR> wBitCount = 4; // set default value to 4 if parameter is bogus <BR><BR> // initialize BITMAPINFOHEADER <BR><BR> bi.biSize = sizeof(BITMAPINFOHEADER); <BR> bi.biWidth = dwWidth; // fill in width from parameter <BR> bi.biHeight = dwHeight; // fill in height from parameter <BR> bi.biPlanes = 1; // must be 1 <BR> bi.biBitCount = wBitCount; // from parameter <BR> bi.biCompression = BI_RGB; <BR> bi.biSizeImage = 0; // 0's here mean "default" <BR> bi.biXPelsPerMeter = 0; <BR> bi.biYPelsPerMeter = 0; <BR> bi.biClrUsed = 0; <BR> bi.biClrImportant = 0; <BR><BR> // calculate size of memory block required to store the DIB. This <BR> // block should be big enough to hold the BITMAPINFOHEADER, the color <BR> // table, and the bits <BR><BR> dwBytesPerLine = WIDTHBYTES(wBitCount * dwWidth); <BR> dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight); <BR><BR> // alloc memory block to store our bitmap <BR><BR> hDIB = GlobalAlloc(GHND, dwLen); <BR><BR> // major bummer if we couldn't get memory block <BR><BR> if (!hDIB) <BR> return NULL; <BR><BR> // lock memory and get pointer to it <BR><BR> lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); <BR><BR> // use our bitmap info structure to fill in first part of <BR> // our DIB with the BITMAPINFOHEADER <BR><BR> *lpbi = bi; <BR><BR> // Since we don't know what the colortable and bits should contain, <BR> // just leave these blank. Unlock the DIB and return the HDIB. <BR><BR> GlobalUnlock(hDIB); <BR><BR> //return handle to the DIB <BR><BR> return hDIB; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * FindDIBBits() <BR> * <BR> * Parameter: <BR> * <BR> * LPSTR lpDIB - pointer to packed-DIB memory block <BR> * <BR> * Return Value: <BR> * <BR> * LPSTR - pointer to the DIB bits <BR> * <BR> * Description: <BR> * <BR> * This function calculates the address of the DIB's bits and returns a <BR> * pointer to the DIB bits. <BR> * <BR> ************************************************************************/ <BR><BR>LPSTR FindDIBBits(LPSTR lpDIB) <BR>{ <BR> return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB)); <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * DIBWidth() <BR> * <BR> * Parameter: <BR> * <BR> * LPSTR lpDIB - pointer to packed-DIB memory block <BR> * <BR> * Return Value: <BR> * <BR> * DWORD - width of the DIB <BR> * <BR> * Description: <BR> * <BR> * This function gets the width of the DIB from the BITMAPINFOHEADER <BR> * width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER <BR> * width field if it is an OS/2-style DIB. <BR> * <BR> ************************************************************************/ <BR><BR><BR>DWORD DIBWidth(LPSTR lpDIB) <BR>{ <BR> LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB <BR> LPBITMAPCOREHEADER lpbmc; // pointer to an OS/2-style DIB <BR><BR> // point to the header (whether Win 3.0 and OS/2) <BR><BR> lpbmi = (LPBITMAPINFOHEADER)lpDIB; <BR> lpbmc = (LPBITMAPCOREHEADER)lpDIB; <BR><BR> // return the DIB width if it is a Win 3.0 DIB <BR><BR> if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) <BR> return lpbmi->biWidth; <BR> else // it is an OS/2 DIB, so return its width <BR> return (DWORD)lpbmc->bcWidth; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * DIBHeight() <BR> * <BR> * Parameter: <BR> * <BR> * LPSTR lpDIB - pointer to packed-DIB memory block <BR> * <BR> * Return Value: <BR> * <BR> * DWORD - height of the DIB <BR> * <BR> * Description: <BR> * <BR> * This function gets the height of the DIB from the BITMAPINFOHEADER <BR> * height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER <BR> * height field if it is an OS/2-style DIB. <BR> * <BR> ************************************************************************/ <BR><BR>DWORD DIBHeight(LPSTR lpDIB) <BR>{ <BR> LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB <BR> LPBITMAPCOREHEADER lpbmc; // pointer to an OS/2-style DIB <BR><BR> // point to the header (whether OS/2 or Win 3.0 <BR><BR> lpbmi = (LPBITMAPINFOHEADER)lpDIB; <BR> lpbmc = (LPBITMAPCOREHEADER)lpDIB; <BR><BR> // return the DIB height if it is a Win 3.0 DIB <BR> if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) <BR> return lpbmi->biHeight; <BR> else // it is an OS/2 DIB, so return its height <BR> return (DWORD)lpbmc->bcHeight; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * DIBNumColors() <BR> * <BR> * Parameter: <BR> * <BR> * LPSTR lpDIB - pointer to packed-DIB memory block <BR> * <BR> * Return Value: <BR> * <BR> * WORD - number of colors in the color table <BR> * <BR> * Description: <BR> * <BR> * This function calculates the number of colors in the DIB's color table <BR> * by finding the bits per pixel for the DIB (whether Win3.0 or OS/2-style <BR> * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256, <BR> * if 24, no colors in color table. <BR> * <BR> ************************************************************************/ <BR><BR>WORD DIBNumColors(LPSTR lpDIB) <BR>{ <BR> WORD wBitCount; // DIB bit count <BR><BR> // If this is a Windows-style DIB, the number of colors in the <BR> // color table can be less than the number of bits per pixel <BR> // allows for (i.e. lpbi->biClrUsed can be set to some value). <BR> // If this is the case, return the appropriate value. <BR> <BR><BR> if (IS_WIN30_DIB(lpDIB)) <BR> { <BR> DWORD dwClrUsed; <BR><BR> dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed; <BR> if (dwClrUsed) <BR><BR> return (WORD)dwClrUsed; <BR> } <BR><BR> // Calculate the number of colors in the color table based on <BR> // the number of bits per pixel for the DIB. <BR> <BR> if (IS_WIN30_DIB(lpDIB)) <BR> wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount; <BR> else <BR> wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount; <BR><BR> // return number of colors based on bits per pixel <BR><BR> switch (wBitCount) <BR> { <BR> case 1: <BR> return 2; <BR><BR> case 4: <BR> return 16; <BR><BR> case 8: <BR> return 256; <BR><BR> default: <BR> return 0; <BR> } <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * CreateDIBPalette() <BR> * <BR> * Parameter: <BR> * <BR> * HDIB hDIB - specifies the DIB <BR> * <BR> * Return Value: <BR> * <BR> * HPALETTE - specifies the palette <BR> * <BR> * Description: <BR> * <BR> * This function creates a palette from a DIB by allocating memory for the <BR> * logical palette, reading and storing the colors from the DIB's color table <BR> * into the logical palette, creating a palette from this logical palette, <BR> * and then returning the palette's handle. This allows the DIB to be <BR> * displayed using the best possible colors (important for DIBs with 256 or <BR> * more colors). <BR> * <BR> ************************************************************************/ <BR><BR>HPALETTE CreateDIBPalette(HDIB hDIB) <BR>{ <BR> LPLOGPALETTE lpPal; // pointer to a logical palette <BR> HANDLE hLogPal = NULL; // handle to a logical palette <BR> HPALETTE hPal = NULL; // handle to a palette <BR> int i, wNumColors; // loop index, number of colors in color table <BR> LPSTR lpbi; // pointer to packed-DIB <BR> LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure (Win3.0) <BR> LPBITMAPCOREINFO lpbmc; // pointer to BITMAPCOREINFO structure (OS/2) <BR> BOOL bWinStyleDIB; // Win3.0 DIB? <BR><BR> // if handle to DIB is invalid, return NULL <BR><BR> if (!hDIB) <BR> return NULL; <BR><BR> // lock DIB memory block and get a pointer to it <BR><BR> lpbi = (char*) GlobalLock(hDIB); <BR><BR> // get pointer to BITMAPINFO (Win 3.0) <BR><BR> lpbmi = (LPBITMAPINFO)lpbi; <BR><BR> // get pointer to BITMAPCOREINFO (OS/2 1.x) <BR><BR> lpbmc = (LPBITMAPCOREINFO)lpbi; <BR><BR> // get the number of colors in the DIB <BR><BR> wNumColors = DIBNumColors(lpbi); <BR><BR> // is this a Win 3.0 DIB? <BR><BR> bWinStyleDIB = IS_WIN30_DIB(lpbi); <BR> if (wNumColors) <BR> { <BR> // allocate memory block for logical palette <BR><BR> hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + <BR> sizeof(PALETTEENTRY) * wNumColors); <BR><BR> // if not enough memory, clean up and return NULL <BR><BR> if (!hLogPal) <BR> { <BR> GlobalUnlock(hDIB); <BR> return NULL; <BR> } <BR><BR> // lock memory block and get pointer to it <BR><BR> lpPal = (LPLOGPALETTE)GlobalLock(hLogPal); <BR><BR> // set version and number of palette entries <BR><BR> lpPal->palVersion = PALVERSION; <BR> lpPal->palNumEntries = wNumColors; <BR><BR> // store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB) <BR> // into palette <BR> <BR> for (i = 0; i < wNumColors; i++) <BR> { <BR> if (bWinStyleDIB) <BR> { <BR> lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; <BR> lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; <BR> lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; <BR> lpPal->palPalEntry[i].peFlags = 0; <BR> } <BR> else <BR> { <BR> lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; <BR> lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; <BR> lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; <BR> lpPal->palPalEntry[i].peFlags = 0; <BR> } <BR> } <BR><BR> // create the palette and get handle to it <BR><BR> hPal = CreatePalette(lpPal); <BR><BR> // if error getting handle to palette, clean up and return NULL <BR><BR> if (!hPal) <BR> { <BR> GlobalUnlock(hLogPal); <BR> GlobalFree(hLogPal); <BR> return NULL; <BR> } <BR> } <BR><BR> // clean up <BR><BR> GlobalUnlock(hLogPal); <BR> GlobalFree(hLogPal); <BR> GlobalUnlock(hDIB); <BR><BR> // return handle to DIB's palette <BR> return hPal; <BR>} <BR><BR>/************************************************************************* <BR> * <BR> * DIBToBitmap() <BR> * <BR> * Parameters: <BR> * <BR> * HDIB hDIB - specifies the DIB to convert <BR> * <BR> * HPALETTE hPal - specifies the palette to use with the bitmap <BR> * <BR> * Return Value: <BR> * <BR> * HBITMAP - identifies the device-dependent bitmap <BR> * <BR> * Description: <BR> * <BR> * This function creates a bitmap from a DIB using the specified palette. <BR> * If no palette is specified, default is used. <BR> * <BR> * NOTE: <BR> * <BR> * The bitmap returned from this funciton is always a bitmap compatible <BR> * with the screen (e.g. same bits/pixel and color planes) rather than <BR> * a bitmap with the same attributes as the DIB. This behavior is by <BR> * design, and occurs because this function calls CreateDIBitmap to <BR> * do its work, and CreateDIBitmap always creates a bitmap compatible <BR> * with the hDC parameter passed in (because it in turn calls <BR> * CreateCompatibleBitmap). <BR> * <BR> * So for instance, if your DIB is a monochrome DIB and you call this <BR> * function, you will not get back a monochrome HBITMAP -- you will <BR> * get an HBITMAP compatible with the screen DC, but with only 2 <BR> * colors used in the bitmap. <BR> * <BR> * If your application requires a monochrome HBITMAP returned for a <BR> * monochrome DIB, use the function SetDIBits(). <BR> * <BR> * Also, the DIBpassed in to the function is not destroyed on exit. This <BR> * must be done later, once it is no longer needed. <BR> * <BR> ************************************************************************/ <BR><BR>HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal) <BR>{ <BR> LPSTR lpDIBHdr, lpDIBBits; // pointer to DIB header, pointer to DIB bits <BR> HBITMAP hBitmap; // handle to device-dependent bitmap <BR> HDC hDC; // handle to DC <BR> HPALETTE hOldPal = NULL; // handle to a palette <BR><BR> // if invalid handle, return NULL <BR><BR> if (!hDIB) <BR> return NULL; <BR><BR> // lock memory block and get a pointer to it <BR><BR> lpDIBHdr = (char*) GlobalLock(hDIB); <BR><BR> // get a pointer to the DIB bits <BR><BR> lpDIBBits = FindDIBBits(lpDIBHdr); <BR><BR> // get a DC <BR><BR> hDC = GetDC(NULL); <BR> if (!hDC) <BR> { <BR> // clean up and return NULL <BR><BR> GlobalUnlock(hDIB); <BR> return NULL; <BR> } <BR><BR> // select and realize palette <BR><BR> if (hPal) <BR> hOldPal = SelectPalette(hDC, hPal, FALSE); <BR><BR> RealizePalette(hDC); <BR><BR> // create bitmap from DIB info. and bits <BR> hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT, <BR> lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS); <BR><BR> // restore previous palette <BR> if (hOldPal) <BR> SelectPalette(hDC, hOldPal, FALSE); <BR><BR> // clean up <BR> ReleaseDC(NULL, hDC); <BR> GlobalUnlock(hDIB); <BR><BR> // return handle to the bitmap <BR> return hBitmap; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * BitmapToDIB() <BR> * <BR> * Parameters: <BR> * <BR> * HBITMAP hBitmap - specifies the bitmap to convert <BR> * <BR> * HPALETTE hPal - specifies the palette to use with the bitmap <BR> * <BR> * Return Value: <BR> * <BR> * HDIB - identifies the device-dependent bitmap <BR> * <BR> * Description: <BR> * <BR> * This function creates a DIB from a bitmap using the specified palette. <BR> * <BR> ************************************************************************/ <BR><BR>HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal) <BR>{ <BR> BITMAP bm; // bitmap structure <BR> BITMAPINFOHEADER bi; // bitmap header <BR> LPBITMAPINFOHEADER lpbi; // pointer to BITMAPINFOHEADER <BR> DWORD dwLen; // size of memory block <BR> HANDLE hDIB, h; // handle to DIB, temp handle <BR> HDC hDC; // handle to DC <BR> WORD biBits; // bits per pixel <BR><BR> // check if bitmap handle is valid <BR><BR> if (!hBitmap) <BR> return NULL; <BR><BR> // fill in BITMAP structure, return NULL if it didn't work <BR><BR> if (!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm)) <BR> return NULL; <BR><BR> // if no palette is specified, use default palette <BR><BR> if (hPal == NULL) <BR> hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); <BR><BR> // calculate bits per pixel <BR><BR> biBits = bm.bmPlanes * bm.bmBitsPixel; <BR><BR> // make sure bits per pixel is valid <BR><BR> if (biBits <= 1) <BR> biBits = 1; <BR> else if (biBits <= 4) <BR> biBits = 4; <BR> else if (biBits <= 8) <BR> biBits = 8; <BR> else // if greater than 8-bit, force to 24-bit <BR> biBits = 24; <BR><BR> // initialize BITMAPINFOHEADER <BR><BR> bi.biSize = sizeof(BITMAPINFOHEADER); <BR> bi.biWidth = bm.bmWidth; <BR> bi.biHeight = bm.bmHeight; <BR> bi.biPlanes = 1; <BR> bi.biBitCount = biBits; <BR> bi.biCompression = BI_RGB; <BR> bi.biSizeImage = 0; <BR> bi.biXPelsPerMeter = 0; <BR> bi.biYPelsPerMeter = 0; <BR> bi.biClrUsed = 0; <BR> bi.biClrImportant = 0; <BR><BR> // calculate size of memory block required to store BITMAPINFO <BR><BR> dwLen = bi.biSize + PaletteSize((LPSTR)&bi); <BR><BR> // get a DC <BR><BR> hDC = GetDC(NULL); <BR><BR> // select and realize our palette <BR><BR> hPal = SelectPalette(hDC, hPal, FALSE); <BR> RealizePalette(hDC); <BR><BR> // alloc memory block to store our bitmap <BR><BR> hDIB = GlobalAlloc(GHND, dwLen); <BR><BR> // if we couldn't get memory block <BR><BR> if (!hDIB) <BR> { <BR> // clean up and return NULL <BR><BR> SelectPalette(hDC, hPal, TRUE); <BR> RealizePalette(hDC); <BR> ReleaseDC(NULL, hDC); <BR> return NULL; <BR> } <BR><BR> // lock memory and get pointer to it <BR><BR> lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); <BR><BR> /// use our bitmap info. to fill BITMAPINFOHEADER <BR><BR> *lpbi = bi; <BR><BR> // call GetDIBits with a NULL lpBits param, so it will calculate the <BR> // biSizeImage field for us <BR><BR> GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi, <BR> DIB_RGB_COLORS); <BR><BR> // get the info. returned by GetDIBits and unlock memory block <BR><BR> bi = *lpbi; <BR> GlobalUnlock(hDIB); <BR><BR> // if the driver did not fill in the biSizeImage field, make one up <BR> if (bi.biSizeImage == 0) <BR> bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight; <BR><BR> // realloc the buffer big enough to hold all the bits <BR><BR> dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + bi.biSizeImage; <BR><BR> if (h = GlobalReAlloc(hDIB, dwLen, 0)) <BR> hDIB = h; <BR> else <BR> { <BR> // clean up and return NULL <BR><BR> GlobalFree(hDIB); <BR> hDIB = NULL; <BR> SelectPalette(hDC, hPal, TRUE); <BR> RealizePalette(hDC); <BR> ReleaseDC(NULL, hDC); <BR> return NULL; <BR> } <BR><BR> // lock memory block and get pointer to it */ <BR><BR> lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); <BR><BR> // call GetDIBits with a NON-NULL lpBits param, and actualy get the <BR> // bits this time <BR><BR> if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi + <BR> (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi, <BR> DIB_RGB_COLORS) == 0) <BR> { <BR> // clean up and return NULL <BR><BR> GlobalUnlock(hDIB); <BR> hDIB = NULL; <BR> SelectPalette(hDC, hPal, TRUE); <BR> RealizePalette(hDC); <BR> ReleaseDC(NULL, hDC); <BR> return NULL; <BR> } <BR><BR> bi = *lpbi; <BR><BR> // clean up <BR> GlobalUnlock(hDIB); <BR> SelectPalette(hDC, hPal, TRUE); <BR> RealizePalette(hDC); <BR> ReleaseDC(NULL, hDC); <BR><BR> // return handle to the DIB <BR> return hDIB; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * PalEntriesOnDevice() <BR> * <BR> * Parameter: <BR> * <BR> * HDC hDC - device context <BR> * <BR> * Return Value: <BR> * <BR> * int - number of palette entries on device <BR> * <BR> * Description: <BR> * <BR> * This function gets the number of palette entries on the specified device <BR> * <BR> ************************************************************************/ <BR><BR>int PalEntriesOnDevice(HDC hDC) <BR>{ <BR> int nColors; // number of colors <BR><BR> // Find out the number of colors on this device. <BR> <BR> nColors = (1 << (GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES))); <BR><BR> ASSERT(nColors); <BR> return nColors; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * GetSystemPalette() <BR> * <BR> * Parameters: <BR> * <BR> * None <BR> * <BR> * Return Value: <BR> * <BR> * HPALETTE - handle to a copy of the current system palette <BR> * <BR> * Description: <BR> * <BR> * This function returns a handle to a palette which represents the system <BR> * palette. The system RGB values are copied into our logical palette using <BR> * the GetSystemPaletteEntries function. <BR> * <BR> ************************************************************************/ <BR><BR>HPALETTE GetSystemPalette(void) <BR>{ <BR> HDC hDC; // handle to a DC <BR> static HPALETTE hPal = NULL; // handle to a palette <BR> HANDLE hLogPal; // handle to a logical palette <BR> LPLOGPALETTE lpLogPal; // pointer to a logical palette <BR> int nColors; // number of colors <BR><BR> // Find out how many palette entries we want. <BR><BR> hDC = GetDC(NULL); <BR> <BR> if (!hDC) <BR> return NULL; <BR><BR> nColors = PalEntriesOnDevice(hDC); // Number of palette entries <BR><BR> // Allocate room for the palette and lock it. <BR><BR> hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + nColors * <BR> sizeof(PALETTEENTRY)); <BR><BR> // if we didn't get a logical palette, return NULL <BR><BR> if (!hLogPal) <BR> return NULL; <BR><BR> // get a pointer to the logical palette <BR><BR> lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal); <BR><BR> // set some important fields <BR><BR> lpLogPal->palVersion = PALVERSION; <BR> lpLogPal->palNumEntries = nColors; <BR><BR> // Copy the current system palette into our logical palette <BR><BR> GetSystemPaletteEntries(hDC, 0, nColors, <BR> (LPPALETTEENTRY)(lpLogPal->palPalEntry)); <BR><BR> // Go ahead and create the palette. Once it's created, <BR> // we no longer need the LOGPALETTE, so free it. <BR><BR> hPal = CreatePalette(lpLogPal); <BR><BR> // clean up <BR><BR> GlobalUnlock(hLogPal); <BR> GlobalFree(hLogPal); <BR> ReleaseDC(NULL, hDC);<BR> <BR><BR> return hPal; <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * AllocRoomForDIB() <BR> * <BR> * Parameters: <BR> * <BR> * BITMAPINFOHEADER - bitmap info header stucture <BR> * <BR> * HBITMAP - handle to the bitmap <BR> * <BR> * Return Value: <BR> * <BR> * HDIB - handle to memory block <BR> * <BR> * Description: <BR> * <BR> * This routine takes a BITMAPINOHEADER, and returns a handle to global <BR> * memory which can contain a DIB with that header. It also initializes <BR> * the header portion of the global memory. GetDIBits() is used to determine <BR> * the amount of room for the DIB's bits. The total amount of memory <BR> * needed = sizeof(BITMAPINFOHEADER) + size of color table + size of bits. <BR> * <BR> ************************************************************************/ <BR><BR>HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap) <BR>{ <BR> DWORD dwLen; <BR> HANDLE hDIB; <BR> HDC hDC; <BR> LPBITMAPINFOHEADER lpbi; <BR> HANDLE hTemp; <BR><BR> // Figure out the size needed to hold the BITMAPINFO structure <BR> // (which includes the BITMAPINFOHEADER and the color table). <BR><BR> dwLen = bi.biSize + PaletteSize((LPSTR) &bi); <BR> hDIB = GlobalAlloc(GHND,dwLen); <BR><BR> // Check that DIB handle is valid <BR><BR> if (!hDIB) <BR> return NULL; <BR><BR> // Set up the BITMAPINFOHEADER in the newly allocated global memory, <BR> // then call GetDIBits() with lpBits = NULL to have it fill in the <BR> // biSizeImage field for us. <BR><BR> lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); <BR> *lpbi = bi; <BR><BR> hDC = GetDC(NULL); <BR><BR> GetDIBits(hDC, hBitmap, 0, (UINT) bi.biHeight, NULL, (LPBITMAPINFO)lpbi, <BR> DIB_RGB_COLORS); <BR> ReleaseDC(NULL, hDC); <BR><BR> // If the driver did not fill in the biSizeImage field, <BR> // fill it in -- NOTE: this is a bug in the driver! <BR> <BR> if (lpbi->biSizeImage == 0) <BR> lpbi->biSizeImage = WIDTHBYTES((DWORD)lpbi->biWidth * <BR> lpbi->biBitCount) * lpbi->biHeight; <BR><BR> // Get the size of the memory block we need <BR><BR> dwLen = lpbi->biSize + PaletteSize((LPSTR) &bi) + lpbi->biSizeImage; <BR><BR> // Unlock the memory block <BR><BR> GlobalUnlock(hDIB); <BR><BR> // ReAlloc the buffer big enough to hold all the bits <BR><BR> if (hTemp = GlobalReAlloc(hDIB,dwLen,0)) <BR> return hTemp; <BR> else <BR> { <BR> // Else free memory block and return failure <BR><BR> GlobalFree(hDIB); <BR> return NULL; <BR> } <BR>} <BR><BR><BR>/************************************************************************* <BR> * <BR> * ChangeDIBFormat() <BR> * <BR> * Parameter: <BR> * <BR> * HDIB - handle to packed-DIB in memory <BR> * <BR> * WORD - desired bits per pixel <BR> * <BR> * DWORD - desired compression format <BR> * <BR> * Return Value: <BR> * <BR> * HDIB - handle to the new DIB if successful, else NULL <BR> * <BR> * Description: <BR> * <BR> * This function will convert the bits per pixel and/or the compression <BR> * format of the specified DIB. Note: If the conversion was unsuccessful, <BR> * we return NULL. The original DIB is left alone. Don't use code like the <BR> * following: <BR> * <BR> * hMyDIB = ChangeDIBFormat(hMyDIB, 8, BI_RLE4); <BR> * <BR> * The conversion will fail, but hMyDIB will now be NULL and the original <BR> * DIB will now hang around in memory. We could have returned the old <BR> * DIB, but we wanted to allow the programmer to check whether this <BR> * conversion succeeded or failed. <BR> * <BR> ************************************************************************/ <BR><BR>HDIB ChangeDIBFormat(HDIB hDIB, WORD wBitCount, DWORD dwCompression) <BR>{ <BR> HDC hDC; // Handle to DC <BR> HBITMAP hBitmap; // Handle to bitmap <BR> BITMAP Bitmap; // BITMAP data structure <BR> BITMAPINFOHEADER bi; // Bitmap info header <BR> LPBITMAPINFOHEADER lpbi; // Pointer to bitmap info <BR> HDIB hNewDIB = NULL; // Handle to new DIB <BR> HPALETTE hPal, hOldPal; // Handle to palette, prev pal <BR> WORD DIBBPP, NewBPP; // DIB bits per pixel, new bpp <BR> DWORD DIBComp, NewComp;// DIB compression, new compression <BR><BR> // Check for a valid DIB handle <BR><BR> if (!hDIB) <BR> return NULL; <BR><BR> // Get the old DIB's bits per pixel and compression format <BR><BR> lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); <BR> DIBBPP = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; <BR> DIBComp = ((LPBITMAPINFOHEADER)lpbi)->biCompression; <BR> GlobalUnlock(hDIB); <BR><BR> // Validate wBitCount and dwCompression <BR> // They must match correctly (i.e., BI_RLE4 and 4 BPP or <BR> // BI_RLE8 and 8BPP, etc.) or we return failure <BR> if (wBitCount == 0) <BR> { <BR> NewBPP = DIBBPP; <BR> if ((dwCompression == BI_RLE4 && NewBPP == 4) || <BR> (dwCompression == BI_RLE8 && NewBPP == 8) || <BR> (dwCompression == BI_RGB)) <BR> NewComp = dwCompression; <BR> else <BR> return NULL; <BR> } <BR> else if (wBitCount == 1 && dwCompression == BI_RGB) <BR> { <BR> NewBPP = wBitCount; <BR> NewComp = BI_RGB; <BR> } <BR> else if (wBitCount == 4) <BR> { <BR> NewBPP = wBitCount; <BR> if (dwCompression == BI_RGB || dwCompression == BI_RLE4) <BR> NewComp = dwCompression; <BR> else <BR> return NULL; <BR> } <BR> else if (wBitCount == 8) <BR> { <BR> NewBPP = wBitCount; <BR> if (dwCompression == BI_RGB || dwCompression == BI_RLE8) <BR> NewComp = dwCompression; <BR> else <BR> return NULL; <BR> } <BR> else if (wBitCount == 24 && dwCompression == BI_RGB) <BR> { <BR> NewBPP = wBitCount; <BR> NewComp = BI_RGB; <BR> } <BR> else <BR> return NULL; <BR><BR> // Save the old DIB's palette <BR><BR> hPal = CreateDIBPalette(hDIB); <BR> if (!hPal) <BR> return NULL; <BR><BR> // Convert old DIB to a bitmap <BR><BR> hBitmap = DIBToBitmap(hDIB, hPal); <BR> if (!hBitmap) <BR> { <BR> DeleteObject(hPal); <BR> return NULL; <BR> &nb
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -