首页 > 编程知识 正文

Edit Control响应全选Ctrl A

时间:2023-05-03 13:59:41 阅读:218324 作者:2937

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 实现循环 全选/取消全选,虽然取消全选很简单,一句话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()只检查一个键是否被按下,而不区分大小写!



版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。