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

📄 enbitmap.cpp

📁 If you are not using these features and wish to reduce the size
💻 CPP
📖 第 1 页 / 共 3 页
字号:
									else
										hRgn = h;
									pData->rdh.nCount = 0;
									SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
								}
							}
						}

						// Go to next row (remember, the bitmap is inverted vertically)
						p32 -= bm32.bmWidthBytes;
					}

					// Create or extend the region with the remaining rectangles
					HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
					if(hRgn)
					{
						CombineRgn(hRgn, hRgn, h, RGN_OR);
						::DeleteObject(h);
					}
					else
						hRgn = h;

					// Clean up
					GlobalFree(hData);
					SelectObject(hDC, holdBmp);
					DeleteDC(hDC);
				}

				::DeleteObject(SelectObject(hMemDC, holdBmp));
			}

			DeleteDC(hMemDC);
		}	
	}

	return hRgn;
}

BOOL CEnBitmap::Draw(CDC *pDC, LPRECT r)
{
	CDC dc;
	dc.CreateCompatibleDC( pDC );
	CBitmap * bmp = dc.SelectObject( this );	
	pDC->BitBlt( r->left, r->top, r->right - r->left, r->bottom - r->top, &dc, 0, 0 ,
		  SRCCOPY );

	dc.SelectObject( bmp );		
	return TRUE;
}

// TransparentBlt	- Copies a bitmap transparently onto the destination DC
// hdcDest		- Handle to destination device context 
// nXDest		- x-coordinate of destination rectangle's upper-left corner 
// nYDest		- y-coordinate of destination rectangle's upper-left corner 
// nWidth		- Width of destination rectangle 
// nHeight		- height of destination rectangle 
// hBitmap		- Handle of the source bitmap
// nXSrc		- x-coordinate of source rectangle's upper-left corner 
// nYSrc		- y-coordinate of source rectangle's upper-left corner 
// colorTransparent	- The transparent color
// hPal			- Logical palette to be used with bitmap. Can be NULL

void CEnBitmap::TransparentBlt(CDC &dc,CRect rc,UINT colorTransparent)
{
	CDC pDC;
	pDC.CreateCompatibleDC(&dc);	
	HBITMAP hOldBmp = (HBITMAP) ::SelectObject( pDC.m_hDC, m_hObject );
	
	::TransparentBlt(dc.GetSafeHdc(),rc.left ,rc.top ,rc.Width(),rc.Height(),pDC.GetSafeHdc()  ,0,0,GetWidth(),GetHeight(),colorTransparent);
	::SelectObject(pDC.m_hDC,hOldBmp);
	pDC.DeleteDC();

}



