C# 在自定义控件中重写OnKeyDown将字符置于起始位置
我正在创建一个自定义热键控件,因为msctls_hotkey32无法正确处理两个键(如媒体键和numpad键)。然而,当简单地按字符键(A-Z,0-9)时,实际上会将这些键放在文本框的前面 如果我多次按箭头键,它们也会被处理。 我覆盖了OnKeyPress和OnKeyUp,希望这些键能够停止 我非常感谢你的帮助。 问候 代码:C# 在自定义控件中重写OnKeyDown将字符置于起始位置,c#,winforms,custom-controls,C#,Winforms,Custom Controls,我正在创建一个自定义热键控件,因为msctls_hotkey32无法正确处理两个键(如媒体键和numpad键)。然而,当简单地按字符键(A-Z,0-9)时,实际上会将这些键放在文本框的前面 如果我多次按箭头键,它们也会被处理。 我覆盖了OnKeyPress和OnKeyUp,希望这些键能够停止 我非常感谢你的帮助。 问候 代码: using System.Windows.Forms; namespace HKMgr { public partial class Hotkey : Text
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);
}
公共部分类热键:文本框
{
公用热键()
{
base.SetStyle(ControlStyles.UserPaint
|ControlStyles.StandardClick
|ControlStyles.StandardDoubleClick
|ControlStyles.UseTextForAccessibility,false);
base.SetStyle(ControlStyles.FixedHeight,true);
}
受保护的覆盖无效OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
e、 已处理=正确;
Text=密钥字符串(如KeyData);
}
受保护的覆盖无效OnKeyUp(KeyEventArgs e)
{
基元键合(e);
e、 已处理=正确;
if((internalKeyData&~(Keys.Control | Keys.Alt | Keys.Shift))==Keys.None)
Text=“”;
}
按键时受保护的覆盖无效(按键事件参数e)
{
按键(e);
e、 已处理=正确;
}
字符串密钥字符串(键k)
{
字符串文本=”;
internalKeyData=键。无;
if((k&Keys.Shift)=Keys.Shift)
{
k&=~Keys.Shift;
文本+=“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;
文本+=“Ctrl+”;
internalKeyData |=Keys.Control;
}
if(k!=Keys.ControlKey&&k!=Keys.ShiftKey&&k!=Keys.Menu)
{
text+=ResolveToAlias(k);
internalKeyData |=k;
}
如果(文本==“”)
text=“无”;
返回(文本);
}
字符串ResolveToAlias(键k)
{
if(k==Keys.Next)
返回(“向下翻页”);
否则,如果(k>=Keys.D0&&k我找到了解决方案(如评论中所述)。对于以后阅读本文的任何人,请在覆盖中使用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);
}
公共部分类热键:文本框
{
公用热键()
{
base.SetStyle(ControlStyles.UserPaint
|ControlStyles.StandardClick
|ControlStyles.StandardDoubleClick
|ControlStyles.UseTextForAccessibility,false);
base.SetStyle(ControlStyles.FixedHeight,true);
}
受保护的覆盖无效OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
e、 已处理=正确;
Text=密钥字符串(如KeyData);
}
受保护的覆盖无效OnKeyUp(KeyEventArgs e)
{
基元键合(e);
e、 已处理=正确;
if((internalKeyData&~(Keys.Control | Keys.Alt | Keys.Shift))==Keys.None)
Text=“”;
}
按键时受保护的覆盖无效(按键事件参数e)
{
按键(e);
e、 已处理=正确;
}
字符串密钥字符串(键k)
{
字符串文本=”;
internalKeyData=键。无;
if((k&Keys.Shift)=Keys.Shift)
{
k&=~Keys.Shift;
文本+=“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;
文本+=“Ctrl+”;
internalKeyData |=Keys.Control;
}
if(k!=Keys.ControlKey&&k!=Keys.ShiftKey&&k!=Keys.Menu)
{
text+=ResolveToAlias(k);
internalKeyData |=k;
}
如果(文本==“”)
text=“无”;
返回(文本);
}
字符串ResolveToAlias(键k)
{
if(k==Keys.Next)
返回(“向下翻页”);
否则,如果(k>=Keys.D0&&k Adde.Handled=e.SuppressKeyPress=true;
这样文本框就看不到按键了。效果很好!谢谢。@HansPassant在本例中,您如何让用户取消/重置热键?他/她可以键入什么来将其设置为“无”还是一个空字符串?@Jamleian查看编辑后的答案。添加e.Handled=e.SuppressKeyPress=true;
使文本框看不到按键。这很好!谢谢。@HansPassant在本例中,您如何让用户取消/重置热键?他/她可以键入什么将其设置为“无”还是一个空字符串?@Jamrelian看看编辑过的答案。