home *** CD-ROM | disk | FTP | other *** search
/ Mastering MFC Development / MMD.ISO / labs / c12 / lab01 / baseline / dibpal.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-20  |  4.9 KB  |  193 lines

  1. // dibpal.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "dibpal.h"
  6.  
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char BASED_CODE THIS_FILE[] = __FILE__;
  10. #endif
  11.  
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CDIBPal
  14.  
  15. CDIBPal::CDIBPal()
  16. {
  17.     m_nSelectionIndex = 0;
  18.     m_bDraw3D = TRUE;
  19. }
  20.  
  21. CDIBPal::~CDIBPal()
  22. {
  23. }
  24.  
  25. // Create a palette from the color table in a DIB.
  26. BOOL CDIBPal::Create(CDIB* pDIB)
  27. {
  28.     DWORD dwColors = pDIB->GetNumClrEntries();
  29.     // Check to see whether the DIB has a color table.
  30.     if (!dwColors) 
  31.     {
  32.         TRACE("No color table");   
  33.         return FALSE;
  34.     }
  35.  
  36.     // Get a pointer to the RGB quads in the color table.
  37.     RGBQUAD* pRGB = pDIB->GetClrTabAddress();
  38.  
  39.     // Allocate a logical palette and fill it with the color table info.
  40.     LOGPALETTE* pPal = (LOGPALETTE*) malloc(sizeof(LOGPALETTE) 
  41.                      + dwColors * sizeof(PALETTEENTRY));
  42.     if (0 != pPal) 
  43.     {
  44.         TRACE("Out of memory for logical palette");
  45.         return FALSE;
  46.     }
  47.     pPal->palVersion = 0x300;              // Windows 3.0
  48.     pPal->palNumEntries = (WORD) dwColors; // Table size
  49.     for (DWORD dw=0; dw<dwColors; dw++) 
  50.     {
  51.         pPal->palPalEntry[dw].peRed = pRGB[dw].rgbRed;
  52.         pPal->palPalEntry[dw].peGreen = pRGB[dw].rgbGreen;
  53.         pPal->palPalEntry[dw].peBlue = pRGB[dw].rgbBlue;
  54.         pPal->palPalEntry[dw].peFlags = 0;
  55.     }
  56.     BOOL bResult = CreatePalette(pPal);
  57.     free(pPal);
  58.     return bResult;
  59. }
  60.  
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CDIBPal commands
  63.  
  64. int CDIBPal::GetNumColors()
  65. {
  66.     int nColors = 0;
  67.     if (!GetObject(sizeof(nColors), &nColors)) 
  68.     {
  69.         TRACE("Failed to get the number of colors in the palette");
  70.         return 0;
  71.     }
  72.     return nColors;
  73. }
  74.  
  75. void CDIBPal::SetSelectionIndex(int nPaletteIndex)
  76. {
  77.     int nColors = GetNumColors();
  78.     ASSERT(nPaletteIndex >= 0 && nPaletteIndex < 256);
  79.  
  80.     m_nSelectionIndex = nPaletteIndex;
  81. }
  82.  
  83. COLORREF CDIBPal::GetColorFromIndex(int nPaletteIndex)
  84. {
  85.     int nColors = GetNumColors();
  86.     ASSERT(nPaletteIndex >= 0 && nPaletteIndex < nColors);
  87.  
  88.     PALETTEENTRY pe[256];
  89.  
  90.     GetPaletteEntries(0, nColors, pe);
  91.     return RGB(pe[nPaletteIndex].peRed, pe[nPaletteIndex].peGreen,
  92.                 pe[nPaletteIndex].peBlue);
  93. }
  94.  
  95. /************************************************************************
  96. *    CDIBPal::Draw()
  97. *
  98. *    Draws the palette color table in a 16 x 16 grid
  99. *    Conditionally draws 3D and/or selection indicator.
  100. *
  101. ************************************************************************/
  102. void CDIBPal::Draw(    CDC* pDC, 
  103.                     const CRect& rcRect, 
  104.                     BOOL bShowSelection /*= FALSE*/,
  105.                     BOOL bBkgnd /*= FALSE*/)
  106. {
  107.     int nColors = GetNumColors();
  108.     CPalette* pOldPal = pDC->SelectPalette(this, bBkgnd);
  109.     pDC->RealizePalette();
  110.  
  111.     int i, j, top, left, bottom, right;
  112.     for (j=0, top=rcRect.top; j<16; j++, top=bottom) 
  113.     {
  114.         bottom = rcRect.top + ((j+1) * rcRect.Height() / 16 + 1);
  115.         for (i=0, left=rcRect.left; i<16; i++, left=right) 
  116.         {
  117.             right = rcRect.left + ((i+1) * rcRect.Width() / 16 + 1);
  118.             CBrush br;
  119.             if(nColors >= 0)
  120.             {
  121.                 br.CreateSolidBrush (PALETTEINDEX(j * 16 + i));
  122.             }
  123.             else
  124.             {
  125.                 br.CreateStockObject(LTGRAY_BRUSH);
  126.             }
  127.             CBrush* pOldBrush = pDC->SelectObject(&br);
  128.             
  129.             
  130.             //    Create a working rect
  131.             CRect    rcFill(left-1, top-1, right, bottom);
  132.  
  133.             //    Fill with Color
  134.             pDC->Rectangle(&rcFill);
  135.                 
  136.             //    Draw a 3D Frame
  137.             if(m_bDraw3D)
  138.             {
  139.                 rcFill.InflateRect(-1, -1);
  140.                 pDC->Draw3dRect(&rcFill, RGB(96,96,96), RGB(255,255,255));
  141.  
  142.                 rcFill.InflateRect(-1, -1);
  143.                 pDC->Draw3dRect(&rcFill, RGB(0,0,0), RGB(192,192,192));
  144.             }
  145.  
  146.             //    and selection rect if needed
  147.             if(bShowSelection && (m_nSelectionIndex == (j * 16 + i)))
  148.             {
  149.                 rcFill.InflateRect(-1, -1);
  150.                 pDC->Draw3dRect(&rcFill, RGB(255,0,0), RGB(255,0,0));
  151.             }
  152.  
  153.             if(pOldBrush)
  154.             {
  155.                 pDC->SelectObject(pOldBrush);
  156.             }
  157.             nColors--;
  158.         }
  159.     }
  160.     pDC->SelectPalette(pOldPal, FALSE);
  161. }
  162.  
  163. /************************************************************************
  164. *    CDIBPal::HitTest()
  165. *
  166. *    Determines which palette index whould be hit if a 16 x 16 grid
  167. *    of colors were drawn in the provided rect
  168. *
  169. ************************************************************************/
  170. int    CDIBPal::HitTest(const CRect& rcRect, CPoint pt)
  171. {
  172.     int i, j, top, left, bottom, right;
  173.     for (j=0, top=rcRect.top; j<16; j++, top=bottom) 
  174.     {
  175.         bottom = rcRect.top + ((j+1) * rcRect.Height() / 16 + 1);
  176.         for (i=0, left=rcRect.left; i<16; i++, left=right) 
  177.         {
  178.             right = rcRect.left + ((i+1) * rcRect.Width() / 16 + 1);
  179.  
  180.             //    Create a working rect
  181.             CRect    rcHit(left-1, top-1, right, bottom);
  182.  
  183.             if(rcHit.PtInRect(pt))
  184.             {
  185.                 //    Return Index
  186.                 return (j * 16 + i);
  187.             }
  188.         }
  189.     }
  190.     //    No Hits
  191.     return -1;
  192. }
  193.