• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 317
  • Last Modified:

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 { :-(( }
0
MostlyWater
Asked:
MostlyWater
  • 2
1 Solution
 
duneramCommented:
the last one has some important notes for using TPalette....
0
 
brosenb0Commented:
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.

//MyDIB.h

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

/*
       OVERVIEW
       ========
       Class definition for TMyDib (TDib).
*/

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


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


//{{TDib = TMyDib}}
class TMyDib : public TDib {
public:
       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 ();

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


#endif                                      // __mydib_h sentry.


//MyDIB.Cpp
/*
    OVERVIEW
    ========
    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.
      SetupDib();
}

//--Create from resource
TMyDib::TMyDib(HINSTANCE instance, TResId resID):
      TDib(instance, resID)
{
      SetupDib();
}

//--Load from .bmp or .dib file
TMyDib::TMyDib(const char *name):
      TDib(name)
{
      SetupDib();
}


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

_Done:
      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)
            if(!SetupDib())
                  return FALSE;

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

      //--Make sure to use the stretching mode, best for color pictures
      dc.SetStretchBltMode(COLORONCOLOR);

      //--Determine whether to call StretchDIBits() or SetDIBitsToDevice()
      if ((rectDC.Width() == rectDIB.Width()) &&
            (rectDC.Height() == rectDIB.Height()))
            bResult = dc.SetDIBitsToDevice(rectDC, rectDIB.TopLeft(), (TDib)*this);
      else
            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 {
public:
    MyTDLGClient (TWindow *parent, TResId resId = IDD_CLIENT, TModule *module = 0);
    virtual ~MyTDLGClient ();

public:
    {.....}
   
protected:
    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 ()
{
    TDialog::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();
    ScreenToClient(topLeft);
    ScreenToClient(botRight);
    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);
}


MyTDLGClient::~MyTDLGClient
{
    if(m_pDibLogo) delete m_pDibLogo;
}
0
 
MostlyWaterAuthor Commented:
Adjusted points to 100
0

Featured Post

Upgrade your Question Security!

Add Premium security features to your question to ensure its privacy or anonymity. Learn more about your ability to control Question Security today.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now