zoukankan      html  css  js  c++  java
  • 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()仅仅检查一个键是否被按下,而不区分大写和小写!



  • 相关阅读:
    后端架构师技术图谱
    互联网经典技术架构
    软件开发知识体系(二)
    软件开发知识体系(一)
    HSF源码剖析
    分库分表的几种常见形式以及可能遇到的难题
    iOS 关于MVC和MVVM设计模式的那些事
    MVC与MVP简单对比
    MVC、MVP、MVVM 模式
    Learning Android ActionBar
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7294699.html
Copyright © 2011-2022 走看看