changing a color in TBitmap

Hi y´all,

Painting the Bitmaps isn´t all that difficult, but handling any special
behaviour is.

I´m starting out with a bitmap having a flag.
Different players should have different colors, still using the same bitmap (the
flag if you will).
I somehow cannot extract the palette from the bitmap.

The Bitmap is defined in a resource.

code as follows:
foo::Paint(TDC &DC...)
 TBitmap *BM = new TBitmap(GetModule(),IDB_FLAG);
 //paints ok (using TMemoryDC and SelectObject)

 //I´ve tried this (a little naíve...)
 TPalette Palette(*BM);
 //does compile but also generates an access of 0xfffff
 //not good.

if( any ideas ) { :-) }
else { :-(( }
Who is Participating?
brosenb0Connect With a Mentor Commented:
I just had the same problem recently.  The way I got around it was to derive a class from TDib and include palette handling and painting functionality.  I'll include the source code for you to play with.


#if !defined(__mydib_h)              // Sentry, use file only if it's not already included.
#define __mydib_h

       Class definition for TMyDib (TDib).

#include <owl\owlpch.h>
#pragma hdrstop

#include "ntnstlap.rh"            // Definition of all resources.

//{{TDib = TMyDib}}
class TMyDib : public TDib {
       TMyDib (HGLOBAL handle, TAutoDelete autoDelete = NoAutoDelete);
       TMyDib (HINSTANCE instance, TResId resID);
       TMyDib (const char *name);
       BOOL SetupDib();
       BOOL CreatePalette();
       Paint  (TDC &dc, TRect rectDC, TRect rectDIB);
       virtual ~TMyDib ();

      TPalette *m_pPalette;
};    //{{TMyDib}}

#endif                                      // __mydib_h sentry.

    Source file for implementation of TMyDib (TDib).      

#include <owl\owlpch.h>
#pragma hdrstop

#include "mydib.h"

//{{TMyDib Implementation}}

//--Create from handle to existing dib
TMyDib::TMyDib (HGLOBAL handle, TAutoDelete autoDelete):
       TDib(handle, autoDelete)
       // INSERT>> Your constructor code here.

//--Create from resource
TMyDib::TMyDib(HINSTANCE instance, TResId resID):
      TDib(instance, resID)

//--Load from .bmp or .dib file
TMyDib::TMyDib(const char *name):

TMyDib::~TMyDib ()
       // INSERT>> Your destructor code here.
      if(m_pPalette) delete m_pPalette;

BOOL TMyDib::SetupDib()
      BOOL bResult;

      //--Allocate objects
      m_pPalette = new TPalette(*this);
      if(!m_pPalette) {
            bResult = FALSE;
            goto _Done;

      //--Create the dib's palette
      bResult = CreatePalette();

      //--Add what ever else you want to setup here

      return bResult;

BOOL TMyDib::CreatePalette()
      BITMAPINFO   *pInfo;
      PALETTEENTRY  palEntry;
      WORD wNumColors;

      pInfo = GetInfo();
      wNumColors = (WORD)NumColors();

      if(wNumColors) {
            for (int i = 0; i < (int)wNumColors; i++) {
                  palEntry.peRed   = pInfo->bmiColors[i].rgbRed;
                  palEntry.peGreen = pInfo->bmiColors[i].rgbGreen;
                  palEntry.peBlue  = pInfo->bmiColors[i].rgbBlue;
                  palEntry.peFlags = 0;
                  m_pPalette->SetPaletteEntry(i, palEntry);
      return TRUE;

TMyDib::Paint  (TDC &dc, TRect rectDC, TRect rectDIB)
      BOOL bResult;

      //--Get the DIB's palette, then select it into DC
      if (m_pPalette == NULL)
                  return FALSE;

      //--Select as background palette & realize the palette
      dc.SelectObject(*m_pPalette, TRUE);

      //--Make sure to use the stretching mode, best for color pictures

      //--Determine whether to call StretchDIBits() or SetDIBitsToDevice()
      if ((rectDC.Width() == rectDIB.Width()) &&
            (rectDC.Height() == rectDIB.Height()))
            bResult = dc.SetDIBitsToDevice(rectDC, rectDIB.TopLeft(), (TDib)*this);
            bResult = dc.StretchDIBits(rectDC, rectDIB, (TDib)*this, SRCCOPY);

      return bResult;

To implement the class, create a TMyDib pointer as a member of your view (or dialog) class.  Instantiate a new object during view or dialog initialization, pass parameters to the TMyDib constructor.  Delete the TMyDib object in your view's destructor.  Don't create a new object each time your paint function is called or your painting will be very slow and will flicker.  I implemented it in a dialog like this: -

class MyTDLGClient : public TDialog {
    MyTDLGClient (TWindow *parent, TResId resId = IDD_CLIENT, TModule *module = 0);
    virtual ~MyTDLGClient ();

    void EvPaint ();

    TMyDib    *m_pDibLogo;

bool MyTDLGClient::EvInitDialog (HWND hWndFocus)
    bool bResult;

    bResult = TDialog::EvInitDialog(hWndFocus);

    // INSERT>> Your code here.
    m_pDibLogo = new TMyDib(GetApplication()->GetInstance(), IDB_SETUPLOGO);

    return bResult;

void MyTDLGClient::EvPaint ()

    // INSERT>> Your code here.
    TClientDC dc(*this);
    HWND hwndStatic;
    TRect rectDest;
    TPoint topLeft, botRight;

    //--Get pointer to app's TModule
   TModule *pModule = GetApplication();

   //--I painted into a static control to get the sunken border.  You can paint where ever
   //--you want.  Just create a rectangle within the dest. dc.

   //--Get the static control's rectangle
   hwndStatic = GetDlgItem(IDC_STATICLOGO);
   TWindow wndStatic(hwndStatic, pModule);
   rectDest = wndStatic.GetWindowRect();

    //--Convert the rectangle to client coordinates
    topLeft  = rectDest.TopLeft();
    botRight = rectDest.BottomRight();
    rectDest.Set(topLeft.x, topLeft.y, botRight.x, botRight.y);

    //--Create a rectangle for the DIB
    TRect rectDIB(TPoint(0,0), TPoint(m_pDibLogo->Width(), m_pDibLogo->Height()));

    //--Paint the DIB
    m_pDibLogo->Paint(dc, rectDest, rectDIB);

    if(m_pDibLogo) delete m_pDibLogo;
the last one has some important notes for using TPalette....
MostlyWaterAuthor Commented:
Adjusted points to 100
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.