MFC : Make a bitmap with a transparant color - Page 3
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 3 of 3 FirstFirst 123
Results 31 to 36 of 36

Thread: MFC : Make a bitmap with a transparant color

  1. #31
    Join Date
    Jan 2006
    Location
    Marseille, France
    Posts
    94

    Lightbulb 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);
    }
    Last edited by FireJocker; February 21st, 2006 at 09:05 AM.

  2. #32
    Join Date
    Sep 2014
    Posts
    4

    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.

  3. #33
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,546

    Re: MFC : Make a bitmap with a transparant color

    Quote Originally Posted by santoshg View Post
    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?
    Victor Nijegorodov

  4. #34
    Join Date
    Sep 2014
    Posts
    4

    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.

  5. #35
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,755

    Re: MFC : Make a bitmap with a transparant color

    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.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  6. #36
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,051

    Re: MFC : Make a bitmap with a transparant color

    Quote Originally Posted by santoshg View Post
    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?
    Best regards,
    Igor

Page 3 of 3 FirstFirst 123

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center