// DrawGreyScale    - Draws a bitmap in Grey scale
// pDC              - Pointer to target device context
// hDIB             - Handle of device-independent bitmap
//
void CEnBitmap::DrawGreyScale( CDC *pDC )
{
    CPalette pal;
    CPalette *pOldPalette = 0;

	HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();

	// allocate memory for extended image information
	BITMAPINFO &bmInfo= *(LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
	memset( &bmInfo, 0, sizeof(BITMAPINFO) + 8 );
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

	// get extended information about image (length, compression, length of color table if exist, ...)
	DWORD res = GetDIBits(pDC->GetSafeHdc() , hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS );
	// allocate memory for image data (colors)
	LPBYTE pBits = new BYTE[ bmInfo.bmiHeader.biSizeImage + 4 ];

	res = GetDIBits( pDC->GetSafeHdc(), hBmp, 0,  bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS );

    int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 
                1 << bmInfo.bmiHeader.biBitCount;
    
    int nWidth = bmInfo.bmiHeader.biWidth;
    int nHeight = bmInfo.bmiHeader.biHeight;
    
    // Compute the address of the bitmap bits
    LPVOID lpDIBBits;
    if( bmInfo.bmiHeader.biBitCount > 8 )
        lpDIBBits = (LPVOID)((LPDWORD)(pBits + 
            bmInfo.bmiHeader.biClrUsed) + 
            ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
    else
        lpDIBBits = (LPVOID)(pBits + nColors);
    
    // Create the palette if needed
    if( pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE && nColors <= 256 )
    {
        // The device supports a palette and bitmap has color table
        
        // Allocate memory for a palette
        UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
        LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

        pLP->palVersion = 0x300;
        pLP->palNumEntries = nColors;
        
        for( int i=0; i < nColors; i++)
        {
            int nGrey = Grey( bmInfo.bmiColors[i].rgbRed, bmInfo.bmiColors[i].rgbGreen,
                bmInfo.bmiColors[i].rgbBlue );
            pLP->palPalEntry[i].peRed = nGrey;
            pLP->palPalEntry[i].peGreen = nGrey;
            pLP->palPalEntry[i].peBlue = nGrey;
            pLP->palPalEntry[i].peFlags = 0;
        }
        
        pal.CreatePalette( pLP );
        
        delete[] pLP;

        // Select the palette
        pOldPalette = pDC->SelectPalette(&pal, FALSE);
        pDC->RealizePalette();
    }
    else
    {
        // Modify the bitmaps pixels directly
        // Note : This ends up changing the DIB. If that is not acceptable then
        // copy the DIB and then change the copy rather than the original
        if ( bmInfo.bmiHeader.biBitCount == 24 ||  bmInfo.bmiHeader.biBitCount == 32)
        {
            BYTE *dst=(BYTE*)lpDIBBits;
            int Size=nWidth*nHeight;

            while ( Size-- )
            {
                int nGrey = Grey( dst[2], dst[1], dst[0] );

                dst[0]=(BYTE)nGrey;
                dst[1]=(BYTE)nGrey;
                dst[2]=(BYTE)nGrey;
                dst+=4;
            }
        }
        else if ( bmInfo.bmiHeader.biBitCount == 16 )
        {
            WORD *dst=(WORD*)lpDIBBits;
            int Size=nWidth*nHeight;

            while ( Size-- )
            {
                BYTE b = (BYTE)((*dst)&(0x1F));
                BYTE g = (BYTE)(((*dst)>>5)&(0x1F));
                BYTE r = (BYTE)(((*dst)>>10)&(0x1F));

                int nGrey = Grey( r, g, b );

                *dst++ = ((WORD)(((BYTE)(nGrey)|((WORD)((BYTE)(nGrey))<<5))|(((DWORD)(BYTE)(nGrey))<<10)));
            }
        }
    }

    // Draw the image 
    ::SetDIBitsToDevice(pDC->m_hDC,    // hDC
        0,                             // XDest
        0,                             // YDest
        nWidth,                        // nDestWidth
        nHeight,                       // nDestHeight
        0,                             // XSrc
        0,                             // YSrc
        0,                             // nStartScan
        nHeight,                       // nNumScans
        lpDIBBits,                     // lpBits
        &bmInfo,            // lpBitsInfo
        DIB_RGB_COLORS);               // wUsage
    
    
    if ( pOldPalette )
        pDC->SelectPalette(pOldPalette, FALSE);
}

//
//      DitherBlt :     Draw a bitmap dithered (3D grayed effect like disabled buttons in toolbars) into a destination DC
//      Author :        Jean-Edouard Lachand-Robert (iamwired@geocities.com), June 1997.
//
//      hdcDest :       destination DC
//      nXDest :        x coordinate of the upper left corner of the destination rectangle into the DC
//      nYDest :        y coordinate of the upper left corner of the destination rectangle into the DC
//      nWidth :        width of the destination rectangle into the DC
//      nHeight :       height of the destination rectangle into the DC
//      hbm :           the bitmap to draw (as a part or as a whole)
//      nXSrc :         x coordinates of the upper left corner of the source rectangle into the bitmap
//      nYSrc :         y coordinates of the upper left corner of the source rectangle into the bitmap
//
void CEnBitmap::DitherBlt (HDC hdcDest, int nXDest, int nYDest, int nWidth, 
				int nHeight, HBITMAP hbm, int nXSrc, int nYSrc)
{
	ASSERT(hdcDest && hbm);
	ASSERT(nWidth > 0 && nHeight > 0);
	
	// Create a generic DC for all BitBlts
	HDC hDC = CreateCompatibleDC(hdcDest);
	ASSERT(hDC);
	
	if (hDC)
	{
		// Create a DC for the monochrome DIB section
		HDC bwDC = CreateCompatibleDC(hDC);
		ASSERT(bwDC);
		
		if (bwDC)
		{
			// Create the monochrome DIB section with a black and white palette
			struct {
				BITMAPINFOHEADER bmiHeader; 
				RGBQUAD 		 bmiColors[2]; 
			} RGBBWBITMAPINFO = {
				
				{		// a BITMAPINFOHEADER
					sizeof(BITMAPINFOHEADER),	// biSize 
						nWidth, 				// biWidth; 
						nHeight,				// biHeight; 
						1,						// biPlanes; 
						1,						// biBitCount 
						BI_RGB, 				// biCompression; 
						0,						// biSizeImage; 
						0,						// biXPelsPerMeter; 
						0,						// biYPelsPerMeter; 
						0,						// biClrUsed; 
						0						// biClrImportant; 
				},
				
				{
					{ 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 }
					} 
			};
			VOID *pbitsBW;
			HBITMAP hbmBW = CreateDIBSection(bwDC,
				(LPBITMAPINFO)&RGBBWBITMAPINFO, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
			ASSERT(hbmBW);
			
			if (hbmBW)
			{
				// Attach the monochrome DIB section and the bitmap to the DCs
				SelectObject(bwDC, hbmBW);
				SelectObject(hDC, hbm);
				
				// BitBlt the bitmap into the monochrome DIB section
				BitBlt(bwDC, 0, 0, nWidth, nHeight, hDC, nXSrc, nYSrc, SRCCOPY);
				
				// Paint the destination rectangle in gray
				FillRect(hdcDest, CRect(nXDest, nYDest, nXDest + nWidth, nYDest +
					nHeight), GetSysColorBrush(COLOR_3DFACE));
				
				// BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT bits in the destination DC
				// The magic ROP comes from the Charles Petzold's book
				HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
				HBRUSH oldBrush = (HBRUSH)SelectObject(hdcDest, hb);
				BitBlt(hdcDest, nXDest + 1, nYDest + 1, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
				
				// BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW bits in the destination DC
				hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
				::DeleteObject(SelectObject(hdcDest, hb));
				BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
				::DeleteObject(SelectObject(hdcDest, oldBrush));
			}
			
			VERIFY(DeleteDC(bwDC));
		}
		
		VERIFY(DeleteDC(hDC));
	}
}

// CreateReservedPalette	- Create a palette using the PC_RESERVED flag
//				  Limit the colors to 236 colors
// Returns			- Handle to a palette object
// hDIB				- Handle to a device-independent bitmap
//
HPALETTE CEnBitmap::CreateReservedPalette(CDC *pDC)
{
	HPALETTE hPal = NULL;    // handle to a palette
	
	HBITMAP hBmp = (HBITMAP)this->GetSafeHandle();
	// get image properties
	//BITMAP bmp = { 0 };
	//::GetObject( hBmp, sizeof(BITMAP), &bmp );
	// allocate memory for extended image information
	BITMAPINFO &bmInfo= *(LPBITMAPINFO) new BYTE[ sizeof(BITMAPINFO) + 8 ];
	memset( &bmInfo, 0, sizeof(BITMAPINFO) + 8 );
	bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

	// get extended information about image (length, compression, length of color table if exist, ...)
	DWORD res = GetDIBits(pDC->GetSafeHdc() , hBmp, 0, GetHeight(), 0, &bmInfo, DIB_RGB_COLORS );
	// allocate memory for image data (colors)
	LPBYTE pBits = new BYTE[ bmInfo.bmiHeader.biSizeImage + 4 ];

	res = GetDIBits( pDC->GetSafeHdc(), hBmp, 0,  bmInfo.bmiHeader.biHeight, pBits, &bmInfo, DIB_RGB_COLORS );

    
    int nWidth = bmInfo.bmiHeader.biWidth;
    int nHeight = bmInfo.bmiHeader.biHeight;
 
	int nColors = bmInfo.bmiHeader.biClrUsed ? bmInfo.bmiHeader.biClrUsed : 
					1 << bmInfo.bmiHeader.biBitCount;

	if( nColors > 256 ) 
		return NULL;		// No Palette   

	
	//allocate memory block for logical palette
	UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
	LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

	// Initialize the palette version
	pLP->palVersion = 0x300;

	// If it is a 256 color DIB, then let's find the most used 236 colors 
	// and make a palette out of those colors
	if (nColors > 236)
	{
		typedef struct _tagBESTCOLORS
		{
			DWORD dwColorCnt;	//Count of how many times a color is used
			BOOL  bDontUse;	//Should we use this color?
		} BESTCOLORS;
		
		BESTCOLORS bc[256];
		BYTE dwLeastUsed[20];		// Least used color indices
		LPSTR lpBits;			// pointer to D.I. bits of a DIB
		int   nWidth, nHeight, nBytesPerLine, cx, cy;   
		
		::ZeroMemory( bc, 256*sizeof(BESTCOLORS));
		
		lpBits = (LPSTR)(pBits + nColors);
		nWidth = bmInfo.bmiHeader.biWidth;
		nHeight = bmInfo.bmiHeader.biHeight;
		nBytesPerLine = ((((bmInfo.bmiHeader.biWidth * 
					bmInfo.bmiHeader.biBitCount) + 31) & ~31) / 8);
		
		// Traverse through all of the bits in the bitmap and place the 
		// color count of each color in the BESTCOLORS array
		for (cy = 0; cy < nHeight; cy++)
			for (cx = 0; cx < nWidth; cx++)
				bc[*(LPBYTE)(lpBits+cy*nBytesPerLine+cx)].dwColorCnt++;
			
		// Let's arbitrarily place the first few colors in the "Least Used" list.
		int nReject = nColors - 236;
		for (cx=0; cx < nReject; cx++)
		{
			bc[cx].bDontUse = TRUE;
			dwLeastUsed[cx] = cx;
		}
		
		// Now, let's traverse through all of the colors and 
		// sort out the least used
		for (cx=0; cx < nColors; cx++)
		{
			cy = 0;
			while ((!(bc[cx].bDontUse)) && cy < nReject)
			{
				if (bc[cx].dwColorCnt < bc[dwLeastUsed[cy]].dwColorCnt) 
				{     
					bc[dwLeastUsed[cy]].bDontUse = FALSE;
					dwLeastUsed[cy] = cx;
					bc[cx].bDontUse = TRUE;
				}
				cy++;
			}
		}
		
		// We want only 236 colors, so that the 20 system colors 
		// are left untouched
		pLP->palNumEntries = 236;
		
		cx = 0;
		for(int i = 0; i < nColors; i++)
		{
			// Should we use this color?
			if (!((bc[i].bDontUse)))
			{  
				pLP->palPalEntry[cx].peRed = bmInfo.bmiColors[i].rgbRed;
				pLP->palPalEntry[cx].peGreen = 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -