Solved

how to use DIB_PAL_COLORS in CreateDIBSection() ?

Posted on 1998-12-02
7
1,687 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
  • 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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
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

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
bobThere java chalenge 45 85
ODBC Connection Logging, ADO.NET 6 50
Whole sheet autoscrub still needed 19 44
Line meaning 9 77
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now