【发布时间】:2021-09-04 15:20:36
【问题描述】:
我的目标是实现自定义 Control + S 按键处理程序,以连接到 winforms 应用程序中的自定义保存方法。
根据我的研发,有几种方法可以做到这一点。首先,我尝试了明显的 KeyPress 事件处理程序。这还不够强大,无法捕获我需要的按键(它没有在编辑器级别调用,而这正是我所需要的)。
第二个看起来更好的选项是受保护的覆盖 bool ProcessCmdKey(ref Message msg, Keys keyData) 覆盖。这有效 - 它拦截了 CTRL 键单击,但显然我需要编写额外的代码来坚持按下 CTRL 键的事实并拦截下一个按键(在我的情况下是 S),然后执行自定义操作。
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.S | Keys.Control))
{
// This is never called
}
else if (keyData == (Keys.Menu | Keys.Alt))
{
// this is called each time I hit CTRL
}
return true;
}
ProcessCmdKey 似乎在我按下 CTRL 键后立即被调用。
这篇文章建议创建一个 KeyTracker 类,该类将持续按下的键并执行它需要执行的操作:
Capture Key Sequence via ProcessCmdKey
这似乎是一个不错的选择,但在我深入研究实现一个纪念品跟踪模式之前,是否有人对如何完成这个看似常见的功能提出意见?
另一种模式使用 GetKeyboardState API 函数:
Capture multiple key downs in C#
这看起来很有趣,但我不确定它是否适合我的需求。
[DllImport ("user32.dll")]
public static extern int GetKeyboardState(byte[] keystate);
private void Form1_KeyDown( object sender, KeyEventArgs e )
{
byte[] keys = new byte[255];
GetKeyboardState (keys);
if( keys[(int)Keys.Up] == 129 && keys[(int)Keys.Right] == 129 )
{
Console.WriteLine ("Up Arrow key and Right Arrow key down.");
}
}
感谢您查看我的问题。
更新
我已向我的 DataPanel 添加了三个用于密钥处理的事件。当我在事件中设置断点时,VS 不会拾取这些事件,所以这让我相信 ProcessCmdKey 是我的最佳选择。
如果我能让这些事件发挥作用,那也很好:
// Ctrl + S: Save Support
this.ParentForm.KeyPreview = true;
this.KeyPress += new KeyPressEventHandler(DataPanel_KeyPress);
this.KeyDown += new KeyEventHandler(DataPanel_KeyDown);
this.PreviewKeyDown += new PreviewKeyDownEventHandler(DataPanel_PreviewKeyDown);
按下任何键时似乎都没有捕捉到这些事件:
void DataPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == (Keys.S | Keys.Control))
{
SessionManager.Trace.AddTrace("You Hit Save!!");
}
}
void DataPanel_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == (Keys.S | Keys.Control))
{
SessionManager.Trace.AddTrace("You Hit Save!!");
}
}
void DataPanel_KeyPress(object sender, KeyPressEventArgs e)
{
var key = e.KeyChar;
}
更新
我通过使用一个简单的 KeyUp 事件和 KeyPreview 标志解决了这个问题:
void ShipmentDataPanel_KeyUp(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.S)
{
MessageBox.Show("Control + S Key Hit!");
}
}
谢谢。
【问题讨论】: