在自定义控件中覆盖 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);
}
我正在创建一个自定义热键控件,因为 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);
}