Problem with buttons containing bitmaps

Hi all!

Please help me. My problem is following:
I want to create Button containing bitmap. (MS Visual C++ 6.0) I place button control to a form. Add propierties: Bitmap, Transparent. Associate variable m_bmp with this button (Control, class CButton)

Add source code:

  CBitmap bmp;
  bmp.LoadBitmap(TEST_BMP);
  m_bmp.SetBitmap((HBITMAP)bmp);

(TEST_BMP is a 16 color bitmap)

But the image does not showing.

And Q2: How can I set this image transparent (e.g. Set transparent color, for example color of top-left pixel)?

Thanks

Regards,
  Ruslan (mahno@mail.lv)

LVL 1
mahnoAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
krispConnect With a Mentor Commented:
Hi,
 Say you have a bitmap by the ID - IDB_BITMAP2, and a button variable as m_myButton.

Now use the following code to display the bitmap -

HBITMAP hbitmap = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP2));
m_myButton.SetBitmap( hbitmap );


Cheers.
0
 
ZoppoCommented:
Hi mahno,

try add a

bmp.Detach();

after the line with the SetBitmap() function to avoid deletion of the bitmap's GDI object with dtor of CBitmap.

Since the drawing of CButton does not support transparency you can only create a new bitmap with all pixels you want to be transparent set to the color of the buttons background.

ZOPPO
0
 
ZoppoCommented:
Hey, krisp, you should even say something about Q2 when locking the question as answered ...
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
krispCommented:
sorry zoppo
0
 
ZoppoCommented:
Not my problem, but manho's             :)
0
 
mahnoAuthor Commented:
Thanks krisp and Zoppo, Q1 is clearified to me (both methods are working) Just one more question (Q2): I'm trying to get transparent bitmap by this way:

  CBitmap bmp;
  const int nBmpSize = 16*16; //Bitmap size
  unsigned short *lpBits;
  DWORD dwCount = nBmpSize<<1;
  DWORD dwSysColor;

  lpBits = new unsigned short[nBmpSize];
  bmp.LoadBitmap(IDB_BITMAP2);
  dwCount = bmp.GetBitmapBits(dwCount, (LPVOID)lpBits);
  dwSysColor = GetSysColor(COLOR_BTNFACE);

  if (dwCount == nBmpSize<<1) {
    for (int nIndex = 1; nIndex < nBmpSize; nIndex++) {
      //Top-Left with StdWinBtnFace color
      if (lpBits[nIndex] == lpBits[0]) {
        lpBits[nIndex] = (unsigned short)dwSysColor; //Error
      }
    }
    lpBits[0] = (unsigned short)dwSysColor; //Error
    bmp.SetBitmapBits(dwCount, (LPVOID)lpBits);
  }
  m_bmp.SetBitmap((HBITMAP)bmp.Detach());

One problem: When I get bitmap bits using "GetBitmapBits" - for each pixel I get 16bit color value, but using "GetSysColor" - 32bit (24bit are used). How can I convert 24 -> 16? I can't find this in help.

Thanks,
  Ruslan
0
 
ZoppoCommented:
Hi mahno,

Use ::GetDIBits() instead ...

ZOPPO
0
 
mahnoAuthor Commented:
Zoppo, something like this?

  DWORD dwCount;
  BITMAPINFO bi;

  HBITMAP hbitmap = LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP2));
  dwCount = ::GetDIBits(this->GetDC()->GetSafeHdc(), hbitmap, 0, 16, (LPVOID)lpBits, &bi, DIB_RGB_COLORS);

?

Thanks,
  Ruslan

0
 
ZoppoCommented:
I do not know exactly how to use it (because I did not use it until now), but here are some MSDN articles which may help you with this:

ID: Q81498
ID: Q230492
ID: Q80080

ZOPPO
0
 
mahnoAuthor Commented:
Thanks,
  mahno
0
 
ZoppoCommented:
:(
0
 
mahnoAuthor Commented:
Hi Zoppo,

I'm sorry but, unfortunately, I'm not experienced in Experts-Exchange (This is my first time :-) Therefore I've made mistake when add PTS ONLY to krisp. Would You mind explaining me how could I correct my mistake and add PTS both of you?

ps: You answers was fine and now I have almoust transparent bitmap :-).
I've got this by the following:

  CBitmap bmp;
  const int nBmpSize = 16*16; //Bitmap size
  unsigned short *lpBits;
  DWORD dwCount = nBmpSize<<1;
  DWORD dwSysColor;
  WORD wSysColor;

  lpBits = new unsigned short[nBmpSize];
  bmp.LoadBitmap(IDB_BITMAP2);
  dwCount = bmp.GetBitmapBits(dwCount, (LPVOID)lpBits);
  dwSysColor = GetSysColor(COLOR_BTNFACE);
  //Converting 24bpp -> 15bpp
  wSysColor = (((WORD)((dwSysColor&0xff)>>3) << 10)&0x7c00) |        //Red
              (((WORD)(((dwSysColor&0xff00)>>8)>>3) << 5)&0x03e0) |  //Green
              (((WORD)(((dwSysColor&0xff0000)>>16)>>3))&0x001f);     //Blue


  if (dwCount == nBmpSize<<1) {
    for (int nIndex = 1; nIndex < nBmpSize; nIndex++) {
      //Replace Top-Left with StdWinBtnFace color
      if (lpBits[nIndex] == lpBits[0]) {
        lpBits[nIndex] = wSysColor;
      }
    }
    lpBits[0] = wSysColor;
    bmp.SetBitmapBits(dwCount, (LPVOID)lpBits);
  }
  m_bmp.SetBitmap((HBITMAP)bmp.Detach());

Later I change code (use ::GetDIBits()), because in current implementation I loose some color information (converting 8bit-per-color -> 5bit-per-color)

Regards,
  mahno
0
 
ZoppoCommented:
It's not possible to correct given points, but never mind, krisp will be very happy abouot his/her first points ...

enjoy learning with EE           :)

0
All Courses

From novice to tech pro — start learning today.