头文件。
Code
#if !defined(AFX_HOVERBUTTON_H__1155737E_628E_11D2_81B5_0020AFC24C58__INCLUDED_)
#define AFX_HOVERBUTTON_H__1155737E_628E_11D2_81B5_0020AFC24C58__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// HoverButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CHoverButton window
enum BUTTON_STATE{ BUTTON_OFF, BUTTON_ON, BUTTON_OVER, BUTTON_GREYED};
class CHoverButton : public CBitmapButton
{
// Construction
public:
// Constructor: default is to use buttons defined in our resources
CHoverButton();
// Attributes
public:
// The only way of accessing data from outside this class is to call these 2 functions
BUTTON_STATE GetButtonState(void) { return(m_ButtonState);};
BUTTON_STATE SetButtonState(BUTTON_STATE nState);
private:
BOOL m_bMouseTracking;
BUTTON_STATE m_ButtonState;
CBitmap m_bmpButtonDown;
CBitmap m_bmpButtonFocussed;
CBitmap m_bmpButtonUp;
CBitmap m_bmpButtonDisabled;
HWND m_hWndOld;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHoverButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
private:
// Called by OnMouseMove() when entering/leaving the button
void OnMouseLeave(void);
void OnMouseEnter(void);
// Implementation
public:
virtual ~CHoverButton();
BOOL LoadBitmaps(UINT nBitmapUp, UINT nBitmapDown, UINT nBitmapFocus, UINT nBitmapDisabled);
BOOL LoadBitmaps(LPCSTR lpszBitmapUp, LPCSTR lpszBitmapDown, LPCSTR lpszBitmapFocus, LPCSTR lpszBitmapDisabled);
void SizeToContent();
// Generated message map functions
protected:
//{{AFX_MSG(CHoverButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT, CPoint);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HOVERBUTTON_H__1155737E_628E_11D2_81B5_0020AFC24C58__INCLUDED_)
#if !defined(AFX_HOVERBUTTON_H__1155737E_628E_11D2_81B5_0020AFC24C58__INCLUDED_)
#define AFX_HOVERBUTTON_H__1155737E_628E_11D2_81B5_0020AFC24C58__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// HoverButton.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CHoverButton window
enum BUTTON_STATE{ BUTTON_OFF, BUTTON_ON, BUTTON_OVER, BUTTON_GREYED};
class CHoverButton : public CBitmapButton
{
// Construction
public:
// Constructor: default is to use buttons defined in our resources
CHoverButton();
// Attributes
public:
// The only way of accessing data from outside this class is to call these 2 functions
BUTTON_STATE GetButtonState(void) { return(m_ButtonState);};
BUTTON_STATE SetButtonState(BUTTON_STATE nState);
private:
BOOL m_bMouseTracking;
BUTTON_STATE m_ButtonState;
CBitmap m_bmpButtonDown;
CBitmap m_bmpButtonFocussed;
CBitmap m_bmpButtonUp;
CBitmap m_bmpButtonDisabled;
HWND m_hWndOld;
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CHoverButton)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
private:
// Called by OnMouseMove() when entering/leaving the button
void OnMouseLeave(void);
void OnMouseEnter(void);
// Implementation
public:
virtual ~CHoverButton();
BOOL LoadBitmaps(UINT nBitmapUp, UINT nBitmapDown, UINT nBitmapFocus, UINT nBitmapDisabled);
BOOL LoadBitmaps(LPCSTR lpszBitmapUp, LPCSTR lpszBitmapDown, LPCSTR lpszBitmapFocus, LPCSTR lpszBitmapDisabled);
void SizeToContent();
// Generated message map functions
protected:
//{{AFX_MSG(CHoverButton)
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT, CPoint);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_HOVERBUTTON_H__1155737E_628E_11D2_81B5_0020AFC24C58__INCLUDED_)
源码文件。
Code
// HoverButton.cpp : implementation file
//
#include "stdafx.h"
//#include "hovbutt.h"
#include "HoverButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHoverButton
BEGIN_MESSAGE_MAP(CHoverButton, CBitmapButton)
//{{AFX_MSG_MAP(CHoverButton)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHoverButton construction / destruction
CHoverButton::CHoverButton()
{
// To start with, the button is switched off and we are NOT tracking the mouse
m_ButtonState = BUTTON_OFF;
m_bMouseTracking = FALSE;
}
CHoverButton::~CHoverButton()
{
}
/////////////////////////////////////////////////////////////////////////////
// CHoverButton message handlers
void CHoverButton::OnMouseMove(UINT nFlags, CPoint point)
{
CBitmapButton::OnMouseMove(nFlags, point);
// 1. Mouse has moved and we are not tracking this button, or
// 2. mouse has moved and the cursor was not above this window
// == Is equivalent to WM_MOUSEENTER (for which there is no message)
if((!m_bMouseTracking || GetCapture()!=this) && (m_ButtonState == BUTTON_OFF))
{
OnMouseEnter();
}
else
{
if(m_ButtonState == BUTTON_OVER)
{
CRect rc;
GetClientRect(&rc);
if(!rc.PtInRect(point)) // The mouse cursor is no longer above this button
OnMouseLeave();
}
}
}
void CHoverButton::SizeToContent()
{
ASSERT(m_bmpButtonUp.m_hObject != NULL);
CSize bitmapSize;
BITMAP bmInfo;
VERIFY(m_bmpButtonUp.GetObject(sizeof(bmInfo), &bmInfo) == sizeof(bmInfo));
VERIFY(SetWindowPos(NULL, -1, -1, bmInfo.bmWidth, bmInfo.bmHeight,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE));
}
void CHoverButton::OnMouseEnter(void)
{
// We are now tracking the mouse, OVER this button
m_bMouseTracking = TRUE;
m_ButtonState = BUTTON_OVER;
// Ensure that mouse input is sent to the button
SetCapture();
Invalidate();
UpdateWindow();
}
void CHoverButton::OnMouseLeave(void)
{
// We are not tracking the mouse, this button is OFF.
m_ButtonState = BUTTON_OFF;
m_bMouseTracking = FALSE;
// Release mouse capture from the button and restore normal mouse input
Invalidate();
UpdateWindow();
ReleaseCapture();
}
void CHoverButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// Highlight button
SetButtonState(BUTTON_OFF);
m_ButtonState = BUTTON_ON;
CBitmapButton::OnLButtonDown(nFlags, point);
}
void CHoverButton::OnLButtonUp(UINT nFlags, CPoint point)
{
SetButtonState(BUTTON_ON); // Highlight button
m_ButtonState = BUTTON_OFF;
CBitmapButton::OnLButtonUp(nFlags, point);
}
// Purpose: Set the new state of the button
// Return: Returns the old state of the button
// Parameters: nState = Either ON or OFF. The default is OFF. This is NOT tri-state button!
BUTTON_STATE CHoverButton::SetButtonState(BUTTON_STATE nState)
{
BUTTON_STATE nOldState = (BUTTON_STATE)GetCheck();
m_ButtonState = nState;
switch(m_ButtonState)
{
case BUTTON_ON:
EnableWindow(TRUE);
SetState(BUTTON_ON);
break;
case BUTTON_GREYED:
EnableWindow(FALSE);
break;
case BUTTON_OVER:
EnableWindow(TRUE);
SetState(BUTTON_OVER);
break;
default:
EnableWindow(TRUE);
SetState(BUTTON_OFF);
m_ButtonState = BUTTON_OFF;
break;
}
return(nOldState);
}
// Draws the buttons in their relevant state, and text labels
void CHoverButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC memDC;
CBitmap* pOld=NULL;
CBitmap* pBitmap=NULL;
CDC* pDC;
CRect rc;
int iSaveDC;
pDC= CDC::FromHandle(lpDrawItemStruct->hDC);
memDC.CreateCompatibleDC(pDC);
VERIFY(pDC);
iSaveDC=pDC->SaveDC();
rc.CopyRect(&lpDrawItemStruct->rcItem);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(GetSysColor(COLOR_WINDOWFRAME));// Black text color
switch(m_ButtonState)
{
case BUTTON_ON:
pBitmap=&m_bmpButtonDown;
break;
case BUTTON_OVER:
pBitmap=&m_bmpButtonFocussed;
break;
case BUTTON_GREYED:
pBitmap=&m_bmpButtonDisabled;
break;
default:
pBitmap=&m_bmpButtonUp;
break;
}
CString strTitle;
GetWindowText(strTitle);
if (pBitmap->m_hObject)
{
CRect rcBitmap(rc);
BITMAP bmpInfo;
CSize size;
// Text
size = pDC->GetTextExtent(strTitle);
rcBitmap.OffsetRect(size.cx+5,0);
// Draw bitmap
if(!pBitmap->GetBitmap(&bmpInfo))
return;
pOld=memDC.SelectObject((CBitmap*) pBitmap);
if (pOld==NULL)
return; //Destructors will clean up
if(!pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY))
return;
memDC.SelectObject(pOld);
if(memDC==NULL)
return;
}
/*
CRect rcText(rc);
UINT nFormat = DT_CENTER;
if(m_ButtonState == BUTTON_GREYED)
{
rcText.OffsetRect(1,1);
pDC->SetTextColor(GetSysColor(COLOR_BTNHIGHLIGHT));
pDC->DrawText(strTitle,rcText,nFormat);
rcText.OffsetRect(-1,-1);
pDC->SetTextColor(GetSysColor(COLOR_BTNSHADOW));
pDC->DrawText(strTitle,rcText,nFormat);
}
else
pDC->DrawText(strTitle,rcText,nFormat);
*/
pDC->RestoreDC(iSaveDC);
}
BOOL CHoverButton::LoadBitmaps(UINT nBitmapUp, UINT nBitmapDown,
UINT nBitmapFocus, UINT nBitmapDisabled)
{
return LoadBitmaps(MAKEINTRESOURCE(nBitmapUp),
MAKEINTRESOURCE(nBitmapDown),
MAKEINTRESOURCE(nBitmapFocus),
MAKEINTRESOURCE(nBitmapDisabled));
}
BOOL CHoverButton::LoadBitmaps(LPCSTR lpszBitmapUp, LPCSTR lpszBitmapDown,
LPCSTR lpszBitmapFocus, LPCSTR lpszBitmapDisabled)
{
BOOL bAllLoaded=TRUE;
//Delete old ones
m_bmpButtonDown.DeleteObject();
m_bmpButtonFocussed.DeleteObject();
m_bmpButtonUp.DeleteObject();
m_bmpButtonDisabled.DeleteObject();
if (!m_bmpButtonUp.LoadBitmap(lpszBitmapUp))
{
TRACE0("Failed to load up bitmap of bitmap button\n");
return FALSE;
}
if (lpszBitmapDown!=NULL)
{
if (!m_bmpButtonDown.LoadBitmap(lpszBitmapDown))
{
TRACE0("Failed to load down bitmap of bitmap button\n");
return bAllLoaded=FALSE;
}
}
if (lpszBitmapFocus!=NULL)
{
if (!m_bmpButtonFocussed.LoadBitmap(lpszBitmapFocus))
{
TRACE0("Failed to load focussed bitmap of bitmap button\n");
return bAllLoaded=FALSE;
}
}
if (lpszBitmapDisabled!=NULL)
{
if (!m_bmpButtonDisabled.LoadBitmap(lpszBitmapDisabled))
{
TRACE0("Failed to load disabled bitmap of bitmap button\n");
return bAllLoaded=FALSE;
}
}
return bAllLoaded;
}
// HoverButton.cpp : implementation file
//
#include "stdafx.h"
//#include "hovbutt.h"
#include "HoverButton.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CHoverButton
BEGIN_MESSAGE_MAP(CHoverButton, CBitmapButton)
//{{AFX_MSG_MAP(CHoverButton)
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CHoverButton construction / destruction
CHoverButton::CHoverButton()
{
// To start with, the button is switched off and we are NOT tracking the mouse
m_ButtonState = BUTTON_OFF;
m_bMouseTracking = FALSE;
}
CHoverButton::~CHoverButton()
{
}
/////////////////////////////////////////////////////////////////////////////
// CHoverButton message handlers
void CHoverButton::OnMouseMove(UINT nFlags, CPoint point)
{
CBitmapButton::OnMouseMove(nFlags, point);
// 1. Mouse has moved and we are not tracking this button, or
// 2. mouse has moved and the cursor was not above this window
// == Is equivalent to WM_MOUSEENTER (for which there is no message)
if((!m_bMouseTracking || GetCapture()!=this) && (m_ButtonState == BUTTON_OFF))
{
OnMouseEnter();
}
else
{
if(m_ButtonState == BUTTON_OVER)
{
CRect rc;
GetClientRect(&rc);
if(!rc.PtInRect(point)) // The mouse cursor is no longer above this button
OnMouseLeave();
}
}
}
void CHoverButton::SizeToContent()
{
ASSERT(m_bmpButtonUp.m_hObject != NULL);
CSize bitmapSize;
BITMAP bmInfo;
VERIFY(m_bmpButtonUp.GetObject(sizeof(bmInfo), &bmInfo) == sizeof(bmInfo));
VERIFY(SetWindowPos(NULL, -1, -1, bmInfo.bmWidth, bmInfo.bmHeight,
SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW|SWP_NOACTIVATE));
}
void CHoverButton::OnMouseEnter(void)
{
// We are now tracking the mouse, OVER this button
m_bMouseTracking = TRUE;
m_ButtonState = BUTTON_OVER;
// Ensure that mouse input is sent to the button
SetCapture();
Invalidate();
UpdateWindow();
}
void CHoverButton::OnMouseLeave(void)
{
// We are not tracking the mouse, this button is OFF.
m_ButtonState = BUTTON_OFF;
m_bMouseTracking = FALSE;
// Release mouse capture from the button and restore normal mouse input
Invalidate();
UpdateWindow();
ReleaseCapture();
}
void CHoverButton::OnLButtonDown(UINT nFlags, CPoint point)
{
// Highlight button
SetButtonState(BUTTON_OFF);
m_ButtonState = BUTTON_ON;
CBitmapButton::OnLButtonDown(nFlags, point);
}
void CHoverButton::OnLButtonUp(UINT nFlags, CPoint point)
{
SetButtonState(BUTTON_ON); // Highlight button
m_ButtonState = BUTTON_OFF;
CBitmapButton::OnLButtonUp(nFlags, point);
}
// Purpose: Set the new state of the button
// Return: Returns the old state of the button
// Parameters: nState = Either ON or OFF. The default is OFF. This is NOT tri-state button!
BUTTON_STATE CHoverButton::SetButtonState(BUTTON_STATE nState)
{
BUTTON_STATE nOldState = (BUTTON_STATE)GetCheck();
m_ButtonState = nState;
switch(m_ButtonState)
{
case BUTTON_ON:
EnableWindow(TRUE);
SetState(BUTTON_ON);
break;
case BUTTON_GREYED:
EnableWindow(FALSE);
break;
case BUTTON_OVER:
EnableWindow(TRUE);
SetState(BUTTON_OVER);
break;
default:
EnableWindow(TRUE);
SetState(BUTTON_OFF);
m_ButtonState = BUTTON_OFF;
break;
}
return(nOldState);
}
// Draws the buttons in their relevant state, and text labels
void CHoverButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
CDC memDC;
CBitmap* pOld=NULL;
CBitmap* pBitmap=NULL;
CDC* pDC;
CRect rc;
int iSaveDC;
pDC= CDC::FromHandle(lpDrawItemStruct->hDC);
memDC.CreateCompatibleDC(pDC);
VERIFY(pDC);
iSaveDC=pDC->SaveDC();
rc.CopyRect(&lpDrawItemStruct->rcItem);
pDC->SetBkMode(TRANSPARENT);
pDC->SetTextColor(GetSysColor(COLOR_WINDOWFRAME));// Black text color
switch(m_ButtonState)
{
case BUTTON_ON:
pBitmap=&m_bmpButtonDown;
break;
case BUTTON_OVER:
pBitmap=&m_bmpButtonFocussed;
break;
case BUTTON_GREYED:
pBitmap=&m_bmpButtonDisabled;
break;
default:
pBitmap=&m_bmpButtonUp;
break;
}
CString strTitle;
GetWindowText(strTitle);
if (pBitmap->m_hObject)
{
CRect rcBitmap(rc);
BITMAP bmpInfo;
CSize size;
// Text
size = pDC->GetTextExtent(strTitle);
rcBitmap.OffsetRect(size.cx+5,0);
// Draw bitmap
if(!pBitmap->GetBitmap(&bmpInfo))
return;
pOld=memDC.SelectObject((CBitmap*) pBitmap);
if (pOld==NULL)
return; //Destructors will clean up
if(!pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0, 0, SRCCOPY))
return;
memDC.SelectObject(pOld);
if(memDC==NULL)
return;
}
/*
CRect rcText(rc);
UINT nFormat = DT_CENTER;
if(m_ButtonState == BUTTON_GREYED)
{
rcText.OffsetRect(1,1);
pDC->SetTextColor(GetSysColor(COLOR_BTNHIGHLIGHT));
pDC->DrawText(strTitle,rcText,nFormat);
rcText.OffsetRect(-1,-1);
pDC->SetTextColor(GetSysColor(COLOR_BTNSHADOW));
pDC->DrawText(strTitle,rcText,nFormat);
}
else
pDC->DrawText(strTitle,rcText,nFormat);
*/
pDC->RestoreDC(iSaveDC);
}
BOOL CHoverButton::LoadBitmaps(UINT nBitmapUp, UINT nBitmapDown,
UINT nBitmapFocus, UINT nBitmapDisabled)
{
return LoadBitmaps(MAKEINTRESOURCE(nBitmapUp),
MAKEINTRESOURCE(nBitmapDown),
MAKEINTRESOURCE(nBitmapFocus),
MAKEINTRESOURCE(nBitmapDisabled));
}
BOOL CHoverButton::LoadBitmaps(LPCSTR lpszBitmapUp, LPCSTR lpszBitmapDown,
LPCSTR lpszBitmapFocus, LPCSTR lpszBitmapDisabled)
{
BOOL bAllLoaded=TRUE;
//Delete old ones
m_bmpButtonDown.DeleteObject();
m_bmpButtonFocussed.DeleteObject();
m_bmpButtonUp.DeleteObject();
m_bmpButtonDisabled.DeleteObject();
if (!m_bmpButtonUp.LoadBitmap(lpszBitmapUp))
{
TRACE0("Failed to load up bitmap of bitmap button\n");
return FALSE;
}
if (lpszBitmapDown!=NULL)
{
if (!m_bmpButtonDown.LoadBitmap(lpszBitmapDown))
{
TRACE0("Failed to load down bitmap of bitmap button\n");
return bAllLoaded=FALSE;
}
}
if (lpszBitmapFocus!=NULL)
{
if (!m_bmpButtonFocussed.LoadBitmap(lpszBitmapFocus))
{
TRACE0("Failed to load focussed bitmap of bitmap button\n");
return bAllLoaded=FALSE;
}
}
if (lpszBitmapDisabled!=NULL)
{
if (!m_bmpButtonDisabled.LoadBitmap(lpszBitmapDisabled))
{
TRACE0("Failed to load disabled bitmap of bitmap button\n");
return bAllLoaded=FALSE;
}
}
return bAllLoaded;
}