CorpSms/LuButton/LuButton.cpp
lujiang e17c4ce7ed 重新对窗口布局进行优化,解决缺字的情况。
对图标显示进行了优化,使用gdi+按DPI进行缩放。
2025-04-14 17:24:47 +08:00

1111 lines
26 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// LuButton.cpp : implementation file
//
#include "stdafx.h"
#include "LuButton.h"
#include <mmsystem.h> //加入对多媒体控制的类,记得加入winmm.lib
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// LuButton
LuButton::LuButton()
{
m_bSelect = false; //用于此按扭是否被选中
m_bFlat = false; //此按扭是否是浮动的
m_bFlash = false; //此按扭是否在闪动
m_bSound = false; //现在没有声音
m_bTransBk= false; //现在不需要显示透明位图
m_lBmpCount=0; //所加入图片的总数
m_lNowBmp=0; //现在显示的图片数为0;
m_lMaxBmp =5; //最大能加入的图片数,跟据以下m_bmpX决定
m_lFlashCount=0; //闪动计数当计数为0时则不闪
m_lMaxFlashCount=0; //最大的闪动计数
m_lFlashTime=LUBUTTON_FLASHTIME; //闪动的间隔时间
m_lDHTime = 800; //动画间隔时间
m_bUnBmp = false; //现在还没有设UnBmp
m_bFlatBmp = false; //现在还没有设FlatBmp
m_bDisBmp = false;
m_bClickBmp = false;
m_bMouseOnButton = false; //鼠标还没有在按扭之上
m_ToolTip.m_hWnd = NULL; //用于显示按扭的提示信息
*m_szSelTip = 0;
*m_szUnSelTip = 0;
m_RGBTrans= RGB(0,0,0);//需要去掉背景色的颜色
m_bHandBmp = false; //不需直接从HBITMAP中绘制
m_bHandBmp2 = false;
// 初始化GDI+
m_pBitmap = NULL;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput, NULL);
}
LuButton::~LuButton()
{
if (m_dcBk.m_hDC != NULL && m_pbmpOldBk != NULL)
{
m_dcBk.SelectObject(m_pbmpOldBk);
}
FreeBitmapData();
// 关闭GDI+
GdiplusShutdown(m_gdiplusToken);
}
void LuButton::FreeBitmapData()
{
if (m_pBitmap)
{
delete m_pBitmap;
m_pBitmap = NULL;
}
}
BEGIN_MESSAGE_MAP(LuButton, CButton)
//{{AFX_MSG_MAP(LuButton)
ON_WM_MOUSEMOVE()
ON_WM_TIMER()
ON_WM_KILLFOCUS()
ON_WM_CAPTURECHANGED()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// LuButton message handlers
void LuButton::PreSubclassWindow()
{
UINT nBS;
nBS = GetButtonStyle();
// Check if this is the default button
//if (nBS & BS_DEFPUSHBUTTON) m_bIsDefault = TRUE;
// Add BS_OWNERDRAW style
SetButtonStyle(nBS | BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
void LuButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
//如果设置为闪动,有时则不需要重画
if ( m_bFlash && m_lFlashCount % 2 != 0 )
{
return ;
}
//取得dc;
//CDC* pDC = CDC::FromHandle(lpDIS->hDC);
CDC *pdrawDC = CDC::FromHandle(lpDIS->hDC);
CMemDC2 memDC(pdrawDC);
CDC *pDC = &memDC;
CDC pDispDC;
pDispDC.CreateCompatibleDC( pDC );
CBitmap * pOldBitmap; //用于存旧的Bitmap
BOOL bOldBitmap=false; //是否已把旧的Bitmpa存起来
BITMAP bmpSize; //用于取bmp的大小
BOOL bIsPressed = (lpDIS->itemState & ODS_SELECTED); //取得当前状态
BOOL bIsFocused = (lpDIS->itemState & ODS_FOCUS);
BOOL bIsDisabled = (lpDIS->itemState & ODS_DISABLED);
BOOL bIsSelect = (lpDIS->itemAction & ODA_SELECT );
//char Buf[ 256 ];
//_stprintf( Buf , " %d , %d , %d , %d \n" , bIsPressed , bIsFocused , bIsDisabled , bIsSelect);
//TRACE( Buf );
CRect itemRect = lpDIS->rcItem;
//第一步先将背景置为淡灰
COLORREF colorRef = RGB(192, 192, 192);
//COLORREF colorRef = GetSysColor(COLOR_WINDOW);
CBrush brush_LTGRAY(colorRef );
pDC->FillRect( &itemRect ,&brush_LTGRAY);//将整个背景置为淡灰
pDC->SetStretchBltMode(STRETCH_HALFTONE);
pDispDC.SetStretchBltMode(STRETCH_HALFTONE);
if ( bIsDisabled && m_bDisBmp ) //如果按扭已DISABLE及已设置了DISABLE图片
{
if (!this->m_bTransBk)
{
DrawBitmap(pDC, itemRect.left, itemRect.top, itemRect.Width(), itemRect.Height(), &m_DisBmp);
/*
if ( !bOldBitmap )
{
pOldBitmap = pDispDC.SelectObject( &m_DisBmp );
bOldBitmap = true;
}
m_DisBmp.GetBitmap( &bmpSize );
pDC->StretchBlt( itemRect.left , itemRect.top ,
itemRect.right - itemRect.left , itemRect.bottom - itemRect.top , &pDispDC ,
0 , 0 , bmpSize.bmWidth , bmpSize.bmHeight , SRCCOPY );
*/
}
else
{
PaintBk(pDC);
this->DrawTransparentBitmap( pDC , itemRect.left , itemRect.top , &m_DisBmp , m_RGBTrans );
}
pDispDC.SelectObject( pOldBitmap );
return;
}
//如果为选中状态
if ( m_bSelect && m_lBmpCount > 0 )
{
CBitmap * pTempBmp = NULL;
switch( m_lNowBmp )
{
case 1:
pTempBmp = &m_bmp1;
break;
case 2:
pTempBmp = &m_bmp2;
break;
case 3:
pTempBmp = &m_bmp3;
break;
case 4:
pTempBmp = &m_bmp4;
break;
case 5:
pTempBmp = &m_bmp5;
break;
default:
pTempBmp = &m_bmp1;
break;
}
if (!this->m_bTransBk)
{
DrawBitmap(pDC, itemRect.left, itemRect.top, itemRect.Width(), itemRect.Height(), pTempBmp);
/*
if ( !bOldBitmap )
{
pOldBitmap = pDispDC.SelectObject( pTempBmp );
bOldBitmap = true;
}
pTempBmp->GetBitmap( &bmpSize );
pDC->StretchBlt( itemRect.left , itemRect.top ,
itemRect.right - itemRect.left , itemRect.bottom - itemRect.top , &pDispDC ,
0 , 0 , bmpSize.bmWidth , bmpSize.bmHeight , SRCCOPY );
*/
}
else
{
PaintBk(pDC);
this->DrawTransparentBitmap( pDC , itemRect.left , itemRect.top , pTempBmp , m_RGBTrans );
}
}
else
{
if ( m_bUnBmp )
{
//画未被选中的图片
if (!this->m_bTransBk)
{
DrawBitmap(pDC, itemRect.left, itemRect.top, itemRect.Width(), itemRect.Height(), &m_unBmp);
/*
if (!bOldBitmap)
{
pOldBitmap = pDispDC.SelectObject(&m_unBmp);
bOldBitmap = true;
}
m_unBmp.GetBitmap(&bmpSize);
pDC->StretchBlt( itemRect.left , itemRect.top , itemRect.right - itemRect.left , itemRect.bottom - itemRect.top , &pDispDC , 0 , 0 , bmpSize.bmWidth , bmpSize.bmHeight , SRCCOPY );
*/
}
else
{
PaintBk(pDC);
this->DrawTransparentBitmap( pDC , itemRect.left , itemRect.top , &m_unBmp , m_RGBTrans );
}
}
}
if ( m_bMouseOnButton && m_bFlatBmp && !bIsPressed ) //如果鼠标在按扭之上和已设置了浮动图片
{
if (!this->m_bTransBk)
{
DrawBitmap(pDC, itemRect.left, itemRect.top, itemRect.Width(), itemRect.Height(), &m_FlatBmp);
/*
if ( !bOldBitmap )
{
pDispDC.SelectObject( &m_FlatBmp );
bOldBitmap = true;
}
m_FlatBmp.GetBitmap( &bmpSize );
pDC->StretchBlt( itemRect.left , itemRect.top ,
itemRect.right - itemRect.left , itemRect.bottom - itemRect.top , &pDispDC ,
0 , 0 , bmpSize.bmWidth , bmpSize.bmHeight , SRCCOPY );
*/
}
else
{
PaintBk(pDC);
this->DrawTransparentBitmap( pDC , itemRect.left , itemRect.top , &m_FlatBmp , m_RGBTrans );
}
}
if ( bIsPressed && m_bClickBmp ) //如果鼠标已按下及已设置了Click图片
{
if (!this->m_bTransBk)
{
DrawBitmap(pDC, itemRect.left, itemRect.top, itemRect.Width(), itemRect.Height(), &m_ClickBmp);
/*
if ( !bOldBitmap )
{
pDispDC.SelectObject( &m_ClickBmp );
bOldBitmap = true;
}
m_ClickBmp.GetBitmap( &bmpSize );
pDC->StretchBlt( itemRect.left , itemRect.top ,
itemRect.right - itemRect.left , itemRect.bottom - itemRect.top , &pDispDC ,
0 , 0 , bmpSize.bmWidth , bmpSize.bmHeight , SRCCOPY );
*/
}
else
{
PaintBk(pDC);
this->DrawTransparentBitmap( pDC , itemRect.left , itemRect.top , &m_ClickBmp , m_RGBTrans );
}
}
//直接从HBITMAP中绘制
if ( m_bHandBmp && m_bHandBmp2 ) //直接从HBITMAP中绘制
{
CBitmap * pBmp = CBitmap::FromHandle( m_hHandBmp );
//画未被选中的图片
if (!this->m_bTransBk)
{
DrawBitmap(pDC, itemRect.left, itemRect.top, itemRect.Width(), itemRect.Height(), &m_ClickBmp);
/*
if ( !bOldBitmap )
{
pOldBitmap = pDispDC.SelectObject( pBmp );
bOldBitmap = true;
}
pBmp->GetBitmap( &bmpSize );
pDC->StretchBlt( itemRect.left , itemRect.top ,
itemRect.right - itemRect.left , itemRect.bottom - itemRect.top , &pDispDC ,
0 , 0 , bmpSize.bmWidth , bmpSize.bmHeight , SRCCOPY );
*/
}
else
{
PaintBk(pDC);
this->DrawTransparentBitmap( pDC , itemRect.left , itemRect.top , pBmp , m_RGBTrans );
}
}
else
{
TRACE( _T("No Draw Hand \r\n") );
}
if ( m_bMouseOnButton && m_bFlat ) //如果鼠标在按扭之上则需要画
{
//CPen p_BLACK(PS_SOLID,1,RGB(0,0,0)); //黑色画笔
CPen p_WHITE(PS_SOLID,1,RGB(255,255,255)); //白色画笔
CPen p_GRAY(PS_SOLID,1,RGB(128,128,128)); //灰色画笔
//CPen p_LTGRAY(PS_SOLID,1,RGB(192,192,192)); //淡灰色画笔
CPen *pOldPen; //用于存旧的Pen
if ( !bIsPressed ) //此变量是否是在鼠标下在按下沿未弹起之中
{
pOldPen = pDC->SelectObject( &p_WHITE );
//上
pDC->MoveTo( itemRect.left , itemRect.top );
pDC->LineTo( itemRect.right -1, itemRect.top );
//左
pDC->MoveTo( itemRect.left , itemRect.top );
pDC->LineTo( itemRect.left , itemRect.bottom -1);
//右
pDC->SelectObject( &p_GRAY );
pDC->MoveTo( itemRect.right -1, itemRect.top );
pDC->LineTo( itemRect.right -1 , itemRect.bottom -1 );
//下
pDC->MoveTo( itemRect.left , itemRect.bottom -1 );
pDC->LineTo( itemRect.right -1, itemRect.bottom -1);
}
else
{
pOldPen = pDC->SelectObject( &p_GRAY );
//上
pDC->MoveTo( itemRect.left , itemRect.top );
pDC->LineTo( itemRect.right -1, itemRect.top );
//左
pDC->MoveTo( itemRect.left , itemRect.top );
pDC->LineTo( itemRect.left , itemRect.bottom -1);
//右
pDC->SelectObject( &p_WHITE );
pDC->MoveTo( itemRect.right -1, itemRect.top );
pDC->LineTo( itemRect.right -1 , itemRect.bottom -1 );
//下
pDC->MoveTo( itemRect.left , itemRect.bottom -1 );
pDC->LineTo( itemRect.right -1, itemRect.bottom -1);
}
pDC->SelectObject( pOldPen );
}
if (bOldBitmap )
pDispDC.SelectObject( pOldBitmap );
}
BOOL LuButton::PreTranslateMessage(MSG* pMsg)
{
if (m_ToolTip.m_hWnd == NULL)
{
m_ToolTip.Create(this);
m_ToolTip.SetMaxTipWidth(400);
m_ToolTip.Activate(FALSE);
}
m_ToolTip.RelayEvent(pMsg);
return CButton::PreTranslateMessage(pMsg);
}
void LuButton::OnMouseMove(UINT nFlags, CPoint point)
{
CButton::OnMouseMove(nFlags, point);
/*
//正在点击
if (nFlags & MK_LBUTTON )
{
Invalidate(true);
return;
}
*/
if (GetCapture() != this )
{
if ( m_bSound ) //发出声音
sndPlaySound( m_szSoundFile , SND_ASYNC );
m_bMouseOnButton = true;
SetCapture();
Invalidate(true);
}
else
{
POINT p2 = point;
ClientToScreen(&p2);
CWnd* wndUnderMouse = WindowFromPoint(p2);
if (wndUnderMouse != this)
{
if (m_bMouseOnButton == TRUE)
{
m_bMouseOnButton = FALSE;
Invalidate();
}
if (!(nFlags & MK_LBUTTON)) ReleaseCapture();
}
}
}
void LuButton::OnTimer(UINT_PTR nIDEvent)
{
switch( nIDEvent )
{
case 1:
//如果为选中状态,则需要变换显示的图片
if ( m_bSelect && m_lBmpCount > 0)
{
m_lNowBmp ++;
if ( m_lNowBmp >m_lBmpCount )
m_lNowBmp = 1;
this->Invalidate();
}
break;
case 2:
if ( m_bFlash && m_lMaxFlashCount > 0 )
{
m_lFlashCount ++;
this->Invalidate();
}
break;
}
CButton::OnTimer(nIDEvent);
}
BOOL LuButton::SetSelTooltip(TCHAR *szText)
{
if ( szText )
{
_stprintf( m_szSelTip , szText );
return true;
}
else
{
return false;
}
}
BOOL LuButton::ActiveToolTip(bool bActive)
{
TCHAR szTipText[ 256 ];
if ( m_bSelect )
_stprintf( szTipText , m_szSelTip );
else
_stprintf( szTipText , m_szUnSelTip );
// Initialize ToolTip
if (m_ToolTip.m_hWnd == NULL)
{
// Create ToolTip control
m_ToolTip.Create(this);
m_ToolTip.SetMaxTipWidth(400);
// Create inactive
m_ToolTip.Activate(FALSE);
}
// If there is no tooltip defined then add it
if (m_ToolTip.GetToolCount() == 0)
{
CRect rectBtn;
GetClientRect(rectBtn);
m_ToolTip.AddTool(this, szTipText, rectBtn, 1);
}
// Set text for tooltip
m_ToolTip.UpdateTipText(szTipText, this, 1);
m_ToolTip.Activate(bActive);
return true;
}
BOOL LuButton::SetUnSelToolTip(TCHAR *szText)
{
if ( szText )
{
_stprintf( m_szUnSelTip , szText );
return true;
}
else
{
return false;
}
}
BOOL LuButton::SetButtonSel(BOOL bSelect)
{
m_bSelect = bSelect;
if ( m_bSelect )
{//如果当前为选中状态,则需要设时间
if ( m_lBmpCount > 1 ) //只有当总图片数大于1时才认为此按扭为动画的,所以需要设置timer
SetTimer( 1 , m_lDHTime , NULL );
}
else
{//否则将杀死timer,不能留情
KillTimer( 1 );
}
ActiveToolTip( true );
this->Invalidate();
return m_bSelect;
}
BOOL LuButton::GetButtonSel()
{
return m_bSelect;
}
long LuButton::AddButtonBmp(UINT nIDResource)
{
if ( m_lBmpCount >= m_lMaxBmp )
return -1;
m_lBmpCount = m_lBmpCount +1;
switch( m_lBmpCount )
{
case 1:
m_bmp1.LoadBitmap( nIDResource );break;
case 2:
m_bmp2.LoadBitmap( nIDResource );break;
case 3:
m_bmp3.LoadBitmap( nIDResource );break;
case 4:
m_bmp4.LoadBitmap( nIDResource );break;
case 5:
m_bmp5.LoadBitmap( nIDResource );break;
}
return m_lBmpCount;
}
long LuButton::AddButtonBmp(LPCTSTR lpszResourceName)
{
if ( m_lBmpCount >= m_lMaxBmp )
return -1;
m_lBmpCount = m_lBmpCount +1;
switch( m_lBmpCount )
{
case 1:
m_bmp1.LoadBitmap( lpszResourceName );break;
case 2:
m_bmp2.LoadBitmap( lpszResourceName );break;
case 3:
m_bmp3.LoadBitmap( lpszResourceName );break;
case 4:
m_bmp4.LoadBitmap( lpszResourceName );break;
case 5:
m_bmp5.LoadBitmap( lpszResourceName );break;
}
return m_lBmpCount;
}
BOOL LuButton::SetUnSelBmp(UINT nIDResource)
{
if ( !m_bUnBmp )
{
m_unBmp.LoadBitmap( nIDResource );
m_bUnBmp = true;
return true;
}
else
{
m_unBmp.DeleteObject();
m_unBmp.LoadBitmap( nIDResource );
return true;
}
return false;
}
BOOL LuButton::SetUnSelBmp(LPCTSTR lpszResourceName )
{
if ( !m_bUnBmp )
{
m_unBmp.LoadBitmap( lpszResourceName );
m_bUnBmp = true;
return true;
}
else
{
m_unBmp.DeleteObject();
m_unBmp.LoadBitmap( lpszResourceName );
return true;
}
return false;
}
//DEL void LuButton::OnClicked()
//DEL {
//DEL // if ( m_lBmpCount >0 )
//DEL // SetButtonSel( m_bSelect ? false : true );
//DEL }
BOOL LuButton::SetFlat(BOOL bFlat)
{
BOOL bOldFlat = m_bFlat;
m_bFlat = bFlat ;
return bOldFlat ;
}
BOOL LuButton::GetFlat()
{
return m_bFlat ;
}
BOOL LuButton::SetSound(bool bSound)
{
BOOL bOldSound = bSound;
m_bSound = bSound;
return bOldSound;
}
BOOL LuButton::SetSoundFileName(TCHAR *szFile)
{
if ( szFile )
{
_stprintf( m_szSoundFile , szFile );
m_bSound = true;
return true;
}
else
{
return false;
}
}
BOOL LuButton::SetDisableBmp(UINT nIDResource)
{
if ( !m_bDisBmp )
{
m_DisBmp.LoadBitmap( nIDResource );
m_bDisBmp = true;
return true;
}
else
{
m_DisBmp.DeleteObject();
m_DisBmp.LoadBitmap( nIDResource );
return true;
}
return false;
}
BOOL LuButton::SetDisableBmp(LPCTSTR lpszResourceName)
{
if ( !m_bDisBmp )
{
m_DisBmp.LoadBitmap( lpszResourceName );
m_bDisBmp = true;
return true;
}
else
{
m_DisBmp.DeleteObject();
m_DisBmp.LoadBitmap( lpszResourceName );
return true;
}
return false;
}
BOOL LuButton::SetFlatBmp(UINT nIDResource)
{
if ( !m_bFlatBmp )
{
m_FlatBmp.LoadBitmap( nIDResource );
m_bFlatBmp = true;
return true;
}
else
{
m_FlatBmp.DeleteObject();
m_FlatBmp.LoadBitmap( nIDResource );
return true;
}
return false;
}
BOOL LuButton::SetFlatBmp(LPCTSTR lpszResourceName)
{
if ( !m_bFlatBmp )
{
m_FlatBmp.LoadBitmap( lpszResourceName );
m_bFlatBmp = true;
return true;
}
else
{
m_FlatBmp.DeleteObject();
m_FlatBmp.LoadBitmap( lpszResourceName );
return true;
}
return false;
}
BOOL LuButton::SetClickBmp(UINT nIDResource)
{
if ( !m_bClickBmp )
{
m_ClickBmp.LoadBitmap( nIDResource );
m_bClickBmp = true;
return true;
}
else
{
m_ClickBmp.DeleteObject();
m_ClickBmp.LoadBitmap( nIDResource );
return true;
}
return false;
}
BOOL LuButton::SetClickBmp(LPCTSTR lpszResourceName)
{
if ( !m_bClickBmp )
{
m_ClickBmp.LoadBitmap( lpszResourceName );
m_bClickBmp = true;
return true;
}
else
{
m_ClickBmp.DeleteObject();
m_ClickBmp.LoadBitmap( lpszResourceName );
return true;
}
return false;
}
void LuButton::OnKillFocus(CWnd* pNewWnd)
{
CButton::OnKillFocus(pNewWnd);
if ( !m_bFlat && !m_bFlatBmp )
return;
if (m_bMouseOnButton == TRUE)
{
m_bMouseOnButton = FALSE;
Invalidate();
}
}
void LuButton::OnCaptureChanged(CWnd *pWnd)
{
if (m_bMouseOnButton == TRUE)
{
ReleaseCapture();
Invalidate();
}
CButton::OnCaptureChanged(pWnd);
}
BOOL LuButton::SetFlash(long lFlashTimer, long lFlashCount, BOOL bFlash)
{
BOOL bOldFlash = m_bFlash;
if ( lFlashCount > 0)
{
m_lMaxFlashCount = lFlashCount;
m_lFlashCount = 0;
}
else
{
m_lMaxFlashCount = 0;
m_lFlashCount = 0;
}
if ( lFlashTimer > 0 )
m_lFlashTime = lFlashTimer;
m_bFlash = bFlash;
if ( m_bFlash )
SetTimer( 2 , m_lFlashTime , NULL );
else
KillTimer( 2 );
return bOldFlash;
}
void LuButton::DrawBitmap(CDC* pDC, int x, int y, int width,int height,CBitmap* pBmp)
// x,y 是要显示的图象的位置width与height是绘图区域长与宽
// crColor 是要显示位图的背景色
{
if (!pBmp)
return;
Bitmap* pBitmap = Bitmap::FromHBITMAP((HBITMAP)pBmp->GetSafeHandle(), NULL);
if (pBitmap)
{
Graphics graphics(pDC->m_hDC);
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic); // 设置高质量缩放
/*
int imageWidth = pBitmap->GetWidth();
int imageHeight = pBitmap->GetHeight();
float scaleX = static_cast<float>(width) / imageWidth;
float scaleY = static_cast<float>(height) / imageHeight;
float scale = min(scaleX, scaleY);
int scaledWidth = static_cast<int>(imageWidth * scale);
int scaledHeight = static_cast<int>(imageHeight * scale);s
int xPos = (itemRect.Width() - scaledWidth) / 2;
int yPos = (itemRect.Height() - scaledHeight) / 2;
*/
// 设置背景色为透明
//graphics.Clear(Color::Transparent);
//保持比例显示
//graphics.DrawImage(pBitmap, xPos, yPos, scaledWidth, scaledHeight);
//满屏显示
graphics.DrawImage(pBitmap,x,y, width, height);
delete pBitmap;
}
}
void LuButton::DrawTransparentBitmap(CDC *pDC, int x, int y, CBitmap * pBmp, COLORREF crColor)
// x,y 是要显示的图象的位置id 是要显示的位图资源的ID
// crColor 是要显示位图的背景色
{
COLORREF crOldBack=pDC->SetBkColor(RGB(255,255,255));
COLORREF crOldText=pDC->SetTextColor(RGB(0,0,0));
CDC dcImage,dcMask;
//CBitmap bmp;
BITMAP bm;
//bmp.LoadBitmap(id);
//bmp.LoadBitmap(129);
//bmp.CreateBitmapIndirect(pBmp);
//bmp.FromHandle( (HBITMAP)pBmp );
//bmp = *pBmp
pBmp->GetBitmap(&bm);
int nWidth=bm.bmWidth,nHeight=bm.bmHeight;
dcImage.CreateCompatibleDC(pDC);
dcMask.CreateCompatibleDC(pDC);
CBitmap * pOldBitmapImage=dcImage.SelectObject(pBmp);
CBitmap bitmapMask;
bitmapMask.CreateBitmap(nWidth,nHeight,1,1,NULL);
CBitmap * pOldBitmapMask=dcMask.SelectObject(&bitmapMask);
dcImage.SetBkColor(crColor);
dcMask.BitBlt(0,0,nWidth,nHeight,&dcImage,0,0,SRCCOPY);
pDC->BitBlt(x,y,nWidth,nHeight,&dcImage,0,0,SRCINVERT);
pDC->BitBlt(x,y,nWidth,nHeight,&dcMask,0,0,SRCAND);
pDC->BitBlt(x,y,nWidth,nHeight,&dcImage,0,0,SRCINVERT);
dcImage.SelectObject(pOldBitmapImage);
dcMask.SelectObject(pOldBitmapMask);
pDC->SetBkColor(crOldBack);
pDC->SetTextColor(crOldText);
}
BOOL LuButton::SetTransBK(BOOL bTransBk)
{
BOOL bOldTransBk = m_bTransBk;
m_bTransBk = bTransBk ;
return bOldTransBk ;
}
long LuButton::SetTransBKColor(COLORREF rgbColor)
{
long lOldTransColor = m_RGBTrans;
m_RGBTrans = rgbColor;
return lOldTransColor;
}
long LuButton::SetDHTime( long lDHTime )
{
long lOldTime = m_lDHTime;
m_lDHTime = lDHTime;
return lOldTime;
}
BOOL LuButton::SetWindowRgnFromBmp(HBITMAP hBmp, COLORREF cTransparentColor, COLORREF cTolerance)
{
HRGN hRgn = NULL;
BITMAP bm;
if (hBmp)
{
// Create a memory DC inside which we will scan the bitmap content
HDC hMemDC = CreateCompatibleDC(NULL);
if (hMemDC)
{
// Get bitmap size
//BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
// Create a 32 bits depth bitmap and select it into the memory DC
BITMAPINFOHEADER RGB32BITSBITMAPINFO = {
sizeof(BITMAPINFOHEADER), // biSize
bm.bmWidth, // biWidth;
bm.bmHeight, // biHeight;
1, // biPlanes;
32, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
};
VOID * pbits32;
HBITMAP hbm32 = CreateDIBSection(hMemDC, (BITMAPINFO *)&RGB32BITSBITMAPINFO, DIB_RGB_COLORS, &pbits32, NULL, 0);
if (hbm32)
{
HBITMAP holdBmp = (HBITMAP)SelectObject(hMemDC, hbm32);
// Create a DC just to copy the bitmap into the memory DC
HDC hDC = CreateCompatibleDC(hMemDC);
if (hDC)
{
// Get how many bytes per row we have for the bitmap bits (rounded up to 32 bits)
BITMAP bm32;
GetObject(hbm32, sizeof(bm32), &bm32);
while (bm32.bmWidthBytes % 4)
bm32.bmWidthBytes++;
// Copy the bitmap into the memory DC
HBITMAP holdBmp = (HBITMAP)SelectObject(hDC, hBmp);
BitBlt(hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hDC, 0, 0, SRCCOPY);
// For better performances, we will use the ExtCreateRegion() function to create the
// region. This function take a RGNDATA structure on entry. We will add rectangles by
// amount of ALLOC_UNIT number in this structure.
#define ALLOC_UNIT 100
DWORD maxRects = ALLOC_UNIT;
HANDLE hData = GlobalAlloc(GMEM_MOVEABLE, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects));
RGNDATA *pData = (RGNDATA *)GlobalLock(hData);
pData->rdh.dwSize = sizeof(RGNDATAHEADER);
pData->rdh.iType = RDH_RECTANGLES;
pData->rdh.nCount = pData->rdh.nRgnSize = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
// Keep on hand highest and lowest values for the "transparent" pixels
BYTE lr = GetRValue(cTransparentColor);
BYTE lg = GetGValue(cTransparentColor);
BYTE lb = GetBValue(cTransparentColor);
BYTE hr = min(0xff, lr + GetRValue(cTolerance));
BYTE hg = min(0xff, lg + GetGValue(cTolerance));
BYTE hb = min(0xff, lb + GetBValue(cTolerance));
// Scan each bitmap row from bottom to top (the bitmap is inverted vertically)
BYTE *p32 = (BYTE *)bm32.bmBits + (bm32.bmHeight - 1) * bm32.bmWidthBytes;
for (int y = 0; y < bm.bmHeight; y++)
{
// Scan each bitmap pixel from left to right
for (int x = 0; x < bm.bmWidth; x++)
{
// Search for a continuous range of "non transparent pixels"
int x0 = x;
LONG *p = (LONG *)p32 + x;
while (x < bm.bmWidth)
{
BYTE b = GetRValue(*p);
if (b >= lr && b <= hr)
{
b = GetGValue(*p);
if (b >= lg && b <= hg)
{
b = GetBValue(*p);
if (b >= lb && b <= hb)
// This pixel is "transparent"
break;
}
}
p++;
x++;
}
if (x > x0)
{
// Add the pixels (x0, y) to (x, y+1) as a new rectangle in the region
if (pData->rdh.nCount >= maxRects)
{
GlobalUnlock(hData);
maxRects += ALLOC_UNIT;
hData = GlobalReAlloc(hData, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), GMEM_MOVEABLE);
pData = (RGNDATA *)GlobalLock(hData);
}
RECT *pr = (RECT *)&pData->Buffer;
SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
if (x0 < pData->rdh.rcBound.left)
pData->rdh.rcBound.left = x0;
if (y < pData->rdh.rcBound.top)
pData->rdh.rcBound.top = y;
if (x > pData->rdh.rcBound.right)
pData->rdh.rcBound.right = x;
if (y+1 > pData->rdh.rcBound.bottom)
pData->rdh.rcBound.bottom = y+1;
pData->rdh.nCount++;
// On Windows98, ExtCreateRegion() may fail if the number of rectangles is too
// large (ie: > 4000). Therefore, we have to create the region by multiple steps.
if (pData->rdh.nCount == 2000)
{
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
pData->rdh.nCount = 0;
SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
}
}
}
// Go to next row (remember, the bitmap is inverted vertically)
p32 -= bm32.bmWidthBytes;
}
// Create or extend the region with the remaining rectangles
HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER) + (sizeof(RECT) * maxRects), pData);
if (hRgn)
{
CombineRgn(hRgn, hRgn, h, RGN_OR);
DeleteObject(h);
}
else
hRgn = h;
// Clean up
SelectObject(hDC, holdBmp);
DeleteDC(hDC);
}
DeleteObject(SelectObject(hMemDC, holdBmp));
}
DeleteDC(hMemDC);
}
}
if ( hRgn )
{
CRect rect;
this->GetWindowRect( &rect);
//this->ClientToScreen(&rect);
this->MoveWindow( rect.left , rect.top , bm.bmWidth , bm.bmHeight );
this->SetWindowRgn( hRgn , true);
return true;
}
return false;
}
void LuButton::PaintBk(CDC *pDC)
{
CClientDC clDC(GetParent());
//CPaintDC clDC(m_pMainWnd);
//CDC clDC(this->GetParent() );
//CDC * p2DC =GetParent()->GetDC();
CRect rect;
CRect rect1;
GetClientRect(rect);
GetWindowRect(rect1);
GetParent()->ScreenToClient(rect1);
if (m_dcBk.m_hDC == NULL)
{
m_dcBk.CreateCompatibleDC(&clDC);
m_bmpBk.CreateCompatibleBitmap(&clDC, rect.Width(), rect.Height());
m_pbmpOldBk = m_dcBk.SelectObject(&m_bmpBk);
m_dcBk.BitBlt(0, 0, rect.Width(), rect.Height(), &clDC, rect1.left, rect1.top, SRCCOPY);
}
pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &m_dcBk,0,0, SRCCOPY);
}
void LuButton::SetMainWin(CWnd *pWnd)
{
m_pMainWnd = pWnd;
}
BOOL LuButton::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
return false;
//return CButton::OnEraseBkgnd(pDC);
}
BOOL LuButton::SetWindowRgnFromBmp(UINT uiBmp, COLORREF cTransparentColor, COLORREF cTolerance)
{
CBitmap bmp;
if ( bmp.LoadBitmap( uiBmp ) )
{
SetWindowRgnFromBmp((HBITMAP)bmp , cTransparentColor , cTolerance );
return true;
}
else
return false;
}
void LuButton::SetHandBmp(HBITMAP hBmp)
{
m_bHandBmp = true;
m_bHandBmp2 = true;
m_hHandBmp = hBmp;
}
void LuButton::SetHandBmp(BOOL bTrue)
{
m_bHandBmp = bTrue;
m_bHandBmp2 = bTrue;
}