这次采用自绘BUTTON的方式实现在不同情况下BUTTON展示出来不同的图。 // SkinButton.cpp : implementation file // #include "stdafx.h" #include "TEST2.h" #include "SkinButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif / // CSkinButton CSkinButton::CSkinButton() //自己新建的基于CButton的类 { } CSkinButton::~CSkinButton() { } BEGIN_MESSAGE_MAP(CSkinButton, CButton) //{{AFX_MSG_MAP(CSkinButton) ON_WM_MOUSEMOVE() ON_WM_TIMER() ON_WM_LBUTTONDOWN() //}}AFX_MSG_MAP END_MESSAGE_MAP() / // CSkinButton message handlers //DEL void CSkinButton::Init(CString strTipText) //DEL { //DEL m_ToolTip.UpdateTipText(strTipText,this); //CToolTipCtrl m_ToolTip //DEL } void CSkinButton::PreSubclassWindow() //重载虚函数 { // TODO: Add your specialized code here and/or call the base class m_ToolTip.Create(this); m_ToolTip.SetDelayTime(100); //0.1s延迟时间工具提示 //m_ToolTip.SetMaxTipWidth(200); m_ToolTip.AddTool(this); CButton::PreSubclassWindow(); } BOOL CSkinButton::PreTranslateMessage(MSG* pMsg) //重载虚函数 { // TODO: Add your specialized code here and/or call the base class m_ToolTip.RelayEvent(pMsg); //调用这个函数传递一个鼠标消息的工具 return CButton::PreTranslateMessage(pMsg); } void CSkinButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: Add your code to draw the specified item UINT nID; CDC* pDC; pDC=CDC::FromHandle(lpDrawItemStruct->hDC); //控件对应的绘图设备句柄 UINT nState=lpDrawItemStruct->itemState; //控件状态 if(m_bMouseOver&&(!(nState & ODS_SELECTED))) //三种位图的选择 nID=m_nUp; else if(m_bMouseDown ) nID=m_nDown; else nID=m_nOver; CBitmap bitmap; BITMAP m_Bitmap; CDC MemDC; bitmap.LoadBitmap(nID); MemDC.CreateCompatibleDC(pDC); MemDC.SelectObject(&bitmap); //选择一对象到指定的设备上下文环境 bitmap.GetBitmap(&m_Bitmap); pDC->BitBlt(0,0,m_Bitmap.bmWidth,m_Bitmap.bmHeight,&MemDC,0,0,SRCCOPY); //直接复制源设备区域到目标设备中 bitmap.DeleteObject(); MemDC.DeleteDC(); } void CSkinButton::Init(UINT nNormalID, UINT nMouseOverID,UINT nMouseDownID, CString strTipText) { m_nOver=nNormalID; //没按下时原始的BUTTON位图 m_nUp=nMouseOverID; //鼠标移到BUTTON上时的位图 m_nDown=nMouseDownID; //按下BUTTON的位图 if (IDB_PLAY_OVER==m_nOver) { m_bPlayorStop=TRUE; } else m_bPlayorStop=FALSE; m_ToolTip.UpdateTipText(strTipText,this); //CToolTipCtrl m_ToolTip BITMAP m_Bitmap; CRect rect; CBitmap bitmap; bitmap.LoadBitmap(m_nOver); bitmap.GetBitmap(&m_Bitmap); GetWindowRect(&rect); //根据图象的大小调整按钮大小 GetParent()->ScreenToClient(&rect); rect.right=rect.left+m_Bitmap.bmWidth; rect.bottom=rect.top+m_Bitmap.bmHeight; MoveWindow(&rect,TRUE); m_bMouseOver=FALSE; m_bMouseDown=FALSE; i=0; Invalidate(); } void CSkinButton::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if(m_bMouseDown==FALSE) { m_bMouseOver=TRUE; SetTimer(1,100,NULL); //0.1秒 Invalidate(); OnTimer(1); CButton::OnMouseMove(nFlags, point); } } void CSkinButton::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default POINT point; GetCursorPos(&point); ScreenToClient(&point); CRect rect; GetClientRect(&rect); if(!rect.PtInRect(point)){ //KillTimer(1); didn't use m_bMouseOver=FALSE; Invalidate(); } CButton::OnTimer(nIDEvent); } void CSkinButton::OnLButtonDown(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (m_bMouseDown==FALSE) m_bMouseDown=TRUE; if (m_bPlayorStop==TRUE) { m_ToolTip.UpdateTipText("停止",this); i+=1; } if(i==2) //下一次再按PLAY键的时候 { m_bMouseDown=FALSE; m_ToolTip.UpdateTipText("播放",this); i=0; } CButton::OnLButtonDown(nFlags, point); } 在C??Dlg中的OnInitDlg()函数中最后面(return TRUE前)加入以下代码: CRect rect; //设置窗口的大小和位置 rect.top=100; rect.left=100; rect.right=rect.left+400; rect.bottom=rect.top+200; MoveWindow(&rect,TRUE); //rect.right=1000; //rect.bottom=1000; rect.left=100; rect.top=0; m_btn.MoveWindow(&rect,TRUE); m_btn.Init(IDB_PLAY_OVER,IDB_PLAY_UP,IDB_STOP_OVER,"播放");