如何区分MFC中CSpinButtonCtrl控件的上下箭头按下事件?
嘿,我来帮你解决这个区分CSpinButtonCtrl上下箭头按下的问题!其实有两种实用的方法,一种可以直接在你现有的OnPointerdown事件里处理,另一种是用控件自带的标准通知消息,更推荐后者哦:
方法一:在OnPointerdown中通过坐标判断
既然你已经在使用OnPointerdown事件,那可以通过获取触摸/点击的坐标,判断它落在控件的上半区还是下半区来区分上下箭头:
- 从
lParam中取出POINTER_INFO结构体,获取指针的屏幕位置; - 将屏幕坐标转换为控件的客户区坐标;
- 获取控件的客户区矩形,计算垂直方向的中点;
- 根据点击位置的Y坐标和中点对比,判断是上箭头还是下箭头。
具体代码如下:
afx_msg LRESULT CMySpinButtonCtrl::OnPointerdown(WPARAM wParam, LPARAM lParam) { if(IS_POINTER_PRIMARY_WPARAM(wParam)) { POINTER_INFO* pPointerInfo = reinterpret_cast<POINTER_INFO*>(lParam); if (pPointerInfo != nullptr) { // 获取指针的屏幕坐标并转换为客户区坐标 POINT ptScreen = { pPointerInfo->ptPixelLocation.x, pPointerInfo->ptPixelLocation.y }; ScreenToClient(&ptScreen); // 获取控件客户区并计算垂直中点 RECT rcClient; GetClientRect(&rcClient); int nMidY = rcClient.top + (rcClient.bottom - rcClient.top) / 2; // 判断点击区域 if (ptScreen.y < nMidY) { // 上箭头被按下,这里写你的逻辑 AfxMessageBox(_T("上箭头按下")); } else { // 下箭头被按下,这里写你的逻辑 AfxMessageBox(_T("下箭头按下")); } } } return 0; }
方法二:处理UDN_DELTAPOS标准通知消息(推荐)
其实更靠谱的方式是使用CSpinButtonCtrl自带的UDN_DELTAPOS通知消息,这个消息专门用于通知控件数值即将改变,并且直接包含了操作方向的信息,不管是鼠标点击、键盘操作还是触摸触发,都会触发这个消息:
步骤1:声明消息处理函数
在你的自定义spin控件类的头文件中添加函数声明:
afx_msg void OnDeltapos(NMHDR* pNMHDR, LRESULT* pResult);
步骤2:添加消息映射
在类的.cpp文件的消息映射中添加:
BEGIN_MESSAGE_MAP(CMySpinButtonCtrl, CSpinButtonCtrl) ON_WM_POINTERDOWN() // 保留你原来的指针事件映射(如果需要) ON_NOTIFY_REFLECT(UDN_DELTAPOS, &CMySpinButtonCtrl::OnDeltapos) END_MESSAGE_MAP()
步骤3:实现处理函数
在函数中通过NM_UPDOWN结构体的iDelta值判断方向:
iDelta > 0:上箭头被按下,数值即将增加iDelta < 0:下箭头被按下,数值即将减少
代码示例:
void CMySpinButtonCtrl::OnDeltapos(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = reinterpret_cast<NM_UPDOWN*>(pNMHDR); if (pNMUpDown->iDelta > 0) { // 上箭头触发,这里写你的逻辑 AfxMessageBox(_T("上箭头触发,数值即将增加")); } else if (pNMUpDown->iDelta < 0) { // 下箭头触发,这里写你的逻辑 AfxMessageBox(_T("下箭头触发,数值即将减少")); } *pResult = 0; // 设置为0允许数值改变,若要阻止数值变化可设为1 }
注意:这个方法不需要自己处理坐标,是控件原生的通知机制,兼容性和可靠性都更好,更推荐作为首选方案。
内容的提问来源于stack exchange,提问作者Alberto Bricio
相关产品推荐
相关产品推荐

