效果演示
上位机MFC高亮单选按钮实例
例程与Web页面中弹出按钮相似,鼠标上移会高亮。
使用用到一个集成类,类的头文件与源文件源代码在尾部,可以复制使用,
或下载工程源代码学习:
实现过程:
1.新建一个基于对话框的应用程序,并按上图添加按钮控件,并排版。
2.将工程根目录两文件HOVERBUTTON.CPP,HOVERBUTTON.G复制到自己工程目录中,
并载入到项目中,这样工程中就多出一个集成类,如图:
上位机MFC高亮单选按钮实例
3.在主对话框类中包含头文件#include "HoverButton.h",
并添加按钮对象,初始初始化
CHoverButton m_button4;
CHoverButton m_button3;
CHoverButton m_button2;
CHoverButton m_button1;
void CCBtnDlg:oDataExchange(CDataExchange* pDX)
{
CDialog:oDataExchange(pDX);
//{{AFX_DATA_MAP(CCBtnDlg)
// NOTE: the ClassWizard will add DDX and DDV calls here
DDX_Control(pDX, IDC_BUTTON4, m_button4);
DDX_Control(pDX, IDC_BUTTON3, m_button3);
DDX_Control(pDX, IDC_BUTTON2, m_button2);
DDX_Control(pDX, IDC_BUTTON1, m_button1);
//}}AFX_DATA_MAP
}
初始化按钮图标
m_button4.LoadBitmaps(IDB_RBU, IDB_RBD, IDB_RBF, IDB_RBX);
m_button3.LoadBitmaps(IDB_RBU, IDB_RBD, IDB_RBF, IDB_RBX);
m_button2.LoadBitmaps(IDB_RBU, IDB_RBD, IDB_RBF, IDB_RBX);
m_button1.LoadBitmaps(IDB_RBU, IDB_RBD, IDB_RBF, IDB_RBX);
使用的一些图标,可以使用目录内的,也可以自己创建,图标ID要一致
IDB_RBD
IDB_RBF
IDB_RBU
IDB_RBX
4.编译运行就可以看到效果,下面可以进一步实现按钮单选效果
添加函数与变量
int m_nSelected;
int RefreshButtons(int nSelected);
int CHovbuttDlg::RefreshButtons(int nSelected /*=0*/ )
{
m_button1.SetButtonState(BUTTON_OFF);
m_button2.SetButtonState(BUTTON_OFF);
m_button3.SetButtonState(BUTTON_GREYED);
m_button4.SetButtonState(BUTTON_OFF);
switch(nSelected)
{
case 2:
m_button2.SetButtonState(BUTTON_ON);
break;
case 3:
m_button3.SetButtonState(BUTTON_ON);
break;
case 4:
m_button4.SetButtonState(BUTTON_ON);
break;
default:
m_button1.SetButtonState(BUTTON_ON);
nSelected = 1;
m_nSelected = nSelected;
break;
}
return nSelected;
}
并在初始化时调用函数与初始变量
m_nSelected = 1;
// Redraw the buttons in their various states
RefreshButtons(m_nSelected);
然后是按钮的点击函数的实现
- void CCBtnDlg::OnButton1()
- {
- m_nSelected = 1;
- RefreshButtons(m_nSelected);
- // Do some process (1)
- }
- void CCBtnDlg::OnButton2()
- {
- m_nSelected = 2;
- RefreshButtons(m_nSelected);
- // Do some process (2)
- }
- void CCBtnDlg::OnButton3()
- {
- m_nSelected = 3;
- RefreshButtons(m_nSelected);
- // Do some process (3)
- }
- void CCBtnDlg::OnButton4()
- {
- m_nSelected = 4;
- RefreshButtons(m_nSelected);
- // Do some process (4)
- }
复制代码
5.执行编译,就可以运行例程查看效果了。下面是集成类文件的源代码
- #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);
- // 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
- 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_)
复制代码
- #include "stdafx.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()
- //}}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::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::OnLButtonUp(UINT nFlags, CPoint point)
- {
- SetButtonState(BUTTON_ON); // Highlight button
- 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_bitmapDisabled.LoadBitmap(lpszBitmapDisabled))
- {
- TRACE0("Failed to load disabled bitmap of bitmap button\n");
- return bAllLoaded=FALSE;
- }
- }
- return bAllLoaded;
- }
复制代码
|