代码之家  ›  专栏  ›  技术社区  ›  unrelativity

是否有任何C实现或方法可以让文本框以键序列作为输入?

  •  0
  • unrelativity  · 技术社区  · 14 年前

    我有一个钩住keydown事件的实现,它抑制keypress事件并执行一些魔术。现在我想展示一些比“控制键”等更友好的东西,所以你可以在下面的代码中看到一个开关。但我发现上面的数字键 D1 D2 等等,然后 Add 出现在numpad+。此外,打印屏幕似乎无法识别。

    我有什么遗漏吗?

    private int numKeys = 0;
    private List<int> shortcutKeys = new List<int>();
    
    private void textBoxRegionKeys_Click(object sender, EventArgs e)
    {
        textBoxRegionKeys.SelectAll();
    }
    
    private void textBoxRegionKeys_KeyDown(object sender, KeyEventArgs e)
    {
        // There are certain keys we want to ignore...
        if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
        {
            // We can handle this ourselves, thanks
            e.SuppressKeyPress = true;
    
            // Shortern what we show
            string ret = e.KeyCode.ToString();
            switch (ret)
            {
                case "ControlKey": ret = "Ctrl"; break;
                case "ShiftKey": ret = "Shift"; break;
                case "Menu": ret = "Alt"; break;
            }
    
            // If we haven't selected anything, we should be appending
            if (textBoxRegionKeys.SelectionLength == 0)
            {
                if (numKeys > 0)
                {
                    // Does our key already exist in the list?
                    if (shortcutKeys.Exists(x => x == e.KeyValue))
                    {
                        return;
                    }
    
                    textBoxRegionKeys.Text += " + ";
                }
                textBoxRegionKeys.Text += ret;
                shortcutKeys.Add(e.KeyValue);
                numKeys++;
            }
            else
            {
                textBoxRegionKeys.Text = ret;
                shortcutKeys.Clear();
                shortcutKeys.Add(e.KeyValue);
                numKeys = 1;
            }
        }
    }
    
    1 回复  |  直到 14 年前
        1
  •  1
  •   Chris Baxter    14 年前

    文本框KeyDown/KeyPress etc将只针对可接受为文本框输入的键(以及相关的修饰符)进行提升。因此,您将看不到处理过的键,如打印屏幕等。我能想到的最佳选项并不理想,但您可以重写ProcessKeyPreview或其他表单级消息拦截器,以获得任何按键的通知。有点像。。。

    protected override bool ProcessKeyPreview(ref Message m)
    {
      var keyCode = (Keys)Enum.ToObject(typeof (Keys), m.WParam);
    
      //Insert some logic 
    
      return base.ProcessKeyPreview(ref m);
    }
    

    当然,只要表单有焦点,并且按下了一个键,就会调用此方法,因此您必须通过执行某种形式的检查(这同样不理想)

    if(ReferenceEquals(ActiveControl, textBoxRegionKeys)) {}
    

    至于格式化成友好的消息,我认为你基本上需要你自己的特殊字符地图。。。我不知道任何全球化的键查找。如果我发现了什么,我会挖一点并更新答案。

    做了一点调查,没有发现任何明显的好的密钥映射。我只需要创建一个“友好”键名的映射:

    private static readonly Dictionary<Keys, String> KeysMap = new Dictionary<Keys, String>
                                                                 {
                                                                    { Keys.D1, "1"},
                                                                    { Keys.D9, "9"}
                                                                 };
    

    做一些类似的事情:

      String friendlyKeyCode;
      if (!KeysMap.TryGetValue(keyCode, out friendlyKeyCode))
        friendlyKeyCode = keyCode.ToString();
    

    就我个人而言,我觉得这种方法比大规模的转换更好。。。但这也管用。