📄 bmpbutton.cpp
字号:
// BMPButton.cpp : implementation file
//
#include "stdafx.h"
#include "BMPButton.h"
#include "tools.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CBMPButton
CBMPButton::CBMPButton()
{
m_pBuffer = NULL;
m_iBufferLen = 0;
m_hBitmap = NULL;
m_color = RGB(233, 247, 229);
m_iLeftTopOffset = 0;
m_iRightBottomOffset = 0;
}
CBMPButton::~CBMPButton()
{
if(m_pBuffer)
{
delete[] m_pBuffer;
}
}
BEGIN_MESSAGE_MAP(CBMPButton, CButton)
//{{AFX_MSG_MAP(CBMPButton)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_WM_MOUSEMOVE()
ON_MESSAGE(WM_MOUSELEAVE,OnMouseOut)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CBMPButton message handlers
BOOL CBMPButton::OnEraseBkgnd( CDC* pDC)
{
RECT rcClient;
this->GetClientRect(&rcClient);
HBRUSH hOldBrush;
HBRUSH hBrush = ::CreateSolidBrush(m_color);
hOldBrush = (HBRUSH)pDC->SelectObject(hBrush);
pDC->Rectangle(&rcClient);
pDC->SelectObject(hOldBrush);
::DeleteObject(hBrush);
return TRUE;
}
//-------------------------------------------------------------------------------
void CBMPButton::OnPaint()
{
CButton::OnPaint();
}
//-------------------------------------------------------------------------------
void CBMPButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
CDC *pDC =CDC::FromHandle(lpDIS->hDC);
CRect rtControl(lpDIS->rcItem);
CPen pen,*old_pen;
CBrush brush,*old_brush;
CString strText;
HFONT hOldFont = (HFONT)pDC->SelectObject ((HFONT)::GetStockObject (DEFAULT_GUI_FONT));
UINT state =lpDIS->itemState;
if(state & ODS_FOCUS)
{
rtControl.DeflateRect(1,1); //拥有焦点矩形变小
}
COLORREF crBorder =::GetSysColor(COLOR_HIGHLIGHT);
pen.CreatePen(PS_SOLID, 1, crBorder);
if( state & ODS_SELECTED)
{
//按钮按下时
brush.CreateSolidBrush(HLS_TRANSFORM(crBorder,+50,-50));
pDC->SetTextColor(RGB(240,240,240));
}
else
{
//鼠标在区域内
brush.CreateSolidBrush(HLS_TRANSFORM(crBorder,+90,-66));
pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT));
}
if(state &ODS_DISABLED)
pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));//灰色字:禁用状态
else if(state & ODS_SELECTED)
pDC->SetTextColor(RGB(240,240,240)); //白色字:PUSH状态
else if(MouseOver())
pDC->SetTextColor(0); //黑色字:热感应状态
else
pDC->SetTextColor(::GetSysColor(COLOR_BTNTEXT)); //黑色字:普通状态
old_brush=pDC->SelectObject(&brush);
old_pen =pDC->SelectObject(&pen);
pDC->Rectangle(rtControl);
pDC->SetBkMode(TRANSPARENT);
GetWindowText(strText);
pDC->DrawText(strText,rtControl,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
if(state & ODS_FOCUS)
{
rtControl.DeflateRect(3,3);
pDC->DrawFocusRect(rtControl);
}
pDC->SelectObject(old_pen);
pDC->SelectObject(old_brush);
pDC->SelectObject(hOldFont);
Display();
}
//-------------------------------------------------------------------------------
void CBMPButton::PreSubclassWindow( )
{
ModifyStyle(0,BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
//-------------------------------------------------------------------------------
BOOL CBMPButton::OpenBmpFile(void)
{
static char BASED_CODE szFilter[] = "BMP Files (*.bmp)|*.bmp|All Files (*.*)|*.*||";
CFileDialog dlg(TRUE,"BMP",NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter);
if(dlg.DoModal() == IDOK)
{
CString strFilePath = dlg.GetPathName();
return(setBmpFile(strFilePath));
}
return FALSE;
}
//-------------------------------------------------------------------------------
void CBMPButton::getData(char* pBuffer, int& iDataLen)
{
if(pBuffer)
{
memcpy(pBuffer, m_pBuffer, m_iBufferLen);
}
iDataLen = m_iBufferLen;
}
//-------------------------------------------------------------------------------
CString CBMPButton::getImagePath(void)
{
return m_strImagePath;
}
//-------------------------------------------------------------------------------
void CBMPButton::setOffset(int iLeftTop, int iRightBottom)
{
m_iLeftTopOffset = iLeftTop;
m_iRightBottomOffset = iRightBottom;
}
//-------------------------------------------------------------------------------
void CBMPButton::setColor(COLORREF color)
{
m_color = color;
}
//-------------------------------------------------------------------------------
BOOL CBMPButton::setBmpFile(CString& strFileName)
{
CFile file;
if( !file.Open( strFileName, CFile::modeRead) )
return FALSE;
int iFileLen = file.GetLength();
char* pData = new char[iFileLen];
if(file.ReadHuge(pData,iFileLen) != iFileLen)
return FALSE;
m_strImagePath = strFileName;
BOOL bResult = setBmpData(pData, iFileLen);
delete[] pData;
return bResult;
}
//-----------------------------------------------------------------------------
BOOL CBMPButton::setBmpData(char* pData, int iDataLen)
{
m_bFirst = true;
if(iDataLen <= 0)
{
return FALSE;
}
if(m_iBufferLen < iDataLen)
{
delete[] m_pBuffer;
m_pBuffer = new char[iDataLen];
m_iBufferLen = iDataLen;
}
if(!m_pBuffer)
{
return FALSE;
}
memcpy(m_pBuffer, pData, iDataLen);
if(BufferToHBITMAP() == NULL)
{
return FALSE;
}
Display();
return TRUE;
}
//-----------------------------------------------------------------------------
void CBMPButton::Display(void)
{
if(NULL == m_hBitmap)
{
return;
}
CDC* pDC = this->GetDC();
HBITMAP OldBitmap;
CDC MemDC;
MemDC.CreateCompatibleDC(pDC);
OldBitmap=(HBITMAP)MemDC.SelectObject(m_hBitmap);
RECT rcBmpButton;
GetWindowRect(&rcBmpButton);
CWnd* pParentWnd = this->GetParent();
if(m_bFirst)
{
RECT rcParentWnd;
pParentWnd->GetWindowRect(&rcParentWnd);
RECT rcNewPos;
rcNewPos.top = rcBmpButton.top - rcParentWnd.top;
rcNewPos.left = rcBmpButton.left - rcParentWnd.left;
rcNewPos.right = rcNewPos.left + m_iWidth+ m_iLeftTopOffset + m_iRightBottomOffset;
rcNewPos.bottom = rcNewPos.top + m_iHeight + m_iLeftTopOffset + m_iRightBottomOffset;
this->MoveWindow(&rcNewPos);
m_bFirst = false;
}
pDC->BitBlt(m_iLeftTopOffset,m_iLeftTopOffset,m_iWidth,m_iHeight,&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(OldBitmap);
}
//-----------------------------------------------------------------------------
HBITMAP CBMPButton::BufferToHBITMAP()
{
if(m_hBitmap)
{
::DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
LPSTR hDIB;
LPSTR lpBuffer = m_pBuffer;
LPVOID lpDIBBits;
BITMAPFILEHEADER bmfHeader;
DWORD bmfHeaderLen;
bmfHeaderLen = sizeof(bmfHeader);
strncpy((LPSTR)&bmfHeader,(LPSTR)lpBuffer,bmfHeaderLen);
if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B')) return NULL;
hDIB = lpBuffer + bmfHeaderLen;
BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ;
BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ;
m_iWidth = bmInfo.bmiHeader.biWidth;
m_iHeight = bmInfo.bmiHeader.biHeight;
int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 << bmiHeader.biBitCount;
if( bmInfo.bmiHeader.biBitCount > 8 )
lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) +
((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0));
else
lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors);
CDC* pDC = this->GetDC();
m_hBitmap = CreateDIBitmap(pDC->m_hDC,&bmiHeader,CBM_INIT,lpDIBBits,&bmInfo,DIB_RGB_COLORS);
return m_hBitmap;
}
//-----------------------------------------------------------------------------------------
//返回鼠标是否在按钮区域内
BOOL CBMPButton::MouseOver()
{
return m_bOver;
}
//-----------------------------------------------------------------------------------------
void CBMPButton::OnMouseOut ()
{
//鼠标已离开按钮区域
m_bOver =FALSE;
//重绘按钮
InvalidateRect(NULL,FALSE);
}
//-----------------------------------------------------------------------------------------
void CBMPButton::OnMouseMove(UINT nFlags, CPoint point)
{
/*if(m_bOver ==FALSE)
{
//鼠标在按钮之上
m_bOver =TRUE;
//按钮重绘
InvalidateRect(NULL,FALSE);
//跟踪鼠标
//当鼠标离开按钮区域会收到WM_MOUSELEAVE,该消息直接调用OnMouseOut()
TRACKMOUSEEVENT tme;
tme.cbSize =sizeof(TRACKMOUSEEVENT);
tme.dwFlags =TME_LEAVE;
tme.dwHoverTime=0;
tme.hwndTrack =m_hWnd;
::TrackMouseEvent(&tme);
}*/
CButton::OnMouseMove(nFlags, point);
}
//-----------------------------------------------------------------------------------------
void CBMPButton::ClearBmp(void)
{
if(m_hBitmap)
{
::DeleteObject(m_hBitmap);
m_hBitmap = NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -