Solved

how to use DIB_PAL_COLORS in CreateDIBSection() ?

Posted on 1998-12-02
7
1,811 Views
Last Modified: 2013-11-20
can anybody tell me how to use DIB_PAL_COLORS in CreateDIBSection ? I've tried lot of times, it just doesn't work.
Below is the code i used to create a DIB bitmap with using DIB_PAL_COLORS
//HWND hWnd - hWnd of window own the bitmap
//RGB_TIGA - rgb struct for palette entries
//HBITMAP hBmp -bmp handle to receive the newly created bmp
BOOL CreateTileBitmap(HWND hWnd,RGB_TIGA pal[4],HBITMAP& hBmp)
{
LPBITMAPINFO lpbi;
lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER)  +
     (COLOR_INDEX * sizeof(RGBQUAD))];

lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biWidth = 8;
lpbi->bmiHeader.biHeight = 8;
lpbi->bmiHeader.biPlanes = 1;
lpbi->bmiHeader.biBitCount = 8;
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biSizeImage = 0;
lpbi->bmiHeader.biXPelsPerMeter = 0;
lpbi->bmiHeader.biYPelsPerMeter = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biClrImportant = 0;

for (int i=0;i<COLOR_INDEX;i++)
{
   lpbi->bmiColors[i].rgbRed      = pal[i].bRed<<3;
   lpbi->bmiColors[i].rgbGreen = pal[i].bGreen<<3;
   lpbi->bmiColors[i].rgbBlue      = pal[i].bBlue<<3;
   lpbi->bmiColors[i].rgbReserved =PC_RESERVED;
}

HDC hScreenDC = ::GetDC(hWnd);
hBmp =CreateDIBSection(hScreenDC,lpbi,
                        DIB_PAL_COLORS,
                        NULL,NULL,0);
      ::ReleaseDC(hWnd,hScreenDC);
            
      delete [](BYTE *)lpbi;
return TRUE;
}
is there anything wrong with my code ? is not, then after i've created the bitmap, i use the function below to create a logical palette :

HPALETTE CreatePalette(RGB_TIGA pal[4])
{
    HPALETTE hPal;
    LOGPALETTE* lpPal =(LOGPALETTE*) new BYTE[sizeof(LOGPALETTE) + (COLOR_INDEX*(sizeof(PALETTEENTRY)))];
    lpPal->palVersion = 0x300;
    lpPal->palNumEntries = 4;
            
    for (int i=0;i<COLOR_INDEX;i++)
    {
      lpPal->palPalEntry[i].peRed      = pal[i].bRed;
      lpPal->palPalEntry[i].peGreen      = pal[i].bGreen;
      lpPal->palPalEntry[i].peBlue      = pal[i].bBlue;
      lpPal->palPalEntry[i].peFlags      = PC_RESERVED;
    }
    hPal  = ::CreatePalette(lpPal);
    delete [] (BYTE*) lpPal;
    return hPal;
}
anything wrong with this ? if no, ok then, now i've created both bitmap and my logical palette, then when i want to
blit the bitmap to the dc, i have to select my desired logical palette into dc right ? is it as below :
  HDC dcmem;
  CDC *pDC = GetDC();
  dcmem = CreateCompatibleDC(pDC->m_hDC);
  HPALETTE oldPal = (HPALETTE) SelectPalette(pDC->m_hDC,&m_hMyPal,FALSE);
  HBITMAP old = (HBITMAP)SelectObject(dcmem,m_hMyBmp);
  StretchBlt(pDC->m_hDC,0,0,8,8,
           dcmem,0,0,8,8,SRCCOPY);
   SelectPalette(pDC->m_hDC,&oldPal,FALSE);
   SelectObject(dcmem,old);
   ::DeleteDC(dcmem);
   ReleaseDC(pDC);
...anything wrong with these, why the bmp get drawn in blank ? did i miss out something ? If i use DIB_RGB_COLORS, it
would be fined, but i can't because my application will always change the palette and i can't afford to recreate the
bitmap constantly..
can anybody help please ?
0
Comment
Question by:eugeneng
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 

