Edit Control響應全選(Ctrl+A)


MFC中的Edit控件用於輸入數據,當輸入的數據為大段數字的時候,全選功能就顯得非常重要了,可偏偏在MFC中Edit控件就不 支持全選。Ctrl+A不行,雙擊也不行。

Ctrl+C和Ctrl+V都是默認支持的。因此為了使用方便,我們僅僅能自己讓Edit去支持Ctrl+A全選 功能了。

實現的方式也比較簡單,自己處理消息就是!

Ctrl+A是一個組合消息,在檢測到A或者a按鍵按下的時候。推斷Ctrl鍵的狀態,假設Ctrl鍵有效則說明用戶按下了Ctrl+A按鍵,這時候我們將Edit中內容設置為全選就可以。


在類定義中加入:

BOOL PreTranslateMessage(MSG* pMsg);

實現例如以下:

<span style="color:#444444;">BOOL C***Dlg::PreTranslateMessage(MSG* pMsg)
{
	if (pMsg->message == WM_KEYDOWN)
	{
		BOOL bCtrl = ::GetKeyState(VK_CONTROL) & 0x80;
		//BOOL bShift = ::GetKeyState(VK_SHIFT) & 0x80;
		//BOOL bAlt = ::GetKeyState(VK_MENU) & 0x80;

		switch (pMsg->wParam)
		{
		case 'a':
		case 'A':
			if (bCtrl)
			{
				</span><span style="color:#ff0000;">m_ctrLog.SetSel(0, -1); //或 SendDlgItemMessage(IDC_Log, EM_SETSEL, 0, -1);</span><span style="color:#444444;">
			}
			break;
		}
	}

	return CWnd::PreTranslateMessage(pMsg);
}</span>

或:

BOOL C***Dlg::PreTranslateMessage(MSG* pMsg)
{
	if(pMsg->message == WM_KEYDOWN)
	{
		BOOL b = GetKeyState(VK_CONTROL) & 0×80;
		if(b && (pMsg->wParam==’a'||pMsg->wParam==’A'))
		{
			<span style="color:#ff0000;">SetSel(0,-1);	//或 SendDlgItemMessage(IDC_Log, EM_SETSEL, 0, -1);</span>
			return TRUE;
		}
	}

	return CWnd::PreTranslateMessage(pMsg);
}

備注:

為了避免對使用的Edit一個個的進行處理,能夠通過從CEdit類派生一個新類CEditEx類讓Edit支持Ctrl+A全選功能。


另外:

Ctrl + A 實現循環 全選/取消全選。盡管取消全選非常easy,一句話SetSel(-1),但難點在於怎樣推斷取消全選的條件。代碼例如以下:

對於一個編輯框。實現它的全選和取消全選(前提:該編輯框獲得焦點)

新建一個dialog based MFC application, 命名為“d1”。界面例如以下:

為對話框類加入一個成員變量:bool m_bSelectAll;用於控制全選狀態。

另外重載對話框類的PreTranslateMessage事件,加入例如以下代碼:

BOOL  CD1Dlg::PreTranslateMessage(MSG* pMsg)
{
     if ((GetAsyncKeyState(VK_CONTROL) & 0x8000) && (GetAsyncKeyState( 'A' ) & 0x8000) && pMsg->hwnd == m_pEdit->m_hWnd)
     {
         if (m_bSelectAll)
         {
             m_pEdit->SetSel(-1);         // 取消全選
         }
         else
         {
             m_pEdit->SetSel(0, -1);          // 全選
         }
         m_bSelectAll = !m_bSelectAll;
         return  TRUE;
     }
     
     return  CDialog::PreTranslateMessage(pMsg);
}

這樣。當編輯框獲得焦點時,假設再按下Ctrl+A,編輯框的內容就會被“全選”或“取消全選”。

可是上面以m_bSelectAll來作為推斷是否“已經處於全選”狀態有個問題,那就是當全選時,用戶點擊編輯框而取消了全選,但這時,m_bSelectAll卻還處於全選狀態,也就是說這個標志(m_bSelectAll)與實際的全選狀態不一致。

所以採用了另外的方法來驗證是否處於全選狀態(就是選中內容的長度與編輯框內容長度是否一致)。代碼例如以下:

BOOL  CD1Dlg::PreTranslateMessage(MSG* pMsg)
{
     if (pMsg->hwnd == m_pEdit->m_hWnd && (GetAsyncKeyState(VK_CONTROL) & 0x8000) && (GetAsyncKeyState(_T( 'A' )) & 0x8000))
     {
         CString txt;
         int  start, end;
         
         m_pEdit->GetWindowText(txt);
         m_pEdit->GetSel(start, end);
         if (txt.GetLength() == end - start)  // 處於全選狀態
         {
             m_pEdit->SetSel(-1);         // 取消全選
         }
         else
         {
             m_pEdit->SetSel(0, -1);          // 全選
         }
         return  TRUE;
     }
     
     return  CDialog::PreTranslateMessage(pMsg);
}

 

說明:GetAsyncKeyState()僅僅檢查一個鍵是否被按下,而不區分大寫和小寫!




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM