?
Solved

Problem drawing transparent bitmap using DrawTransparentBitmap exisitng ONLY in Win98 16bit color

Posted on 2003-03-25
6
Medium Priority
?
517 Views
Last Modified: 2013-11-20
Hello,

I'm using following function :
-----------------------------------------------------------------------
void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap, int xStart,
                           int yStart, COLORREF cTransparentColor)
{
      BITMAP     bm;
      COLORREF   cColor;
      HBITMAP    bmAndBack, bmAndObject, bmAndMem, bmSave;
      HBITMAP    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
      HDC        hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
      POINT      ptSize;

      hdcTemp = CreateCompatibleDC(hdc);
      SelectObject(hdcTemp, hBitmap);   // Select the bitmap

      GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
      ptSize.x = bm.bmWidth;            // Get width of bitmap
      ptSize.y = bm.bmHeight;           // Get height of bitmap
      DPtoLP(hdcTemp, &ptSize, 1);      // Convert from device
      
      // to logical points
      
      // Create some DCs to hold temporary data.
      hdcBack   = CreateCompatibleDC(hdc);
      hdcObject = CreateCompatibleDC(hdc);
      hdcMem    = CreateCompatibleDC(hdc);
      hdcSave   = CreateCompatibleDC(hdc);
      
      // Create a bitmap for each DC. DCs are required for a number of
      // GDI functions.
      
      // Monochrome DC
      bmAndBack   = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
      
      // Monochrome DC
      bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
      
      bmAndMem    = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
      bmSave      = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
      
      // Each DC must select a bitmap object to store pixel data.
      bmBackOld   = (HBITMAP)SelectObject(hdcBack, bmAndBack);
      bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
      bmMemOld    = (HBITMAP)SelectObject(hdcMem, bmAndMem);
      bmSaveOld   = (HBITMAP)SelectObject(hdcSave, bmSave);
      
      // Set proper mapping mode.
      SetMapMode(hdcTemp, GetMapMode(hdc));
      
      // Save the bitmap sent here, because it will be overwritten.
      BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
      
      // Set the background color of the source DC to the color.
      // contained in the parts of the bitmap that should be transparent
      cColor = SetBkColor(hdcTemp, cTransparentColor);
      
      // Create the object mask for the bitmap by performing a BitBlt
      // from the source bitmap to a monochrome bitmap.
      BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0,
            SRCCOPY);
      
      // Set the background color of the source DC back to the original
      // color.
      SetBkColor(hdcTemp, cColor);
      
      // Create the inverse of the object mask.
      BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0,
            NOTSRCCOPY);
      
      // Copy the background of the main DC to the destination.
      BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, xStart, yStart,
            SRCCOPY);
      
      // Mask out the places where the bitmap will be placed.
      BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
      
      // Mask out the transparent colored pixels on the bitmap.
      BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
      
      // XOR the bitmap with the background on the destination DC.
      BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
      
      // Copy the destination to the screen.
      BitBlt(hdc, xStart, yStart, ptSize.x, ptSize.y, hdcMem, 0, 0,
            SRCCOPY);
      
      // Place the original bitmap back into the bitmap sent here.
      BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
      
      // Delete the memory bitmaps.
      DeleteObject(SelectObject(hdcBack,   bmBackOld));
      DeleteObject(SelectObject(hdcObject, bmObjectOld));
      DeleteObject(SelectObject(hdcMem,    bmMemOld));
      DeleteObject(SelectObject(hdcSave,   bmSaveOld));
      
      // Delete the memory DCs.
      DeleteDC(hdcMem);
      DeleteDC(hdcBack);
      DeleteDC(hdcObject);
      DeleteDC(hdcSave);
      DeleteDC(hdcTemp);
}
-----------------------------------------------------------------------
I use function a lot and it works perfect. Recently , by chance i finded out
there's a problem in win98 ( second edition ) when using 16 BIT COLOR.

Here's example of how i use this function :

DrawTransparentBitmap(
            m_hMemDC ,
            HBITMAP(pictBubble),
            nBubblePosX,
            nBubblePosY,
            CLR_TRANSPARENT);

Here's my define of transparent color ( "clean" CYAN )
#define CLR_TRANSPARENT         RGB(0,255,255)

As i said , it works everywhere except win98 ( second edition ) when using 16 BIT COLOR.
As far as i know , each loaded image produces it's own palette. In some cases , it can
cause color to be changed to nearest color and obviously , transparency won't work in this
case since above function needs transparent color to be exact down to pixel.
So , i tried to use following to work it out :

cTransparentColor = GetNearestColor( hdc , CLR_TRANSPARENT );       

But , it didn't work.


Need your help ( it's pretty urgent ) , thanks !
P.S. I just prefer solution that won't force me to change everything , but a small patch ;)

0
Comment
Question by:c1727130
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
6 Comments
 
LVL 3

Expert Comment

by:Catalepsy
ID: 8204233
This is just a suggestion.  16 bit color comes in two flavors.  R = 5 bits, G = 5 bits and B = 5 bits.  It can also be R = 5 bits, G = 6 bits and B = 5 bits.  Perhaps, the problem you are experiencing has something to do with this.

One other thing, it is unrelated, are you certain you don't need to store the previous bitmap for SelectObject(hdcTemp, hBitmap);?  I normally do as a precaution.  I guess if you don't run out of GDI resources after a few hundred calls you don't need it.
0
 

Author Comment

by:c1727130
ID: 8217094
So how can i deal with these RGB 5/6/6 ?
Any ideas ?
0
 

Author Comment

by:c1727130
ID: 11799079
Please refund points, thank you.
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 11825069
PAQed, with points refunded (145)

modulo
Community Support Moderator
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…

777 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