-
February 9th, 2006, 03:55 AM
#30
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|