2011-03-26 151 views
3

我正在为我的项目使用this键盘挂钩。我无法使用按下SHIFT修饰键的SendKeys.Send()发送小字母。我的应用程序的需要(例如)如果用户按下ķ按钮“一”应发,如果他按下SHIFT +ķ“B”应该发送。的代码是:C# - 如何使用SendKeys.Send发送带SHIFT键的小写字母?

void gkh_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.K) 
    { 
     if (Control.ModifierKeys == Keys.Shift) 
      SendKeys.Send("b"); 
     else 
      SendKeys.Send("a"); 
    } 
    e.Handled == true; 
} 

但它发送“B”(大写字母),而不是“B”,即SHIFT键改变所发送的键击 “B” 为大写。即使在添加了Keys.Shift之后,也会发生这种情况。

我尝试了许多方法,包括使用e.SupressKeyPress的SendKeys( “B” .toLower())并把上述代码在KeyUp事件但在静脉。

请帮助我,我非常沮丧,我的应用程序开发在这一点上受到打击。

回答

3

您正在发送密钥,而Shift密钥仍然关闭,这导致它们被上限。
您需要找出一种方法取消Shift按键以及K按键。

您正在使用的全局钩子示例有点空;它应该正在报告哪些修饰键被按下。不幸的是,它看起来功能尚未实现。

为什么您首先需要使用键盘挂钩?你是否真的需要处理当你的表格没有重点关键时发生的关键事件?如果是这样,为什么你会在世界上使用SendKey?您如何知道当前活动的应用程序将如何处理您发送的按键?

这看起来像是一种在覆盖表单的ProcessCmdKey method时可以更好地处理的东西。例如:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
    { 
    if (keyData == (Keys.K | Keys.Shift)) 
    { 
     SendKeys.Send("b"); 
     return true; // indicate that you handled the key 
    } 
    else if (keyData == Keys.K) 
    { 
     SendKeys.Send("a"); 
     return true; // indicate that you handled the key 
    } 

    // call the base class to handle the key 
    return base.ProcessCmdKey(ref msg, keyData); 
    } 

编辑:您的意见建议,你其实需要处理的时候你不会形成不的焦点发生的关键事件。假设您需要处理的不仅仅是密钥,您需要使用全局钩子来完成此操作。

正如我前面提到的,问题是,用户仍然按住Shift键关键当你发送使用SendInput键,这是导致它作为一个大写字母B的,而不是注册一个小写字母。那么解决办法很明显:你需要找出一种方法来取消Shift按键使它不被操作系统处理。当然,如果你吃了关键事件,你还需要找出跟踪的方式,这样你的应用程序仍然知道它被按下的时间,并可以相应地采取行动。

快速搜索揭示了a similar question已经被问及并回答了关于Windows logo的关键。 (至少,这段代码适用于我编写的全局钩子类;它也适用于你的类,但是,我没有真正测试过):

// Private flag to hold the state of the Shift key even though we eat it 
private bool _shiftPressed = false; 

private void gkh_KeyDown(object sender, KeyEventArgs e) 
{ 
    // See if the user has pressed the Shift key 
    // (the global hook detects individual keys, so we need to check both) 
    if ((e.KeyCode == Keys.LShiftKey) || (e.KeyCode == Keys.RShiftKey)) 
    { 
     // Set the flag 
     _shiftPressed = true; 

     // Eat this key event 
     // (to prevent it from being processed by the OS) 
     e.Handled = true; 
    } 


    // See if the user has pressed the K key 
    if (e.KeyCode == Keys.K) 
    { 
     // See if they pressed the Shift key by checking our flag 
     if (_shiftPressed) 
     { 
     // Clear the flag 
     _shiftPressed = false; 

     // Send a lowercase letter B 
     SendKeys.Send("b"); 
     } 
     else 
     { 
     // Shift was not pressed, so send a lowercase letter A 
     SendKeys.Send("a"); 
     } 

     // Eat this key event 
     e.Handled = true; 
    } 
} 
+0

我需要键盘挂钩,因为我的项目是重新映射键盘按键的IME(输入法编辑器)。表单在启动时未加载,应用程序位于系统托盘中,捕获按键并将不同的字符(使用SendKeys.Send方法)发送到焦点应用程序(例如Word处理器)。 ** e.Handled **取消** K **键,但不取消** SHIFT **键的效果。我还将** Keys.Shift **添加到了钩子中,但仍是静止的。 – ePandit 2011-03-27 07:41:55

+0

@ePandit:我已经更新了我的答案。看看这对你是否有用。正如我所提到的,我使用自己的全局钩子类来测试它,但因为它都基于相同的Windows API函数,所以它也应该适用于您正在使用的类。 – 2011-03-28 05:14:00