Author Comment

by:eugeneng
ID: 1325685
Adjusted points to 200
0
 
LVL 7

Expert Comment

by:psdavis
ID: 1325686
// Here's my code for loading up the palette and drawing a DIB section.  See if it helps you.

// Ignore the CMemDC stuff for now, It's a wonderful little class that will remove your flickering during redraw.

   CPaintDC dc(this); // device context for painting

   if( m_bmLogo.GetSafeHandle( ) == NULL )
   {
      HBITMAP hLogoBitmap = (HBITMAP) ::LoadImage( AfxGetInstanceHandle( ), MAKEINTRESOURCE( IDB_CUSTOMS ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );

      if( hLogoBitmap )
         m_bmLogo.Attach( hLogoBitmap );

      HBITMAP hBackBitmap = (HBITMAP) ::LoadImage( AfxGetInstanceHandle( ), MAKEINTRESOURCE( IDB_GRAYTXT ), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION );

      if( hBackBitmap )
         m_bmBackground.Attach( hBackBitmap );

   // Create the palette to go with our DIB section

      if(( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE ) != 0 )
      {
         DIBSECTION ds;
         m_bmLogo.GetObject( sizeof( DIBSECTION ), &ds );
//       m_bmBackground.GetObject( sizeof( DIBSECTION ), &ds );

         int nColors;

         if( ds.dsBmih.biClrUsed != 0 )
            nColors = ds.dsBmih.biClrUsed;
         else
            nColors = 1 << ds.dsBmih.biBitCount;

      // Create a halftone palette if the DIB section contains more than 256 colors

         if( nColors > 256 )
            m_palLogo.CreateHalftonePalette( &dc );

      // Create a custom palette from the DIB section's color table

         else
         {
            RGBQUAD* pRGB = new RGBQUAD[ nColors ];

            CDC memDC;
            memDC.CreateCompatibleDC( &dc );

            CBitmap* pOldBitmap = memDC.SelectObject( &m_bmLogo );
//          CBitmap* pOldBitmap = memDC.SelectObject( &m_bmBackground );
            ::GetDIBColorTable( memDC.GetSafeHdc( ), 0, nColors, pRGB );
            memDC.SelectObject( pOldBitmap );

            UINT uiSize = sizeof( LOGPALETTE ) + ( sizeof( PALETTEENTRY ) * ( nColors - 1 ));
            LOGPALETTE* pLP = (LOGPALETTE*) new BYTE[ uiSize ];

            pLP->palVersion = 0x300;
            pLP->palNumEntries = (unsigned short) nColors;

            for( int iCurrColor = 0; iCurrColor < nColors; iCurrColor ++ )
            {
               pLP->palPalEntry[ iCurrColor ].peRed   = pRGB[ iCurrColor ].rgbRed;
               pLP->palPalEntry[ iCurrColor ].peGreen = pRGB[ iCurrColor ].rgbGreen;
               pLP->palPalEntry[ iCurrColor ].peBlue  = pRGB[ iCurrColor ].rgbBlue;
               pLP->palPalEntry[ iCurrColor ].peFlags = 0;
            }

            m_palLogo.CreatePalette( pLP );
            delete[] pLP;
            delete[] pRGB;
         }
      }
   }

// if( m_bPreviewMode == false )
   if( true )
   {
      CMemDC pMemDC( &dc );

   // Get the client rectangle

         CRect rcClientRect;
         GetClientRect( &rcClientRect );

      pMemDC.Rectangle( rcClientRect );

   // BitBlts the Logo on to the background

      if( m_bmLogo.GetSafeHandle( ))
      {
      // Setup the palette for this bitmap

         CPalette* pOldPalette = NULL;
   
         if( m_palLogo.GetSafeHandle( ))
         {
            pOldPalette = pMemDC.SelectPalette( &m_palLogo, FALSE );
            pMemDC.RealizePalette( );
         }

      // Create our compatible DC

         DIBSECTION ds;

         CDC memDC;
         memDC.CreateCompatibleDC( &pMemDC );

      // Draw the background in a layered format

         CBitmap* pOldBitmap = NULL;

#if DRAW_BACKGROUND == 1

         pOldBitmap = memDC.SelectObject( &m_bmBackground );

         CRect rcClientRect;
         GetClientRect( &rcClientRect );

         m_bmBackground.GetObject( sizeof( DIBSECTION ), &ds );

         int cx = ( rcClientRect.Width ( ) / ( ds.dsBm.bmWidth  )) + 1;
         int cy = ( rcClientRect.Height( ) / ( ds.dsBm.bmHeight )) + 1;

         CPoint ptSize( ds.dsBm.bmWidth, ds.dsBm.bmHeight );
         memDC.DPtoLP( &ptSize );

         CPoint ptOrigin( 0, 0 );
         memDC.DPtoLP( &ptOrigin );

         for( int iRows = 0; iRows < cx; iRows ++ )
         {
            for( int iColumns = 0; iColumns < cy; iColumns ++ )
            {
               int x = ( iRows    * ( ds.dsBm.bmWidth  ));
               int y = ( iColumns * ( ds.dsBm.bmHeight ));

               pMemDC.BitBlt( x, y, ptSize.x, ptSize.y, &memDC, ptOrigin.x, ptOrigin.y, SRCCOPY );
            }
         }

         memDC.SelectObject( pOldBitmap );

#endif

      // Draw the logo centered on the immge

         m_bmLogo.GetObject( sizeof( DIBSECTION ), &ds );

         pOldBitmap = memDC.SelectObject( &m_bmLogo );

              CPoint ptLogo(( rcClientRect.Width( ) - ds.dsBm.bmWidth ) / 2, ( rcClientRect.Height( ) - ds.dsBm.bmHeight ) / 2 );
         pMemDC.BitBlt( ptLogo.x, ptLogo.y, ds.dsBm.bmWidth, ds.dsBm.bmHeight, &memDC, 0, 0, SRCCOPY );

//       DrawTransparentBitmap( &pMemDC, &m_bmLogo, ptLogo.x, ptLogo.y, RGB( 255, 255, 255 ));

      // Now free up the information and restore the DC

         memDC.SelectObject( pOldBitmap );

         if( pOldPalette != NULL )
            pMemDC.SelectPalette( pOldPalette, FALSE );
      }
   }

Phillip

0
 

Author Comment

by:eugeneng
ID: 1325687
thanx phillip, but your code doesn't help me any thing, I can't use load bitmap to get the hBitmap, instead i have to create it on the fly and have to change their palette frequently, thats why i have to user palette index instead of rgb color, and your code is kind of hard to read. Anyway, thanx for you help.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 12

Accepted Solution

by:
rwilson032697 earned 200 total points
ID: 1325688
You are setting the number of entries in the LogPalette to 4 when it should be set to COLORINDEX (256 I assume). This will have the effect of really messing up your palette. Set it to COLORINDEX:

     lpPal->palNumEntries = COLORINDEX;

Also, why do you shift left 3 the red, green and blue components of your pal[i] array? If these channels were fairly saturated (ie values > 64) the result would be zero (or no colour for that channel).

Cheers,

Raymond.

0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1325689
Ooops, when I mean > 64 I really mean low order 5 bits are zero.

Cheers,

Raymond.
0
 

Author Comment

by:eugeneng
ID: 1325690
i'm really sorry Raymond, actually COLORINDEX is #define constance where i defined it as #define COLORINDEX 4, so there is no difference between COLORINDEX and 4, because i only need 4 colors, and for the <<3 bit, that is my application requirement, because actually i store the color in 5 bits only, so when i want to display the color, i've to shift it back, just ignore it, doesn't matter..
0
 
LVL 12

Expert Comment

by:rwilson032697
ID: 1325691
No problem. You had better reject my answer now.

Cheers,

Raymond.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question