VC位图按钮
VC位图按钮
2011年08月19日
最近利用业余时间自己封装了一个位图按钮的类,写得不怎地,还有很多地方功能没时间添加,有兴趣的可以自行添加。如有错误的地方请留言,我们一起共同学习学习。。。
用法:第3步是必需的
1.定义CLButton lButton;
2.设置(可选择设置)
2.1 设置并加载资源:lButton.SetInfo(this->GetSafeHwnd(),IDC_BUTTON_IMAG,"HELLO",IDB_BITMAP4,IDB_BITMAP5,IDB_BITMAP6);
2.2设置并加载指定路径资源(可支持JPG):
lButton.SetInfo(this->GetSafeHwnd(),IDC_BUTTON_IMAG,"dfkdd",
"F:\\lilinsheng\\myProtectTest\\HankerDemo500W\\image\\11.bmp",
"F:\\lilinsheng\\myProtectTest\\HankerDemo500W\\image\\12.bmp",
"F:\\lilinsheng\\myProtectTest\\HankerDemo500W\\image\\14.bmp");
2.3设置按钮标题字体
lButton.SetButFont(40,12,RGB(255,0,0),"宋体");
2.4设置按钮为不规则
lButton.SetIrreGular(RGB(255,255,255),true);
2.4显视隐藏
3.关联按钮,使其能够进行消息响应,在主对话框中DoDataExchange函数中加入
DDX_Control(pDX, IDC_BUTTON_IMAG, lButton);
源码:
------------------------------------------------------------------------ .H
/*-------------------------------------------------------------------------
类功能 : 图片按钮类
作者 : lilinsheng
日期 : 2011-08-19
最近修改 : 2011-08-19
--------------------------------------------------------------------------*/
#pragma once
#define MAX_PATH 256 //数组最大缓冲区
//字体信息保存结构
typedef struct _buttitlefont
{
_buttitlefont(){
strcpy(cFaceName,"宋体");
hight = 24;
with = 12;
rgb = RGB(0,0,0);
}
int hight;
int with;
COLORREF rgb;
char cFaceName[48];
}BUTTITLEFONT;
class CLButton :public CButton
{
public:
CLButton();
/*
函数名称 : SetInfo
函数功能 : 设置按钮信息,加载工程中的位图资源,默认为0(非位图按钮)
hWnd : 主窗口句柄
butID : 按钮ID
titleName : 按钮标题
backMapID : 背景位图ID
upMapID : 安下按钮时位图ID(或按钮为当前焦点时)
MoveMapID : 移动时显示的位图ID
*/
void SetInfo(HWND hWnd,UINT butID,char *titleName,UINT backMapID = 0,UINT upMapID = 0,UINT MoveMapID = 0);
/*
函数名称 : SetInfo
函数功能 : 设置按钮信息,加载目录下位图资源,默认为NULL(非位图按钮)
hWnd : 主窗口句柄
butID : 按钮ID
titleName : 按钮标题
backMapPath : 背景位图路径
upMapPath : 安下按钮时位图路径(或按钮为当前焦点时)
MoveMapPath : 移动时显示的位图路径
*/
void SetInfo(HWND hWnd,UINT butID,char *titleName,LPCTSTR backMapPath = NULL,LPCTSTR upMapPath = NULL,LPCTSTR MoveMapPath = NULL);
/*
函数名称 : SetButFont
函数功能 : 按钮字体信息设置
hight : 按钮字体高
with : 按钮字体宽
rgb : 按钮字颜色
cFaceName : 按钮字体各式
*/
void SetButFont(int hight,int with,COLORREF rgb,char *cFaceName = "宋体");
/*
函数名称 : Show
函数功能 : 按钮显视状态
show : SW_SHOW 显视/SW_HIDE隐藏
*/
void Show(int show);
/*
函数名称 : GetButWnd
函数功能 : 获取按钮句柄
返回值 : 按钮句柄
*/
HWND GetButWnd(){::GetDlgItem(m_Wnd,m_ButID);}
/*
函数名称 : LoadImageFromFile
函数功能 : 加载指定路径下的位图
返回值 : 位图句柄
*/
HBITMAP LoadImageFromFile(PCTSTR pszBitmapFile);
/*
函数名称 : TransparentBlt
函数功能 : 显视位图,并指定不显视的图标的颜色
Transparent : 透明色,COLORREF类型
*/
void TransparentBlt( CDC *pDC, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
CDC *hdcSrc, //
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT Transparent // 透明色,COLORREF类型
);
/*
函数名称 : SetIrreGular
函数功能 : 设置按钮为不规则按钮。
rgb : 透明色,COLORREF类型
isIrreGular : 是否透明
*/
void SetIrreGular(COLORREF rgb,bool isIrreGular = true);
private:
CBitmap * m_pButBackBitmap;
CBitmap * m_pButUpMapBitmap;
CBitmap * m_pButMoveMapBitmap;
HWND m_Wnd;
UINT m_ButID;
CRect m_Rect;
int m_Show;
BUTTITLEFONT m_butFont;
char m_TitleName[MAX_PATH];
bool m_isIrreGular;
COLORREF m_IrreGularRGB;
//按钮的状态
BOOL m_bOver;
BOOL m_bTracking;
BOOL m_bFocus;
BOOL m_bIsDefault;
BOOL m_nTypeStyle;
BOOL m_sKeyDown;
protected:
LRESULT OnSetStyle(WPARAM wParam, LPARAM lParam);
virtual void UpdataButton(CDC *pDC,UINT state);
virtual void PreSubclassWindow();
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual ~CLButton();
protected:
//{{AFX_MSG(CLButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
afx_msg BOOL OnClicked();
afx_msg UINT OnGetDlgCode();
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
-------------------------------------------------------------------------------------------.CPP
#include "StdAfx.h"
#include "LButton.h"
////////////////////////////////////////
CLButton::CLButton():
m_bOver(FALSE),
m_bTracking(FALSE),
m_sKeyDown(FALSE),
m_bFocus(FALSE),
m_isIrreGular(FALSE)
{
m_Show = SW_SHOW;
memset(m_TitleName,0,MAX_PATH);
m_pButBackBitmap = NULL;
m_pButUpMapBitmap = NULL;
m_pButMoveMapBitmap = NULL;
}
CLButton::~CLButton()
{
if (m_pButBackBitmap)
delete m_pButBackBitmap;
m_pButBackBitmap = NULL;
if (m_pButUpMapBitmap)
delete m_pButUpMapBitmap;
m_pButUpMapBitmap = NULL;
if (m_pButMoveMapBitmap)
delete m_pButMoveMapBitmap;
m_pButMoveMapBitmap = NULL;
}
BEGIN_MESSAGE_MAP(CLButton, CButton)
//{{AFX_MSG_MAP(CXPButton)
ON_WM_MOUSEMOVE()
ON_WM_ERASEBKGND()
ON_WM_GETDLGCODE()
ON_WM_LBUTTONUP()
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_CONTROL_REFLECT_EX(BN_CLICKED, OnClicked)
ON_MESSAGE(BM_SETSTYLE, OnSetStyle)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//添加Owner Draw属性
void CLButton::PreSubclassWindow()
{
ModifyStyle(0, BS_OWNERDRAW);
CButton::PreSubclassWindow();
if (m_nTypeStyle == BS_DEFPUSHBUTTON)
{
m_nTypeStyle = BS_PUSHBUTTON;
}
}
void CLButton::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);
}
CButton::OnMouseMove(nFlags, point);
}
void CLButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
m_sKeyDown = TRUE;
InvalidateRect(NULL, FALSE);
CButton::OnLButtonUp(nFlags, point);
}
LRESULT CLButton::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bOver = FALSE;
m_bTracking = FALSE;
InvalidateRect(NULL, FALSE);
return 0;
}
LRESULT CLButton::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bOver = TRUE;
InvalidateRect(NULL,FALSE);
return 0;
}
HBITMAP CLButton::LoadImageFromFile( PCTSTR pszBitmapFile )
{
IPicture* pIPic;
IStream* pStream = NULL;
HGLOBAL hGlobal;
void* pVoid;
FILE *fp = NULL;
fopen_s( &fp, CT2A( pszBitmapFile ),"rb" );
if ( fp == NULL )return NULL;
fseek( fp, 0, SEEK_END );
long lFS = ftell(fp);
fseek( fp, 0, SEEK_SET );
hGlobal = GlobalAlloc( GPTR, lFS );
if ( hGlobal == NULL)
{
fclose(fp);
return NULL;
}
pVoid = (void*)hGlobal;
fread( pVoid, 1, lFS, fp );
fclose( fp );
// Create an IStream so IPicture can
if( FAILED( CreateStreamOnHGlobal( hGlobal,FALSE,&pStream) ) )
{
GlobalFree(hGlobal);
return NULL;
}
HRESULT hr = OleLoadPicture( pStream, 0, TRUE, IID_IPicture, (void**)&pIPic);
pStream->Release();
GlobalFree(hGlobal);
if( FAILED(hr) )
{
return NULL;
}
HBITMAP hBitmap = NULL;
pIPic->get_Handle( ( unsigned int*)&hBitmap );
HBITMAP hBitmapRet = (HBITMAP)CopyImage( hBitmap, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG );
pIPic->Release();
return hBitmapRet;
}
void CLButton::SetInfo(HWND hWnd,UINT butID,char *titleName,UINT backMapID ,UINT upMapID ,UINT MoveMapID )
{
m_Wnd = hWnd;
m_ButID = butID;
strcpy(m_TitleName,titleName);
if (backMapID)
{
if (m_pButBackBitmap)
delete m_pButBackBitmap;
m_pButBackBitmap = new CBitmap;
m_pButBackBitmap->LoadBitmap(backMapID);
}
if (upMapID)
{
if (m_pButUpMapBitmap)
delete m_pButUpMapBitmap;
m_pButUpMapBitmap = new CBitmap;
m_pButUpMapBitmap->LoadBitmap(upMapID);
}
if (MoveMapID)
{
if (m_pButMoveMapBitmap)
delete m_pButMoveMapBitmap;
m_pButMoveMapBitmap = new CBitmap;
m_pButMoveMapBitmap->LoadBitmap(MoveMapID);
}
HWND wnd = ::GetDlgItem(m_Wnd,butID);
::GetWindowRect(wnd,m_Rect);
}
void CLButton::SetInfo(HWND hWnd,UINT butID,char *titleName,LPCTSTR backMapPath,LPCTSTR upMapPath,LPCTSTR MoveMapPath)
{
m_Wnd = hWnd;
m_ButID = butID;
strcpy(m_TitleName,titleName);
if (backMapPath != NULL)
{
if (m_pButBackBitmap)
{
delete m_pButBackBitmap;
}
HBITMAP hBitmap = LoadImageFromFile(backMapPath);
if (hBitmap)
{
m_pButBackBitmap = new CBitmap;
m_pButBackBitmap->Attach(hBitmap);
}
}
if (upMapPath != NULL)
{
if (m_pButUpMapBitmap)
{
delete m_pButUpMapBitmap;
}
HBITMAP hBitmap = LoadImageFromFile(upMapPath);
if (hBitmap)
{
m_pButUpMapBitmap = new CBitmap;
m_pButUpMapBitmap->Attach(hBitmap);
}
}
if (MoveMapPath != NULL)
{//LPCTSTR
if (m_pButMoveMapBitmap)
{
delete m_pButMoveMapBitmap;
}
HBITMAP hBitmap = LoadImageFromFile(MoveMapPath);
if (hBitmap)
{
m_pButMoveMapBitmap = new CBitmap;
m_pButMoveMapBitmap->Attach(hBitmap);
}
}
HWND wnd = ::GetDlgItem(m_Wnd,butID);
::GetWindowRect(wnd,m_Rect);
}
void CLButton::SetIrreGular(COLORREF rgb,bool isIrreGular)
{
m_IrreGularRGB = rgb;
m_isIrreGular = isIrreGular;
}
void CLButton::SetButFont(int hight,int with,COLORREF rgb,char *cFaceName)
{
m_butFont.hight = hight;
m_butFont.with = with;
m_butFont.rgb = rgb;
strcpy(m_butFont.cFaceName,cFaceName);
}
void CLButton::Show(int show)
{
m_Show = show;
HWND wnd = ::GetDlgItem(m_Wnd,m_ButID);
::ShowWindow(wnd,m_Show);
}
void CLButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
if (m_Show == SW_HIDE)
return ;
//从lpDrawItemStruct获取控件的相关信息
CRect rect = lpDrawItemStruct->rcItem;
CDC *pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
int nSaveDC =pDC->SaveDC();
UINT state = lpDrawItemStruct->itemState;
CBitmap bitmap;
bitmap.CreateCompatibleBitmap(pDC,m_Rect.Width(),m_Rect.Height());
CDC hDC;
hDC.CreateCompatibleDC(pDC);
hDC.SelectObject(&bitmap);
UpdataButton(&hDC,state);
if (!m_isIrreGular)
pDC->BitBlt(0,0,m_Rect.Width(),m_Rect.Height(),&hDC,0,0,SRCCOPY);
else
TransparentBlt(pDC,0,0,m_Rect.Width(),m_Rect.Height(),&hDC,0,0,m_Rect.Width(),m_Rect.Height(),m_IrreGularRGB);
bitmap.DeleteObject();
hDC.DeleteDC();
pDC->RestoreDC(nSaveDC);
}
void CLButton::UpdataButton(CDC *pDC,UINT state)
{
if (m_pButBackBitmap)
{
CDC hdc;
hdc.CreateCompatibleDC(pDC);
hdc.SelectObject(m_pButBackBitmap);
BITMAP *pBitMap= new BITMAP;
m_pButBackBitmap->GetBitmap(pBitMap);
pDC->TransparentBlt(0,0,m_Rect.Width(),m_Rect.Height(),&hdc,0,0,pBitMap->bmWidth,pBitMap->bmHeight,SRCCOPY);
delete pBitMap;
hdc.DeleteDC();
}
//获取按钮的状态
if (state & ODS_FOCUS)
{
if (m_pButUpMapBitmap)
{
CDC hdc;
hdc.CreateCompatibleDC(pDC);
hdc.SelectObject(m_pButUpMapBitmap);
BITMAP *pBitMap= new BITMAP;
m_pButUpMapBitmap->GetBitmap(pBitMap);
pDC->TransparentBlt(0,0,m_Rect.Width(),m_Rect.Height(),&hdc,0,0,pBitMap->bmWidth,pBitMap->bmHeight,SRCCOPY);
delete pBitMap;
hdc.DeleteDC();
}
}
else if (m_bOver&&m_pButMoveMapBitmap)
{
CDC hdc;
hdc.CreateCompatibleDC(pDC);
hdc.SelectObject(m_pButMoveMapBitmap);
BITMAP *pBitMap= new BITMAP;
m_pButMoveMapBitmap->GetBitmap(pBitMap);
pDC->TransparentBlt(0,0,m_Rect.Width(),m_Rect.Height(),&hdc,0,0,pBitMap->bmWidth,pBitMap->bmHeight,SRCCOPY);
delete pBitMap;
hdc.DeleteDC();
}
{
//写标题字体
CFont myFont; //创建字体对象
myFont.CreateFont(
m_butFont.hight, // nHeight
m_butFont.with, // nWidth
0, // nEscapement
120, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
m_butFont.cFaceName);
CFont *OldFont = pDC->SelectObject(&myFont);
pDC->SetBkMode(0);
pDC->SetTextColor(m_butFont.rgb);
int nX = (m_Rect.Width() - m_butFont.with* strlen(m_TitleName))/2;
int nY = (m_Rect.Height() - m_butFont.hight)/2;
pDC->TextOut(nX,nY,m_TitleName, strlen(m_TitleName));
pDC->SelectObject(OldFont);
}
}
void CLButton::TransparentBlt( CDC *pDC, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
CDC *hdcSrc, //
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
)
{
CBitmap hImageBMP;
hImageBMP.CreateCompatibleBitmap(pDC, nWidthDest, nHeightDest);
CBitmap hMaskBMP;
hMaskBMP.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
// 创建单色掩码位图
CDC hImageDC,hMaskDC;
hImageDC.CreateCompatibleDC(pDC);
hMaskDC.CreateCompatibleDC(pDC);
hImageDC.SelectObject(&hImageBMP);
hMaskDC.SelectObject(&hMaskBMP);
hImageDC.TransparentBlt(0, 0, nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
// 设置透明色
hImageDC.SetBkColor(crTransparent);
// 生成透明区域为白色,其它区域为黑色的掩码位图
hMaskDC.BitBlt(0, 0, nWidthDest, nHeightDest, &hImageDC, 0, 0, SRCCOPY);
// 生成透明区域为黑色,其它区域保持不变的位图
hImageDC.SetBkColor(RGB(0,0,0));
hImageDC.SetTextColor(RGB(255,255,255));
hImageDC.BitBlt(0, 0, nWidthDest, nHeightDest, &hMaskDC, 0, 0, SRCAND);
// 透明部分保持屏幕不变,其它部分变成黑色
COLORREF OldBkColor = pDC->SetBkColor(RGB(255,255,255));
COLORREF OldTextColor = pDC->SetTextColor(RGB(0,0,0));
pDC->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, &hMaskDC, 0, 0, SRCAND);
// "或"运算,生成最终效果
pDC->BitBlt(nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, &hImageDC, 0, 0, SRCPAINT);
// 清理、恢复
hImageDC.DeleteDC();
hMaskDC.DeleteDC();
hImageBMP.DeleteObject();
hMaskBMP.DeleteObject();
}
BOOL CLButton::OnClicked()
{
SetFocus();
return FALSE;
}
UINT CLButton::OnGetDlgCode()
{
UINT nCode = CButton::OnGetDlgCode();
nCode |= (1 ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON);
return nCode;
}
LRESULT CLButton::OnSetStyle(WPARAM wParam, LPARAM lParam)
{
UINT nNewType = (wParam & BS_TYPEMASK);
if (nNewType == BS_DEFPUSHBUTTON)
{
m_bIsDefault = TRUE;
}
else if (nNewType == BS_PUSHBUTTON)
{
m_bIsDefault = FALSE;
}
return DefWindowProc(BM_SETSTYLE,(wParam & ~BS_TYPEMASK) | BS_OWNERDRAW, lParam);
}
猜你喜欢
转载自uhq953df.iteye.com/blog/1357739
今日推荐
周排行