📄 flybutton.cpp
字号:
// FlyButton.cpp : implementation file
//
#include "stdafx.h"
#include "WinSurge.h"
#include "FlyButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CFlyButton
CFlyButton::CFlyButton()
{
m_bHover = FALSE;
m_bDown = FALSE;
m_bDowned = FALSE;
m_bDrawed = FALSE;
}
CFlyButton::~CFlyButton()
{
m_Bitmap.DeleteObject();
}
BEGIN_MESSAGE_MAP(CFlyButton, CButton)
//{{AFX_MSG_MAP(CFlyButton)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_ENABLE()
ON_WM_LBUTTONDBLCLK()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CFlyButton message handlers
void CFlyButton::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_bHover)
{
CRect rc;
GetClientRect(&rc);
if(FALSE == rc.PtInRect(point))
{
m_bHover = FALSE;
m_bDown = FALSE;
if(FALSE == m_bDowned)
ReleaseCapture();
if(FALSE == m_bDrawed)
Invalidate();
m_bDrawed = TRUE;
}
else
{
if(TRUE == m_bDowned)
{
if(FALSE == m_bDown) // only redraw when down in control
{
m_bDrawed = FALSE;
m_bDown = TRUE;
Invalidate();
}
}
}
}
else
{
m_bHover = TRUE;
if(FALSE == m_bDowned)
{
m_bDrawed = FALSE;
SetCapture();
Invalidate();
}
}
CButton::OnMouseMove(nFlags, point);
}
void CFlyButton::PreSubclassWindow()
{
// TODO: Add your specialized code here and/or call the base class
::SetWindowLong(m_hWnd,GWL_STYLE,GetStyle()|BS_OWNERDRAW);
CButton::PreSubclassWindow();
}
void CFlyButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
CRect rc;
CRect rcText, rcBmp;
CString str;
BITMAP bmp;
//
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
rc.CopyRect(&(lpDrawItemStruct->rcItem));
pDC->SetBkMode(TRANSPARENT);
DrawFrame(pDC,rc);
GetWindowText(str);
TRACE("%s\t",str);
TRACE("DrawItem\n");
CSize szExtent = pDC->GetTextExtent(str);
m_Bitmap.GetBitmap(&bmp);
//
rcBmp.top = rc.top + (rc.Height()-bmp.bmHeight)/2;
rcBmp.bottom = rcBmp.top + bmp.bmHeight;
rcBmp.left = rc.left + (rc.Width()-szExtent.cx-bmp.bmWidth-10)/2;
rcBmp.right = rcBmp.left + bmp.bmWidth;
//
rcText.top = rc.top + (rc.Height()-szExtent.cy)/2;
rcText.bottom = rcText.top + szExtent.cy;
rcText.left = rcBmp.right +10;
rcText.right = rcText.left + szExtent.cx;
if(m_bDown)
{
rcBmp.InflateRect(-1,-1,1,1);
rcText.InflateRect(-1,-1,1,1);
}
DrawText(pDC,rcText);
DrawBitmap(pDC,rcBmp);
}
void CFlyButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
m_bDown = TRUE;
m_bDowned = TRUE;
Invalidate();
}
void CFlyButton::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_bDowned)
{
m_bDown = FALSE;
m_bDowned = FALSE;
CRect rc;
GetClientRect(&rc);
if(FALSE == rc.PtInRect(point))
{
m_bHover = FALSE;
ReleaseCapture();
}
else
{
Invalidate();
::SendMessage(GetParent()->GetSafeHwnd(),WM_COMMAND,
MAKEWPARAM(this->GetDlgCtrlID(),BN_CLICKED),LPARAM(m_hWnd));
if(::GetFocus() != m_hWnd)
m_bHover = FALSE;
}
Invalidate();
}
}
void CFlyButton::SetBitmap(UINT nID, COLORREF crf)
{
m_Bitmap.LoadBitmap(nID);
m_bkColor = crf;
}
void CFlyButton::DrawBitmap(CDC *pDC,LPRECT lpRect)
{
COLORREF crOldBack = pDC->SetBkColor(RGB(255,255,255));
COLORREF crOldText = pDC->SetTextColor(RGB(0,0,0));
int nWidth = lpRect->right - lpRect->left;
int nHeight = lpRect->bottom - lpRect->top;
int x = lpRect->left;
int y = lpRect->top;
CDC dcImage, dcTrans;
CBitmap *pOldBitmapTrans, *pOldBitmapImage;
// Create two memory dcs for the image and the mask
dcImage.CreateCompatibleDC(pDC);
dcTrans.CreateCompatibleDC(pDC);
// Create the mask bitmap
CBitmap bitmapTrans;
bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL);
// Select the mask bitmap into the appropriate dc
pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans);
BOOL bIsDis = GetStyle() & WS_DISABLED;
// Build mask based on transparent colour
if(!bIsDis)
pOldBitmapImage = dcImage.SelectObject(&m_Bitmap);
// Select the image into the appropriate dc
dcImage.SetBkColor(m_bkColor);
dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY);
// Do the work - True Mask method - cool if not actual display
// bg XOR bmp AND ??? XOR bmp
if(bIsDis)
{
//pDC->DrawState(CPoint(x,y),CSize(nWidth,nHeight),&m_Bitmap,DSS_DISABLED);
DitherBlt(pDC->m_hDC,x,y,nWidth,nHeight,m_Bitmap,0,0);
}
else
{
pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);
pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND);
pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT);
}
// Restore settings
if(!bIsDis)
dcImage.SelectObject(pOldBitmapImage);
dcTrans.SelectObject(pOldBitmapTrans);
pDC->SetBkColor(crOldBack);
pDC->SetTextColor(crOldText);
}
void CFlyButton::DrawFrame(CDC *pDC, LPRECT lpRect)
{
if(m_bHover)
{
pDC->Draw3dRect(lpRect,::GetSysColor(COLOR_3DHILIGHT),::GetSysColor(COLOR_3DSHADOW));
}
if(m_bDown)
{
pDC->Draw3dRect(lpRect,::GetSysColor(COLOR_3DSHADOW),::GetSysColor(COLOR_3DHILIGHT));
}
}
void CFlyButton::DrawText(CDC *pDC, LPRECT lpRect)
{
CString str;
GetWindowText(str);
UINT nFlags = (GetStyle() & WS_DISABLED)? DSS_DISABLED:DSS_NORMAL;
pDC->DrawState(CPoint(lpRect->left,lpRect->top),
CSize(lpRect->right-lpRect->left,lpRect->bottom - lpRect->top),
str,nFlags,TRUE,str.GetLength(),HBRUSH(NULL));
}
void CFlyButton::DitherBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HBITMAP hbm, int nXSrc, int nYSrc)
{
ASSERT(hdcDest && hbm);
ASSERT(nWidth > 0 && nHeight > 0);
// Create a generic DC for all BitBlts
HDC hDC = CreateCompatibleDC(hdcDest);
ASSERT(hDC);
if (hDC)
{
// Create a DC for the monochrome DIB section
HDC bwDC = CreateCompatibleDC(hDC);
ASSERT(bwDC);
if (bwDC)
{
// Create the monochrome DIB section with a black and white palette
struct {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[2];
} RGBBWBITMAPINFO = {
{ // a BITMAPINFOHEADER
sizeof(BITMAPINFOHEADER), // biSize
nWidth, // biWidth;
nHeight, // biHeight;
1, // biPlanes;
1, // biBitCount
BI_RGB, // biCompression;
0, // biSizeImage;
0, // biXPelsPerMeter;
0, // biYPelsPerMeter;
0, // biClrUsed;
0 // biClrImportant;
},
{
{ 0x00, 0x00, 0x00, 0x00 }, { 0xFF, 0xFF, 0xFF, 0x00 }
}
};
VOID *pbitsBW;
HBITMAP hbmBW = CreateDIBSection(bwDC,
(LPBITMAPINFO)&RGBBWBITMAPINFO, DIB_RGB_COLORS, &pbitsBW, NULL, 0);
ASSERT(hbmBW);
if (hbmBW)
{
// Attach the monochrome DIB section and the bitmap to the DCs
SelectObject(bwDC, hbmBW);
SelectObject(hDC, hbm);
// BitBlt the bitmap into the monochrome DIB section
BitBlt(bwDC, 0, 0, nWidth, nHeight, hDC, nXSrc, nYSrc, SRCCOPY);
// Paint the destination rectangle in gray
FillRect(hdcDest, CRect(nXDest, nYDest, nXDest + nWidth, nYDest +
nHeight), GetSysColorBrush(COLOR_3DFACE));
// BitBlt the black bits in the monochrome bitmap into COLOR_3DHILIGHT bits in the destination DC
// The magic ROP comes from the Charles Petzold's book
HBRUSH hb = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
HBRUSH oldBrush = (HBRUSH)SelectObject(hdcDest, hb);
BitBlt(hdcDest, nXDest + 1, nYDest + 1, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
// BitBlt the black bits in the monochrome bitmap into COLOR_3DSHADOW bits in the destination DC
hb = CreateSolidBrush(GetSysColor(COLOR_3DSHADOW));
DeleteObject(SelectObject(hdcDest, hb));
BitBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, bwDC, 0, 0, 0xB8074A);
DeleteObject(SelectObject(hdcDest, oldBrush));
}
VERIFY(DeleteDC(bwDC));
}
VERIFY(DeleteDC(hDC));
}
}
void CFlyButton::OnEnable(BOOL bEnable)
{
CButton::OnEnable(bEnable);
// TODO: Add your message handler code here
Invalidate();
}
void CFlyButton::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// SendMessage(WM_LBUTTONDOWN);
OnLButtonDown(nFlags,point);
CButton::OnLButtonDblClk(nFlags, point);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -