用MFC自绘按钮,处理的消息包括WM_MOUSEHOVER、WM_MOUSELEAVE、WM_LBUTTONDOWN

 

//PicButton.h

class CPicButton : public CButton
{
 // Construction
public:
 CPicButton();
   
 BOOL  bTrackLeave;
 BOOL  bBottonDown;
    DWORD dwMouseStatus[2];
 
 typedef enum tagStatus
 {
  emNormal,
  emHover
 }tStatus;
 
 tStatus tIndex;
 // Attributes
public:
 
 // Operations
public:
 void TraceMouseEvent();
 // Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CPicButton)
public:
 virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
protected:
 virtual void PreSubclassWindow();
 virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam);
 //}}AFX_VIRTUAL
 
 // Implementation
public:
 virtual ~CPicButton();
 
 // Generated message map functions
protected:
 //{{AFX_MSG(CPicButton)
 afx_msg void OnMouseMove(UINT nFlags, CPoint point);
 //}}AFX_MSG
 
 DECLARE_MESSAGE_MAP()
};

 

 

//PicButton.cpp

CPicButton::CPicButton()
{
 tIndex = emNormal;
 bTrackLeave = TRUE;
 bBottonDown = FALSE;
}

CPicButton::~CPicButton()
{
}


BEGIN_MESSAGE_MAP(CPicButton, CButton)
//{{AFX_MSG_MAP(CPicButton)
ON_WM_MOUSEMOVE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPicButton message handlers

void CPicButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 CDC cMemCD,cBmpCD;
 CRect rc;
 HGDIOBJ holdbitmap,hold;
 GetClientRect(rc);
 HBITMAP hBitMap = (HBITMAP)dwMouseStatus[tIndex];
 BITMAP bm;
 ::GetObject(hBitMap,sizeof(BITMAP),&bm);
 
 cMemCD.CreateCompatibleDC(CDC::FromHandle(lpDrawItemStruct->hDC));
 CBitmap bitmap,*oldbitmap;
 bitmap.CreateCompatibleBitmap(CDC::FromHandle(lpDrawItemStruct->hDC),rc.Width(),rc.Height());//兼容视图由设备DC创建,而非兼容DC
 holdbitmap = cMemCD.SelectObject(bitmap);
   
 cBmpCD.CreateCompatibleDC(CDC::FromHandle(lpDrawItemStruct->hDC));
 hold = ::SelectObject(cBmpCD.GetSafeHdc(),hBitMap);
 
    ::StretchBlt(cMemCD.GetSafeHdc(),0,0,rc.Width(),rc.Height(),cBmpCD.GetSafeHdc(),0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
    ::SelectObject(cBmpCD.GetSafeHdc(),hold);
 
 CBrush brush;
 brush.CreateSolidBrush(RGB(0,0,255));
 cMemCD.FrameRect(rc,&brush);
    (CDC::FromHandle(lpDrawItemStruct->hDC))->BitBlt(0,0,rc.Width(),rc.Height(),&cMemCD,0,0,SRCCOPY);
 cMemCD.SelectObject(holdbitmap);
 
 bitmap.DeleteObject();
 CString str;
 GetWindowText(str);
 
 COLORREF crold;
 crold = ::SetTextColor(lpDrawItemStruct->hDC, RGB(17, 35, 113));
 ::SetBkMode(lpDrawItemStruct->hDC, TRANSPARENT);
    if (TRUE == bBottonDown)
    {
  CRect rc1;
  rc1 = lpDrawItemStruct->rcItem;
  rc1.OffsetRect(2,1);
  ::DrawText(lpDrawItemStruct->hDC,str,str.GetLength(),rc1,DT_VCENTER|DT_SINGLELINE|DT_CENTER);
  bBottonDown = FALSE;
    }
    else
 {
        ::DrawText(lpDrawItemStruct->hDC,str,str.GetLength(),rc,DT_VCENTER|DT_SINGLELINE|DT_CENTER);
 }
 
 ::SetTextColor(lpDrawItemStruct->hDC,crold);
 
}

void CPicButton::PreSubclassWindow()
{
 BITMAP bm;
 CRect rc;
 GetClientRect(rc);
 dwMouseStatus[emNormal] = (DWORD)LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP2));
 dwMouseStatus[emHover] = (DWORD)LoadBitmap(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDB_BITMAP1));
 ::GetObject((HBITMAP)dwMouseStatus[emNormal],sizeof(BITMAP),&bm);
 SetWindowPos(NULL,0,0,rc.Width(),bm.bmHeight,SWP_NOMOVE|SWP_NOZORDER);
 
 CButton::PreSubclassWindow();
}

LRESULT CPicButton::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
 switch(message)
 {
 case WM_MOUSEHOVER:
  {
   tIndex = emHover;
   Invalidate();
  }
  break;
 case WM_MOUSELEAVE:
  {
   bTrackLeave = TRUE;
   tIndex = emNormal;
    Invalidate();
  }
  break;
 case WM_LBUTTONDOWN:
  {
   if (FALSE == bBottonDown)
   {
    bBottonDown = TRUE;
   }
  }
  break;
 default:
  break;
 }
 return CButton::DefWindowProc(message, wParam, lParam);
}

void CPicButton::TraceMouseEvent()
{
 TRACKMOUSEEVENT tEventTrack = {0};
 tEventTrack.cbSize = sizeof(tEventTrack);
 tEventTrack.dwFlags = TME_HOVER|TME_LEAVE;
 tEventTrack.dwHoverTime = 1;
 tEventTrack.hwndTrack = GetSafeHwnd();
 BOOL bRet = _TrackMouseEvent(&tEventTrack);
}


void CPicButton::OnMouseMove(UINT nFlags, CPoint point)
{
 if (bTrackLeave)
 {
  TraceMouseEvent();
  bTrackLeave = FALSE;
 }
 CButton::OnMouseMove(nFlags, point);
}

 

你可能感兴趣的:(用MFC自绘按钮,处理的消息包括WM_MOUSEHOVER、WM_MOUSELEAVE、WM_LBUTTONDOWN)