CListCtrl。当双击总是收到 NM_CLICK + NM_DBLCLK
CListCtrl. When double click ALWAYS receive NM_CLICK + NM_DBLCLK
当我用鼠标双击时,总是收到两条消息 NM_CLICK
和 NM_DBLCLK
。为什么?
你知道我如何区分两者吗?
When I press double click with the mouse, I always get two messages NM_CLICK and then NM_DBLCLK. Why?
简答:因为系统没有实现时间机器。
当您用鼠标单击时,系统会生成 NM_CLICK
通知,因为它还不知道这是否是双击序列的开始。这允许应用程序立即响应鼠标单击事件,而无需等待双击超时到期。
要区分单击和双击,您必须推迟 NM_CLICK
处理,直到您知道它不是 NM_DBLCLK
序列的一部分。为此,请在 NM_CLICK
处理程序中设置一个计时器,并从 NM_DBLCLK
中终止计时器。定时器到时,就知道没有NM_DBLCLK
尾随,可以继续处理单击了。
下面应该给你一个想法,如何实现它:
enum TimerId {
TimerId_ListCtrlDblClk = 1
};
BOOL CMyDialog::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ) {
const NMHDR& hdr = *(const NMHDR*)lParam;
switch ( hdr.code ) {
case NM_CLICK:
SetTimer( TimerId_ListCtrlDblClk, ::GetDoubleClickTime(), nullptr );
*pResult = 0;
return TRUE;
case NM_DBLCLK:
KillTimer( TimerId_ListCtrlDblClk );
// Handle double-clicks here.
*pResult = 0;
return TRUE;
default:
break;
}
return CDialogEx::OnNotify( wParam, lParam, pResult );
}
void CMyDialog::OnTimer( UINT_PTR nIDEvent ) {
if ( nIDEvent == TimerId_ListBoxDblClk ) {
// If this timer expires, there is no NM_DBLCLK trailing the NM_CLICK.
// Handle the regular NM_CLICK notification.
}
CDialogEx::OnTimer( nIDEvent );
}
当我用鼠标双击时,总是收到两条消息 NM_CLICK
和 NM_DBLCLK
。为什么?
你知道我如何区分两者吗?
When I press double click with the mouse, I always get two messages NM_CLICK and then NM_DBLCLK. Why?
简答:因为系统没有实现时间机器。
当您用鼠标单击时,系统会生成 NM_CLICK
通知,因为它还不知道这是否是双击序列的开始。这允许应用程序立即响应鼠标单击事件,而无需等待双击超时到期。
要区分单击和双击,您必须推迟 NM_CLICK
处理,直到您知道它不是 NM_DBLCLK
序列的一部分。为此,请在 NM_CLICK
处理程序中设置一个计时器,并从 NM_DBLCLK
中终止计时器。定时器到时,就知道没有NM_DBLCLK
尾随,可以继续处理单击了。
下面应该给你一个想法,如何实现它:
enum TimerId {
TimerId_ListCtrlDblClk = 1
};
BOOL CMyDialog::OnNotify( WPARAM wParam, LPARAM lParam, LRESULT* pResult ) {
const NMHDR& hdr = *(const NMHDR*)lParam;
switch ( hdr.code ) {
case NM_CLICK:
SetTimer( TimerId_ListCtrlDblClk, ::GetDoubleClickTime(), nullptr );
*pResult = 0;
return TRUE;
case NM_DBLCLK:
KillTimer( TimerId_ListCtrlDblClk );
// Handle double-clicks here.
*pResult = 0;
return TRUE;
default:
break;
}
return CDialogEx::OnNotify( wParam, lParam, pResult );
}
void CMyDialog::OnTimer( UINT_PTR nIDEvent ) {
if ( nIDEvent == TimerId_ListBoxDblClk ) {
// If this timer expires, there is no NM_DBLCLK trailing the NM_CLICK.
// Handle the regular NM_CLICK notification.
}
CDialogEx::OnTimer( nIDEvent );
}