none
焦点在EDIT上的时候,响应快捷键碰到的问题 RRS feed

  • 问题

  • 快捷键为全局快捷键,当我焦点在Edit上的时候,这时候就是出现两种情况

    1.当我敲下的键为可输入字符的时候,应该Edit正常输入字符,不去调用TranslateAccelerator

    2.当我敲下的键为不可输入字符的时候,应该调用TranslateAccelerator,响应快捷键

    类似的功能实现上来讲有什么好的办法吗?

    2019年7月8日 10:04

全部回复

  • 你好,

    感谢你在MSDN论坛发帖。

    不知道我的方法是否符合你的要求。我准备了两套加速键方案,在消息预处理函数中判断窗口焦点是否为Edit控件,如果是则使用加速键1,如果不是则使用加速键2,加速键2与加速键1的区别仅在于有没有可输入字符。代码如下,仅供参考。

    //.h文件
    public:
    	CEdit edit;
    	CEdit edit2;
    	HACCEL   m_hAccel;
    	HACCEL   m_hAccel2;


    //.cpp文件
    BOOL CMFCApplication47Dlg::OnInitDialog()
    {
            .........................................
    	edit.Create(WS_BORDER, CRect(100, 100, 200, 200), this, 10012);
    	edit.ShowWindow(SW_SHOW);
    	edit2.Create(WS_BORDER, CRect(200,200,300,300), this, 100151);
    	edit2.ShowWindow(SW_SHOW);
    	// TODO: Add extra initialization here
    	m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));
    	m_hAccel2 = ::LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR2));
            ...........................................
    }
    
    BOOL CMFCApplication47Dlg::PreTranslateMessage(MSG* pMsg)
    {
    	if (GetDlgItem(10012) == GetFocus())
    	{
    		if (m_hAccel)
    		{
    			if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
    			{
    				return(TRUE);
    			}
    		}
    	}
    	else
    	{
    		if (m_hAccel2)
    		{
    			if (::TranslateAccelerator(m_hWnd, m_hAccel2, pMsg))
    			{
    				return(TRUE);
    			}
    		}
    	}
    	return CDialogEx::PreTranslateMessage(pMsg);
    }
    

    经过测试,当设置快捷键C时,进行判断是否为焦点的对话框对应没有用c做快捷键,将可以直接输入正常字符c,而另外一个对话框对应设置c为快捷键,将响应快捷键c,而无法输入字符c。

    Best Regards,

    Suarez Zhou

    2019年7月9日 7:24
  • 感谢你的答复

    我的需求不是这样的,我这边是认为当光标(焦点)在edit控件上的时候,

    这时候应该是输入优先的,只输入不响应快捷键

    当按下F1类似这样不能输入的键的时候,才会去响应快捷键

    现在当键盘按下的时候,在很难判断这时候是不是可以输入的键,

    除非去穷举判断这个键

    这个需求觉得应该比较常见,所以问下有啥好的方法做这件事

    2019年7月9日 11:10
  • 你好,

    BOOL CMFCApplication48View::PreTranslateMessage(MSG* pMsg)
    {
    	// TODO: Add your specialized code here and/or call the base class
    	if (GetDlgItem(1001) == GetFocus())
    	{
    		if (pMsg->wParam <= 'z'&&pMsg->wParam >= 'A')
    		{
    			
    		}
    		else
    		{
    			::TranslateAccelerator(m_hWnd, hAccel, pMsg);
    		}
    	}
    	else 
    	{
    		::TranslateAccelerator(m_hWnd, hAccel, pMsg);
    	}
    	return CView::PreTranslateMessage(pMsg);
    }

    以上代码可以通过完善可输入字符的判定达到你需要的功能,但是其中hAccel加载的是我自定义的加速键表。如果想实现你所需的功能,似乎无法使用系统生成的IDR_MAINFRAME,因为其在app文件中被加载使用,实现的过程被封装,没有相关直接的API去屏蔽加速键的调用。

    Best Regards,

    Suarez Zhou

    2019年7月10日 5:48
  • 感谢的你耐心回答,现在碰到的问题是这样的:

    多文档程序,快捷键的触发的位置是在

    CMainFrame::PreTranslateMessage(MSG* pMsg)

    但是这个EDIT是在子view上,这个时候,当按键按下去,必然会广播到CMainFrame::PreTranslateMessage(MSG* pMsg);

    如果在EDIT或者view的:PreTranslateMessage(MSG* pMsg);返回TRUE;的时候,EDIT的消息被截断从而收不到OnCHAR消息,进而编辑功能失效,这有什么好的办法处理吗?

    2019年7月11日 6:35
  • 你好,

    让我梳理一下你的问题,你的edit在view上,快捷键消息触发位置在CMainFrame::PreTranslateMessage(MSG* pMsg)上,你想要edit在view上正常地输入字符,不想这个字符所代表的快捷键触发在mainframe上的一些操作。是这个意思吗?

    消息响应地顺序为View类 ->Doc类-> MainFrame-> App,你如果不想触发这个消息,可以在view的PreTranslateMessage(MSG* pMsg)中拦截这个消息。return TRUE会使得字符输入消息被拦截,你可以按照如下方式return,以保证字符消息能继续处理下去。


    BOOL CMFCApplication55View::PreTranslateMessage(MSG* pMsg)
    {
    	// TODO: Add your specialized code here and/or call the base class
    	if (pMsg->wParam <= 'z'&&pMsg->wParam >= 'A')
    	{
    		return CView::PreTranslateMessage(pMsg);
    	}
    	return CView::PreTranslateMessage(pMsg);
    }

    Best Regards,

    Suarez Zhou


    2019年7月12日 9:56
  • 你好,非常感谢你的答复

    你的回答的两个return  是不是写错了呢?完全一样的

    2019年7月12日 12:27
  • 你好,

    这仅仅是一段代码,底下还有许多消息处理函数,return CView::PreTranslateMessage(pMsg)可以用来拦截字符消息,让字符消息不经过下面的快捷键消息响应而直接略过这个消息预处理函数,进入CView类的消息预处理函数,从而让字符消息一直处理下去,而不是像return ture一样,直接返回结果,不响应OnCHAR消息。

    Best Regards,

    Suarez Zhou

    2019年7月15日 9:17
  • 你好,

    请问你的问题解决了吗?如果解决了,请标记正确的回复为答案,这会帮助其他有着相同问题的社区成员。如果没有解决,欢迎随时提问。

    Best Regards,

    Suarez Zhou

    2019年7月23日 6:20