在自定义控件中覆盖 OnKeyDown 将字符置于开始位置

Overriding OnKeyDown in custom control puts character in start

我正在创建一个自定义热键控件,因为 msctls_hotkey32 没有正确处理几个键(例如媒体键和小键盘键)。然而,虽然简单地按下字符键(A-Z,0-9)实际上将这些键放在文本框前面 image link.

如果我多次按箭头键,它们也会被处理。 我也重写了 OnKeyPress 和 OnKeyUp,希望这些键能停止。

非常感谢您的帮助。 问候

代码:

using System.Windows.Forms;

namespace HKMgr
{
    public partial class Hotkey : TextBox
    {
        public Hotkey()
        {
            base.SetStyle(ControlStyles.UserPaint
                           | ControlStyles.StandardClick
                           | ControlStyles.StandardDoubleClick
                           | ControlStyles.UseTextForAccessibility, false);
            base.SetStyle(ControlStyles.FixedHeight, true);
        }


        protected override void OnKeyDown(KeyEventArgs e)
        {
            //base.OnKeyDown(e);
            Text = KeysToString(e);
        }


        protected override void OnKeyUp(KeyEventArgs e)
        {
            //base.OnKeyUp(e);
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            //base.OnKeyPress(e);
        }

        string KeysToString(KeyEventArgs e)
        {
            string text = "";

            if ((e.Modifiers & Keys.Shift) == Keys.Shift)
                text = text + "Shift + ";
            if ((e.Modifiers & Keys.Control) == Keys.Control)
                text = text + "Control + ";
            if ((e.Modifiers & Keys.Alt) == Keys.Alt)
                text = text + "Alt + ";
            if (e.KeyCode != Keys.None && e.KeyCode != Keys.ShiftKey && e.KeyCode != Keys.Menu && e.KeyCode != Keys.ControlKey)
                text = text + e.KeyCode;
            //MessageBox.Show(text);
            return (text);
        } 

    }
}

我找到了解决方案(如评论中所述)。对于以后阅读本文的任何人,请在覆盖中使用 e.Handled = e.SuppressKeyPress = true;

编辑:对于未来的读者,这是我正在使用的代码(可以很好地替代 msctls_hotkey32。

public partial class Hotkey : TextBox
{
    public Hotkey()
    {
        base.SetStyle(ControlStyles.UserPaint
                       | ControlStyles.StandardClick
                       | ControlStyles.StandardDoubleClick
                       | ControlStyles.UseTextForAccessibility, false);
        base.SetStyle(ControlStyles.FixedHeight, true);
    }


    protected override void OnKeyDown(KeyEventArgs e)
    {
        base.OnKeyDown(e);
        e.Handled = true;
        Text = KeysToString(e.KeyData);

    }


    protected override void OnKeyUp(KeyEventArgs e)
    {
        base.OnKeyUp(e);
        e.Handled = true;

        if ((internalKeyData & ~(Keys.Control | Keys.Alt | Keys.Shift)) == Keys.None)
            Text = "";
    }

    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        base.OnKeyPress(e);
        e.Handled = true;
    }

    string KeysToString(Keys k)
    {
        string text = "";
        internalKeyData = Keys.None;

        if ((k & Keys.Shift) == Keys.Shift)
        {
            k &= ~Keys.Shift;
            text += "Shift + ";
            internalKeyData |= Keys.Shift;
        }
        if ((k & Keys.Alt) == Keys.Alt)
        {
            k &= ~Keys.Alt;
            text += "Alt + ";
            internalKeyData |= Keys.Alt;
        }
        if ((k & Keys.Control) == Keys.Control)
        {
            k &= ~Keys.Control;
            text += "Ctrl + ";
            internalKeyData |= Keys.Control;
        }

        if (k != Keys.ControlKey && k != Keys.ShiftKey && k != Keys.Menu)
        {
            text += ResolveToAlias(k);
            internalKeyData |= k;
        }

        if (text == "")
            text = "None";
        return (text);
    }

    string ResolveToAlias(Keys k)
    {
        if (k == Keys.Next)
            return ("PageDown");
        else if (k >= Keys.D0 && k <= Keys.D9)
            return ((k - Keys.D0).ToString());
        else if (k.ToString().Contains("Oem"))
            return (ToAscii(k).ToString());
        return (k.ToString());
    }

    Keys internalKeyData;
    public Keys KeyData
    {
        get { return (internalKeyData); }
        set { Text = KeysToString(value); }
    }

    public static char ToAscii(Keys key)
    {
        var outputBuilder = new StringBuilder(2);
        int result = ToAscii((uint)key, 0, new byte[256], outputBuilder, 0);
        if (result == 1)
            return outputBuilder[0];
        else
            throw new Exception("Invalid key");
    }

    [DllImport("user32.dll")]
    private static extern int ToAscii(uint uVirtKey, uint uScanCode,
                                      byte[] lpKeyState,
                                      [Out] StringBuilder lpChar,
                                      uint uFlags);

}