1. 程式人生 > >MFC按鍵響應長按操作

MFC按鍵響應長按操作

最近在做一個MFC專案,部分介面如下:

點選加號/減號,可以調整Edit框內數字大小,但是通過響應按鍵的click訊息,每次點選只能加1/減1,如果我們要調整到一個較大的數字,需要多次點選。直覺告訴我,如果通過長按按鍵快速的變化數字,可以解決這一問題。

但是MFC button控制元件預設即沒有與按鍵長按對應的訊息,也沒有按下鬆開的訊息,如圖:

於是問題變得麻煩,以下是我的方法。

1、攔截滑鼠左鍵按下和鬆開操作

2、判斷1中操作的座標是否為按鍵座標

3、如果滿足1、2則觸發定時器迴圈執行按鍵click回撥函式

實現程式碼:

1、在視窗類內新增成員函式

BOOL PreTranslateMessage(MSG* pMsg); 

2、編寫成員函式

BOOL Cdianji_kz_V11Dlg::PreTranslateMessage(MSG* pMsg)
{
	if(pMsg->message == WM_LBUTTONDOWN)//攔截滑鼠左鍵按下訊息
	{
		if(pMsg->hwnd == GetDlgItem(IDC_BTN_PLUS)->m_hWnd)//判斷按下的位置是否為目標button
		{
			btn_add_plus_flag=1;//表示加
			btn_add_plus_first_flag=1;//表示按下
			SetTimer(2,50,NULL);//觸發定時器,按1秒加20
		}
		else if(pMsg->hwnd == GetDlgItem(IDC_BTN_SUB)->m_hWnd)
		{
			btn_add_plus_flag=2;//表示減
			SetTimer(2,150,NULL);//按1秒減7
		}
	}
	else if(pMsg->message == WM_LBUTTONUP)
	{
		if(pMsg->hwnd == GetDlgItem(IDC_BTN_PLUS)->m_hWnd)
		{
			btn_add_plus_flag=0;//清除標誌
			btn_add_plus_first_flag=0;//清除標誌
			KillTimer(2);//關閉定時器
		}
		else if(pMsg->hwnd == GetDlgItem(IDC_BTN_SUB)->m_hWnd)
		{
			btn_add_plus_flag=0;
			KillTimer(2);
		}
	}

	return CDialog::PreTranslateMessage(pMsg); //一定要有,其他訊息系統預設處理
}

3、編寫定時器回撥函式

void Cdianji_kz_V11Dlg::OnTimer(UINT nIDEvent)
{
	switch (nIDEvent)
	{
	case 2: ///處理ID為24的定時器
		long_sub_add();
		break;
	}
	CDialog::OnTimer(nIDEvent);

}
int Cdianji_kz_V11Dlg::long_sub_add(void)
{
	if (btn_add_plus_first_flag==1)
	{
		Sleep(150);
		btn_add_plus_first_flag=0;
	}
	else if (btn_add_plus_flag==1)
	{
		OnBnClickedBtnPlus(); //按鈕“+”click訊息對應的函式
	}
	else if(btn_add_plus_flag==2)
	{
		OnBnClickedBtnSub();//按鈕“-” click訊息對應的函式
	}
	return 0;
}
btn_add_plus_flag 標誌位作用不難看出,因為點“+”和“-”按鍵觸發的是同一個定時器,執行的是同一個定時器回撥函式,所以用這個變數來區分兩個按鍵,對應不同的操作。 btn_add_plus_first_flag 標誌設定的原因,我們在程式中設定的是如果“+”按鍵被按下,則使能定期器2,“+”按鍵鬆開,關閉定時器,定時器2回撥函式是以50ms為一個週期呼叫按鍵click回撥函式(也就是說自動的一秒點選20次“+”按鍵)。也就是說定時器執行的總時間與我們按鍵按下的時間成正比,因此長按實現了迴圈的“+”的操作。 但這就存在一個問題,如果當我們想實現加1的操作時,點選一次按鈕會有100ms左右的操作延時,因此即執行了原來的click回撥函式,又會觸發定時器函式,所以點一次按鍵可能加2或3。因此需要設定一個標誌,延時執行定時器函式,避免想加1加過頭的情況!