⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dib.c

📁 WinCVS 源码,流行的CVS客户端源码程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************
/* 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 + -