从CButton派生一个可检测按下状态和定时重复发送消息的按钮控件



// PressButton.h : header file
//
#pragma once

/////////////////////////////////////////////////////////////////////////////
// CPressButton window

class CPressButton : public CButton
{
  // Construction
public:
  CPressButton();
  
  // Attributes
public:
  UINT m_RepeateIntTick; //重复间隔ms =0时不重复
  BOOL m_bIsPressedFlag; //按下标记?

  // Operations
public:
  
  // Overrides
  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CPressButton)
  //}}AFX_VIRTUAL
  
  // Implementation
public:
  virtual ~CPressButton();
  
  // Generated message map functions
protected:
  //{{AFX_MSG(CPressButton)
  afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
  afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
  afx_msg void OnTimer(UINT nIDEvent);
  afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
  afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
  //}}AFX_MSG
  
  DECLARE_MESSAGE_MAP()
    
protected:
  BOOL m_bTimeStarted; //定时器已启动?  
  void BeginClickEvent(); //处理按下事件
  void EndClickEvent(); //处理抬起事件
  void PostClickMsg(); //发送消息
};

/////////////////////////////////////////////////////////////////////////////


// PressButton.cpp : implementation file

#include "stdafx.h"
#include "PressButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPressButton

CPressButton::CPressButton()
{
  m_bIsPressedFlag = FALSE;
  m_bTimeStarted = FALSE;
  m_RepeateIntTick = 1000; //重复间隔ms
}

CPressButton::~CPressButton()
{
}


BEGIN_MESSAGE_MAP(CPressButton, CButton)
//{{AFX_MSG_MAP(CPressButton)
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDOWN()
ON_WM_TIMER()
ON_WM_KEYDOWN()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPressButton message handlers

void CPressButton::OnLButtonUp(UINT nFlags, CPoint point) 
{
  // TODO: Add your message handler code here and/or call default
  EndClickEvent();
  CButton::OnLButtonUp(nFlags, point);
}

void CPressButton::OnLButtonDown(UINT nFlags, CPoint point) 
{
  // TODO: Add your message handler code here and/or call default
  BeginClickEvent();  
  CButton::OnLButtonDown(nFlags, point);
}

void CPressButton::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
  // TODO: Add your message handler code here and/or call default
  BeginClickEvent();
  CButton::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CPressButton::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
  // TODO: Add your message handler code here and/or call default
  EndClickEvent();
  CButton::OnKeyUp(nChar, nRepCnt, nFlags);
}

void CPressButton::OnTimer(UINT nIDEvent) 
{
  // TODO: Add your message handler code here and/or call default
  if(nIDEvent == 1)
  {
    PostClickMsg();
  }
  
  CButton::OnTimer(nIDEvent);
}

void CPressButton::BeginClickEvent()
{
  if(!m_bIsPressedFlag)    
  {
    PostClickMsg();
    SetCapture();
    m_bIsPressedFlag = TRUE;
  }
  
  if((!m_bTimeStarted) && m_RepeateIntTick > 0)
  {    
    SetTimer(1, m_RepeateIntTick, NULL);
    m_bTimeStarted = TRUE;
  }  
}

void CPressButton::EndClickEvent()
{
  if(m_bTimeStarted)
  {
    KillTimer(1);
    m_bTimeStarted = FALSE;
  }
  
  if(m_bIsPressedFlag)
  {    
    ReleaseCapture();
    m_bIsPressedFlag = FALSE;
  }
}

void CPressButton::PostClickMsg()
{
  GetParent()->PostMessage(WM_COMMAND, 
    MAKEWPARAM(GetDlgCtrlID(), BN_CLICKED), (LPARAM)m_hWnd);
}



猜你喜欢

转载自blog.csdn.net/zgl7903/article/details/71437641