想要实现长按键的一些控制,查了查可以通过捕获键盘事件,然后处理按键时需要进行的操作。下面简单的实现左右按键界面更新数值加减。
1. 重载PreTranslateMessage(MSG* pMsg)函数,在函数中捕获键盘事件并处理响应:
BOOL CEditTestDlg::PreTranslateMessage(MSG* pMsg) {if (pMsg->message == WM_KEYDOWN){if (pMsg->wParam == VK_RIGHT){tmp++;m_value.Format(_T("%d"),tmp);GetDlgItem(IDC_EDIT1)->SetWindowText(m_value);return TRUE;}if (pMsg->wParam == VK_LEFT){tmp--;m_value.Format(_T("%d"),tmp);GetDlgItem(IDC_EDIT1)->SetWindowText(m_value);return TRUE;}}return CDialog::PreTranslateMessage(pMsg); }
以前一直使用UpdateData()函数更新,但是这次发现GetDlgItem()更适合现在的情况,只更新该控件而不会刷新其他数据。
2. 以上已经可以实现,但是如果想调整多久算长按,那可以通过定时器来实现:
重载PreTranslateMessage(MSG* pMsg)函数
BOOL CEditTestDlg::PreTranslateMessage(MSG* pMsg) {if (pMsg->message == WM_KEYDOWN){this->SetTimer(3,10,NULL);m_bKeyDown = TRUE;if (pMsg->wParam == VK_RIGHT){m_bRight = TRUE;return TRUE;}if (pMsg->wParam == VK_LEFT){m_bLeft = TRUE;return TRUE;}}else if (pMsg->message == WM_KEYUP){m_bRight = FALSE;m_bLeft = FALSE;m_bKeyDown = FALSE;KillTimer(3);}return CDialog::PreTranslateMessage(pMsg); }
定时器处理:
void CEditTestDlg::OnTimer(UINT_PTR nIDEvent) {switch (nIDEvent){case 1:……case 3:if (m_bKeyDown){if (m_bLeft){tmp--;m_value.Format(_T("%d"),tmp);GetDlgItem(IDC_EDIT1)->SetWindowText(m_value);//UpdateData(FALSE); }if (m_bRight){tmp++;m_value.Format(_T("%d"),tmp);GetDlgItem(IDC_EDIT1)->SetWindowText(m_value);//UpdateData(FALSE); }}break;default:break;}CDialog::OnTimer(nIDEvent); }
这样按键响应会更快,但是自带的定时器精度不够高,也可以通过自己实现高精度定时器来控制。
注意:处理按键消息时间以后,需要返回TRUE,不然对话框任然会响应该按键消息,至于PreTranslateMessage(MSG* pMsg)对消息的捕获和屏蔽以及返回值的意义见: