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?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

krispCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
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
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.