Re: MFC : Make a bitmap with a transparant color
Last Update
I just modify the source code to get automatically it's parent window's image
Code:
#pragma once
#include "afxext.h"
class CTransparentBitmapButton :
public CBitmapButton
{
private:
void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap);
// The colour inside this button's bitmap(s) that should be regarded as transparent
// is selected by the one of the pixel locate by X, Y
int m_iXPxlTranparent, m_iYPxlTranparent;
CBitmap m_BitmapBackground;
BOOL m_HasBackGround;
public:
CTransparentBitmapButton(int XPxlT, int YPxlT);
~CTransparentBitmapButton(void);
//virtual void OnPaint();
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
DECLARE_MESSAGE_MAP()
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
protected:
virtual void PreSubclassWindow();
};
#include "StdAfx.h"
#include ".\transparentbitmapbutton.h"
BEGIN_MESSAGE_MAP(CTransparentBitmapButton, CBitmapButton)
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
CTransparentBitmapButton::CTransparentBitmapButton(int XPxlT,int YPxlT)
{
// Initialise the transparent pixel X,Y
m_iXPxlTranparent = XPxlT;
m_iYPxlTranparent = YPxlT;
m_HasBackGround = FALSE;
}
CTransparentBitmapButton::~CTransparentBitmapButton(void)
{
}
void CTransparentBitmapButton::PreSubclassWindow()
{
CBitmapButton::PreSubclassWindow();
CWnd *pParent = GetParent();
if (pParent)
{
CRect Rect;
GetClientRect(&Rect);
ClientToScreen(&Rect);
pParent->ScreenToClient(&Rect);
CDC *pDC = pParent->GetDC();
m_BitmapBackground.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());
}
}
BOOL CTransparentBitmapButton::OnEraseBkgnd(CDC* pDC)
{
if (!m_HasBackGround)
{
CWnd *pParent = GetParent();
if (pParent)
{
CRect Rect;
GetClientRect(&Rect);
ClientToScreen(&Rect);
pParent->ScreenToClient(&Rect);
CDC *pDC = pParent->GetDC();
CDC memdc;
memdc.CreateCompatibleDC(pDC);
CBitmap *oldbmp = memdc.SelectObject(&m_BitmapBackground);
memdc.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);
memdc.SelectObject(oldbmp);
m_HasBackGround = TRUE;
pParent->ReleaseDC(pDC);
}
}
return TRUE;
}
/*
// From 'OnPaint()
void CTransparentBitmapButton::OnPaint()
{
if ((GetParent()) && (GetParent()->IsIconic()))
{
CBitmapButton::OnPaint();
}
else
{
CPaintDC dc(this); // device context for painting
// At least onw bitmap must be loaded before calling 'Paint()'
ASSERT(m_bitmap.m_hObject != NULL);
// and we'll assume until we find otherwise, that
// the button is being drawn in its normal state.
CBitmap* pBitmap = &m_bitmap;
if ((!(IsWindowEnabled())) && (NULL != m_bitmapDisabled.m_hObject))
pBitmap = &m_bitmapDisabled;
DrawTransparentBitmap(dc.m_hDC, *pBitmap);
}
}
*/
void CTransparentBitmapButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
ASSERT(lpDrawItemStruct != NULL);
// At least onw bitmap must be loaded before calling 'DrawItem()'
ASSERT(m_bitmap.m_hObject != NULL);
CBitmap* pBitmap = &m_bitmap;
UINT state = lpDrawItemStruct->itemState;
if ((state & ODS_SELECTED) && (NULL != m_bitmapSel.m_hObject))
pBitmap = &m_bitmapSel;
else if ((state & ODS_FOCUS) && (NULL != m_bitmapFocus.m_hObject))
pBitmap = &m_bitmapFocus;
else if ((state & ODS_DISABLED) && (NULL != m_bitmapDisabled.m_hObject))
pBitmap = &m_bitmapDisabled;
DrawTransparentBitmap(lpDrawItemStruct->hDC, *pBitmap);
}
void CTransparentBitmapButton::DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap)
{
BITMAP bm;
COLORREF cColour;
HBITMAP bmAndBack, bmAndObject, bmAndMem, bmSave;
HBITMAP bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
HDC hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
POINT ptSize;
hdcTemp = CreateCompatibleDC(hdc);
if (HGDIOBJ hOldObj = SelectObject(hdcTemp, hBitmap)) // Select the bitmap
DeleteObject(hOldObj);
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);
COLORREF transparentColour = GetPixel(hdcTemp, m_iXPxlTranparent, m_iYPxlTranparent);
if (transparentColour) cColour = SetBkColor(hdcTemp, transparentColour);
// 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);
SetBkColor(hdcTemp, cColour);
// 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.
if (m_HasBackGround)
{
CDC MemDC;
CDC* pDC = CDC::FromHandle(hdc) ;
BITMAP InfosBmp;
m_BitmapBackground.GetBitmap(&InfosBmp);
MemDC.CreateCompatibleDC(pDC);
MemDC.SelectObject(&m_BitmapBackground);
BitBlt(hdcMem, 0, 0, InfosBmp.bmWidth, InfosBmp.bmHeight, MemDC, 0, 0, SRCCOPY);
DeleteDC(MemDC);
}
else
{
BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdc, 0, 0, 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 coloured 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, 0, 0, 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);
}
Re: MFC : Make a bitmap with a transparant color
Hi ,
I am facing a similar problem with MFC Dialog based application .I am supposed to load a image to a dilaog window..Till now i don't have any issues loading a rectangle shaped picture controls(in .bmp format) to the dialog.But now I got a requirement to load irregular picture control over the Dialog which gives me a white colored background and that is annoying.I could not find any solution after searching for long time.Please help me in.
Re: MFC : Make a bitmap with a transparant color
Quote:
Originally Posted by
santoshg
I am facing a similar problem with MFC Dialog based application ....
I got a requirement to load irregular picture control over the Dialog which gives me a white colored background and that is annoying.
This thread is about how to "Make a bitmap with a transparant color".
What does your "annoying" problem have to do with this?
Re: MFC : Make a bitmap with a transparant color
Hi VictorN.
My Question is whether I can use the same bitmap by changing its background to a transparent color .so that my window's background will not be white.sorry if you think my question is improper because I am new to mfc.
Re: MFC : Make a bitmap with a transparant color
Quote:
sorry if you think my question is improper because I am new to mfc.
It's not that the question is improper - its that this thread is over 8 years old and it would have been more appropriate to start a new thread asking your specific question.
Re: MFC : Make a bitmap with a transparant color
Quote:
Originally Posted by
santoshg
My Question is whether I can use the same bitmap by changing its background to a transparent color .so that my window's background will not be white.sorry if you think my question is improper because I am new to mfc.
Your "Question" has nothing to do with MFC, as MFC provides nothing special in regard to bitmap drawing or transparency.
You need to explain your issue somewhat better. What do you think bitmap background is? What is your drawing procedure looks like? What is "rectangle shaped picture controls(in .bmp format)"? What is irregular picture control? What it has to do with the bitmap? With dialog?
The wording you use sounds kinda confusing, so how could we help you when we experience troubles with understanding?