home *** CD-ROM | disk | FTP | other *** search
- /*
- * CStatBmp.cpp
- * $Header: /bcsample/BUGBNCHX/CSTATBMP.CPP 1 5/28/96 1:11p Dave $
- *
- * Description:
- * The routines that implement a Bitmap display control. Just
- * subclass an existing static control and a bitmap will be displayed.
- * The name assigned to the control is the bitmap that will be loaded.
- *
- * Notes:
- * <implementation notes go here>
- *
- ***********************************************************************
- *
- * Nu-Mega Technologies, Inc.
- * P.O. Box 7780
- * Nashua, NH 03060
- *
- * (c) Copyright 1994, 1995 Nu-Mega Technologies, Inc.
- * ALL RIGHTS RESERVED.
- *
- ***********************************************************************
- *
- **********************************************************************/
- #include "stdafx.h"
- #include "BugBench.h"
- #include "CStatBmp.h"
-
-
- /*----------------------------------------------------------------------
- The declarations and constants for the DIB drawing functions. The
- functions themselves come from the treasure trove of VC++ samples.
- ----------------------------------------------------------------------*/
-
- // DIB constants
- #define PALVERSION 0x300
-
- // DIB Macros
-
- #define IS_WIN30_DIB(lpbi) ( ( * ( LPDWORD )( lpbi ) ) == \
- sizeof ( BITMAPINFOHEADER ) )
-
- // WIDTHBYTES performs DWORD-aligning of DIB scanlines. The "bits"
- // parameter is the bit count for the scanline (biWidth * biBitCount),
- // and this macro returns the number of DWORD-aligned bytes needed
- // to hold those bits.
-
- #define WIDTHBYTES(bits) ( ( ( bits ) + 31 ) / 32 * 4 )
-
- // Function declarations.
- BOOL WINAPI PaintDIB ( HDC hDC ,
- LPRECT lpDCRect ,
- LPSTR lpDIBHdr ,
- LPRECT lpDIBRect ,
- HPALETTE hpalIn ) ;
- BOOL WINAPI CreateDIBPalette ( LPSTR lpbi , HPALETTE* hPal ) ;
- DWORD WINAPI DIBWidth ( LPSTR lpDIB ) ;
- DWORD WINAPI DIBHeight ( LPSTR lpDIB ) ;
- WORD WINAPI PaletteSize ( LPSTR lpbi ) ;
- WORD WINAPI DIBNumColors ( LPSTR lpbi ) ;
-
- #ifdef STRICT
- WNDPROC m_lpPrevWndProc ;
- #else
- FARPROC m_lpPrevWndProc ;
- #endif
-
-
- BOOL StaticBitmap_OnQueryNewPalette ( HWND hWnd ) ;
- void StaticBitmap_OnPaint ( HWND hWnd ) ;
-
- HRSRC m_hRSC = NULL ;
- LPTSTR m_szLockedRSC ;
-
- RECT m_rectDIB ;
- RECT m_rectHDC ;
-
- HPALETTE m_palette ;
-
- void StaticBitmap_CleanUp ( HWND hStatic )
- {
- ASSERT ( IsWindow ( hStatic ) ) ;
-
- // Unlock the resource and free the palette.
- if ( NULL != m_hRSC )
- {
- // This isn't necessary anymore under
- // 32-bit development.
- UnlockResource ( m_hRSC ) ;
- FreeResource ( m_hRSC ) ;
- }
-
- if ( NULL != m_palette )
- DeleteObject ( m_palette ) ;
- }
-
- ////////////////////////////////////////////////////////////////////////
- // The message pump for the StaticBitmap control.
- ////////////////////////////////////////////////////////////////////////
- LRESULT CALLBACK StaticBitmap_WndProc ( HWND hStatic ,
- UINT uMsg ,
- WPARAM wParam ,
- LPARAM lParam )
- {
- switch ( uMsg )
- {
- HANDLE_MSG ( hStatic , WM_PAINT , StaticBitmap_OnPaint ) ;
- HANDLE_MSG ( hStatic , WM_QUERYNEWPALETTE , StaticBitmap_OnQueryNewPalette ) ;
-
- default :
- return ( CallWindowProc( m_lpPrevWndProc , hStatic , uMsg , wParam , lParam ) ) ;
- break ;
- }
-
- return ( LRESULT ) 0 ;
- }
-
- ////////////////////////////////////////////////////////////////////////
- // The message handlers for the StaticBitmap.
- ////////////////////////////////////////////////////////////////////////
- BOOL StaticBitmap_Init ( HWND hwndStatic )
- {
- TCHAR szBuff[ MAX_PATH ] ;
-
- // Get the name of the window, because this will be the name of
- // the bitmap we will load.
- GetWindowText ( hwndStatic , szBuff , sizeof ( szBuff ) ) ;
-
- ASSERT ( _T ( '\0' ) != szBuff[ 0 ] ) ;
- if ( _T ( '\0' ) == szBuff[ 0 ] )
- return ( FALSE ) ;
-
- // Load the resource.
- HRSRC hRSRC = ::FindResource ( GetModuleHandle ( NULL ) ,
- szBuff ,
- RT_BITMAP ) ;
-
- m_hRSC = (HRSRC)::LoadResource ( 0 , hRSRC ) ;
- ASSERT ( NULL != m_hRSC ) ;
- if ( NULL == m_hRSC )
- return ( FALSE ) ;
-
- m_szLockedRSC = (LPSTR)::LockResource ( m_hRSC ) ;
-
- // Get the rect of the bitmap and store it so that we don't have
- // to calculate it each time.
- BITMAP m_bmInfo ;
- memcpy ( &m_bmInfo, m_szLockedRSC , sizeof ( BITMAP ) ) ;
-
- m_rectDIB.top = 0 ;
- m_rectDIB.left = 0 ;
- m_rectDIB.right = m_bmInfo.bmWidth ;
- m_rectDIB.bottom = m_bmInfo.bmHeight ;
-
-
- // Get the client rect and calculate the center area.
- GetClientRect ( hwndStatic , &m_rectHDC ) ;
-
- LONG lHeightDiff = 0 ;
- LONG lWidthDiff = 0 ;
- if ( RECTWIDTH ( &m_rectDIB ) < RECTWIDTH ( &m_rectHDC ) )
- lWidthDiff = ( RECTWIDTH ( &m_rectHDC ) - RECTWIDTH ( &m_rectDIB ) ) / 2 ;
- if ( RECTHEIGHT ( &m_rectDIB ) < RECTHEIGHT ( &m_rectHDC ) )
- lHeightDiff = ( RECTHEIGHT ( &m_rectHDC ) - RECTHEIGHT ( &m_rectDIB ) ) / 2 ;
-
- // Decrease the rect of the HDC we will paint on accordingly.
- m_rectHDC.top += lHeightDiff ;
- m_rectHDC.bottom -= lHeightDiff ;
- m_rectHDC.left += lWidthDiff ;
- m_rectHDC.right -= lWidthDiff ;
-
- // Create the pallette.
- ::CreateDIBPalette ( m_szLockedRSC , &m_palette ) ;
-
- #ifdef STRICT
- m_lpPrevWndProc = ( WNDPROC ) SetWindowLong ( hwndStatic , GWL_WNDPROC, ( LONG ) StaticBitmap_WndProc ) ;
- #else
- m_lpPrevWndProc = ( FARPROC ) SetWindowLong ( hwndStatic , GWL_WNDPROC, ( LONG ) StaticBitmap_WndProc ) ;
- #endif
-
- return ( TRUE ) ;
- }
-
-
-
- UINT StaticBitmap_RealizeDIBPalette ( HWND hStatic )
- {
- // Get the device context for this window.
- HDC hDC = GetDC ( hStatic ) ;
- ASSERT ( NULL != hDC ) ;
- if ( NULL == hDC )
- return ( 0 ) ;
-
- // Make the DIB palette current as the foreground palette.
- HPALETTE hOldPal = ::SelectPalette ( hDC , m_palette , FALSE ) ;
- // Realize it.
- UINT uiRet = RealizePalette ( hDC ) ;
- // Make the old palette the background palette.
- ::SelectPalette ( hDC , hOldPal , TRUE ) ;
-
- // Get rid of the device context.
- ::ReleaseDC ( hStatic , hDC ) ;
-
- // If the realization changed, then we need to repaint the DIB.
- if ( uiRet > 0 )
- {
- InvalidateRect ( hStatic , NULL , TRUE ) ;
- }
- return ( uiRet ) ;
- }
-
- BOOL StaticBitmap_OnQueryNewPalette ( HWND hWnd )
- {
- return ( 0 != StaticBitmap_RealizeDIBPalette ( hWnd ) ) ;
- }
-
- void StaticBitmap_OnPaint ( HWND hWnd )
- {
- HDC hDC = NULL ;
- PAINTSTRUCT ps ;
-
- hDC = ::BeginPaint ( hWnd , &ps ) ;
- ASSERT ( NULL != hDC ) ;
- ASSERT ( NULL != m_hRSC ) ;
-
- ::PaintDIB ( hDC ,
- &m_rectHDC ,
- m_szLockedRSC ,
- &m_rectDIB ,
- m_palette ) ;
-
- ::EndPaint ( hWnd , &ps ) ;
- }
-
-
- /***********************************************************************
- *
- * PaintDIB()
- *
- * Return Value:
- *
- * BOOL - TRUE if DIB was drawn, FALSE otherwise
- *
- * Description:
- * Painting routine for a DIB. Calls StretchDIBits() or
- * SetDIBitsToDevice() to paint the DIB. The DIB is
- * output to the specified DC, at the coordinates given
- * in lpDCRect. The area of the DIB to be output is
- * given by lpDIBRect.
- *
- **********************************************************************/
- BOOL WINAPI PaintDIB ( HDC hDC ,
- LPRECT lpDCRect ,
- LPSTR lpDIBHdr ,
- LPRECT lpDIBRect ,
- HPALETTE hpalIn )
- {
- LPSTR lpDIBBits ; // Pointer to DIB bits
- BOOL bSuccess = FALSE ; // Success/fail flag
- HPALETTE hPal = NULL ; // Our DIB's palette
- HPALETTE hOldPal = NULL ; // Previous palette
-
- // Get a pointer to the beginning of the bit buffer.
-
- lpDIBBits = ( lpDIBHdr + *(LPDWORD)lpDIBHdr +
- ::PaletteSize ( lpDIBHdr ) ) ;
-
- // Get the DIB's palette, then select it into DC
- if ( NULL != hpalIn )
- {
- hPal = (HPALETTE) hpalIn ;
-
- // Select as background since we have
- // already realized in foreground if needed
- hOldPal = ::SelectPalette ( hDC , hPal , FALSE ) ;
- ::RealizePalette ( hDC ) ;
- }
-
- // Make sure to use the stretching mode best for color pictures.
- ::SetStretchBltMode ( hDC , COLORONCOLOR ) ;
-
- // Determine whether to call StretchDIBits() or SetDIBitsToDevice().
- if ( ( RECTWIDTH ( lpDCRect ) == RECTWIDTH ( lpDIBRect ) ) &&
- ( RECTHEIGHT ( lpDCRect ) == RECTHEIGHT ( lpDIBRect ) ) )
- {
-
- bSuccess =
- ::SetDIBitsToDevice ( hDC , // hDC
- lpDCRect->left , // DestX
- lpDCRect->top , // DestY
- RECTWIDTH ( lpDCRect ) , // nDestWidth
- RECTHEIGHT( lpDCRect ) , // nDestHeight
- lpDIBRect->left , // SrcX
- // SrcY
- (int)DIBHeight(lpDIBHdr) -
- lpDIBRect->top - RECTHEIGHT(lpDIBRect),
- 0 , // nStartScan
- (WORD)DIBHeight ( lpDIBHdr ),// nNumScans
- lpDIBBits , // lpBits
- (LPBITMAPINFO)lpDIBHdr , // lpBitsInfo
- DIB_RGB_COLORS ) ; // wUsage
- }
- else
- {
- bSuccess =
- ::StretchDIBits ( hDC , // hDC
- lpDCRect->left , // DestX
- lpDCRect->top , // DestY
- RECTWIDTH ( lpDCRect ) , // nDestWidth
- RECTHEIGHT ( lpDCRect ) , // nDestHeight
- lpDIBRect->left , // SrcX
- lpDIBRect->top , // SrcY
- RECTWIDTH ( lpDIBRect ) , // wSrcWidth
- RECTHEIGHT ( lpDIBRect ), // wSrcHeight
- lpDIBBits , // lpBits
- (LPBITMAPINFO)lpDIBHdr , // lpBitsInfo
- DIB_RGB_COLORS , // wUsage
- SRCCOPY ) ; // dwROP
- }
-
- // Reselect old palette.
- if ( NULL != hOldPal )
- {
- ::SelectPalette ( hDC , hOldPal , TRUE ) ;
- }
- return ( bSuccess ) ;
- }
-
- /***********************************************************************
- *
- * CreateDIBPalette()
- *
- * This function creates a palette from a DIB by allocating memory for
- * the logical palette, reading and storing the colors from the DIB's
- * color table into the logical palette, creating a palette from this
- * logical palette, and then returning the palette's handle. This allows
- * the DIB to be displayed using the best possible colors (important for
- * DIBs with 256 or more colors).
- *
- **********************************************************************/
- BOOL WINAPI CreateDIBPalette ( LPSTR lpbi , HPALETTE* hPal )
- {
- // Pointer to a logical palette
- LPLOGPALETTE lpPal ;
- // Loop index
- int i ;
- // Number of colors in color table
- WORD wNumColors ;
- // Pointer to BITMAPINFO structure (Win3.0)
- LPBITMAPINFO lpbmi ;
- // Pointer to BITMAPCOREINFO structure (old)
- LPBITMAPCOREINFO lpbmc ;
- // Flag which signifies whether this is a Win3.0 DIB
- BOOL bWinStyleDIB ;
- BOOL bResult = FALSE;
-
- // Get pointer to BITMAPINFO (Win 3.0)
- lpbmi = (LPBITMAPINFO)lpbi ;
-
- // Get pointer to BITMAPCOREINFO (old 1.x)
- lpbmc = (LPBITMAPCOREINFO)lpbi ;
-
- // Get the number of colors in the DIB
- wNumColors = ::DIBNumColors ( lpbi ) ;
-
- if ( 0 != wNumColors )
- {
- // Allocate memory block for logical palette.
- lpPal =
- (LPLOGPALETTE) new char [ sizeof ( LOGPALETTE ) +
- ( sizeof(PALETTEENTRY) * wNumColors ) ] ;
-
- // If not enough memory, clean up and return NULL.
- if ( 0 == lpPal )
- {
- return ( FALSE ) ;
- }
-
- // Set version and number of palette entries.
- lpPal->palVersion = PALVERSION ;
- lpPal->palNumEntries = (WORD)wNumColors ;
-
- // Is this a Win 3.0 DIB?
- bWinStyleDIB = IS_WIN30_DIB( lpbi ) ;
- for ( i = 0 ; i < (int)wNumColors ; i++ )
- {
- if ( bWinStyleDIB )
- {
- lpPal->palPalEntry[ i ].peRed =
- lpbmi->bmiColors[ i ].rgbRed ;
- lpPal->palPalEntry[ i ].peGreen =
- lpbmi->bmiColors[ i ].rgbGreen ;
- lpPal->palPalEntry[ i ].peBlue =
- lpbmi->bmiColors[ i ].rgbBlue ;
- lpPal->palPalEntry[ i ].peFlags = 0 ;
- }
- else
- {
- lpPal->palPalEntry[ i ].peRed =
- lpbmc->bmciColors[ i ].rgbtRed ;
- lpPal->palPalEntry[ i ].peGreen =
- lpbmc->bmciColors[ i ].rgbtGreen ;
- lpPal->palPalEntry[ i ].peBlue =
- lpbmc->bmciColors[ i ].rgbtBlue ;
- lpPal->palPalEntry[ i ].peFlags = 0 ;
- }
- }
-
- // Create the palette and get handle to it.
- *hPal = ::CreatePalette ( lpPal ) ;
- if ( NULL != hPal )
- bResult = TRUE ;
-
- delete [] lpPal ;
- }
- return ( bResult ) ;
- }
-
- /***********************************************************************
- *
- * DIBWidth()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * DWORD - width of the DIB
- *
- * Description:
- *
- * This function gets the width of the DIB from the BITMAPINFOHEADER
- * width field if it is a Windows 3.0-style DIB or from the
- * BITMAPCOREHEADER width field if it is an other-style DIB.
- *
- **********************************************************************/
- DWORD WINAPI DIBWidth ( LPSTR lpDIB )
- {
- LPBITMAPINFOHEADER lpbmi ; // Pointer to a Win 3.0-style DIB
- LPBITMAPCOREHEADER lpbmc ; // Pointer to an other-style DIB
-
- // Point to the header (whether Win 3.0 and old)
-
- lpbmi = (LPBITMAPINFOHEADER)lpDIB ;
- lpbmc = (LPBITMAPCOREHEADER)lpDIB ;
-
- // Return the DIB width if it is a Win 3.0 DIB.
- if ( IS_WIN30_DIB ( lpDIB ) )
- return ( lpbmi->biWidth ) ;
- else // It is an other-style DIB, so return its width.
- return ( (DWORD)lpbmc->bcWidth ) ;
- }
-
- /***********************************************************************
- *
- * DIBHeight()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * DWORD - height of the DIB
- *
- * Description:
- *
- * This function gets the height of the DIB from the BITMAPINFOHEADER
- * height field if it is a Windows 3.0-style DIB or from the
- * BITMAPCOREHEADER height field if it is an other-style DIB.
- *
- **********************************************************************/
- DWORD WINAPI DIBHeight ( LPSTR lpDIB )
- {
- LPBITMAPINFOHEADER lpbmi ; // Pointer to a Win 3.0-style DIB.
- LPBITMAPCOREHEADER lpbmc ; // Pointer to an other-style DIB.
-
- // Point to the header (whether old or Win 3.0.
-
- lpbmi = (LPBITMAPINFOHEADER)lpDIB ;
- lpbmc = (LPBITMAPCOREHEADER)lpDIB ;
-
- // Return the DIB height if it is a Win 3.0 DIB.
- if ( IS_WIN30_DIB ( lpDIB ) )
- return ( lpbmi->biHeight ) ;
- else // It is an other-style DIB, so return its height.
- return ( (DWORD)lpbmc->bcHeight ) ;
- }
-
-
- /***********************************************************************
- *
- * PaletteSize()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * WORD - size of the color palette of the DIB
- *
- * Description:
- *
- * This function gets the size required to store the DIB's palette by
- * multiplying the number of colors by the size of an RGBQUAD (for a
- * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other-
- * style DIB).
- *
- **********************************************************************/
- WORD WINAPI PaletteSize ( LPSTR lpbi )
- {
- // Calculate the size required by the palette.
- if ( IS_WIN30_DIB ( lpbi ) )
- return ( (WORD)( ::DIBNumColors ( lpbi ) * sizeof ( RGBQUAD ) ) ) ;
- else
- return ( (WORD)( ::DIBNumColors ( lpbi ) * sizeof ( RGBTRIPLE ) ));
- }
-
-
- /***********************************************************************
- *
- * DIBNumColors()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * WORD - number of colors in the color table
- *
- * Description:
- *
- * This function calculates the number of colors in the DIB's color
- * table by finding the bits per pixel for the DIB (whether Win3.0 or
- * other-style DIB). If bits per pixel is 1: colors=2, if 4: colors=16,
- * if 8: colors=256, if 24, no colors in color table.
- *
- **********************************************************************/
- WORD WINAPI DIBNumColors ( LPSTR lpbi )
- {
- WORD wBitCount ; // DIB bit count
-
- // If this is a Windows-style DIB, the number of colors in the
- // color table can be less than the number of bits per pixel
- // allows for (i.e. lpbi->biClrUsed can be set to some value).
- // If this is the case, return the appropriate value.
-
- if ( IS_WIN30_DIB ( lpbi ) )
- {
- DWORD dwClrUsed ;
-
- dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed ;
- if ( 0 != dwClrUsed )
- return ( (WORD)dwClrUsed ) ;
- }
-
- // Calculate the number of colors in the color table based on
- // the number of bits per pixel for the DIB.
- if ( IS_WIN30_DIB ( lpbi ) )
- wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount ;
- else
- wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount ;
-
- // Return number of colors based on bits per pixel.
- switch ( wBitCount )
- {
- case 1 :
- return ( 2 ) ;
- case 4 :
- return ( 16 ) ;
- case 8 :
- return ( 256 ) ;
- default :
- return ( 0 ) ;
- }
- }
-
-
-
-