【发布时间】:2011-03-15 17:12:09
【问题描述】:
如何在 C# 表单上捕获 Ctrl + Alt + K + P 键? 谢谢
【问题讨论】:
-
全局或仅当表单具有焦点时?
标签: c# keyboard keyboard-shortcuts keyboard-events
如何在 C# 表单上捕获 Ctrl + Alt + K + P 键? 谢谢
【问题讨论】:
标签: c# keyboard keyboard-shortcuts keyboard-events
查看这篇关于在 c# 中设置热键的精彩博文
这里还有一篇很好的文章解释了所有这些
【讨论】:
MessageFilters 可以在这种情况下为您提供帮助。
public class KeystrokMessageFilter : System.Windows.Forms.IMessageFilter
{
public KeystrokMessageFilter() { }
#region Implementation of IMessageFilter
public bool PreFilterMessage(ref Message m)
{
if ((m.Msg == 256 /*0x0100*/))
{
switch (((int)m.WParam) | ((int)Control.ModifierKeys))
{
case (int)(Keys.Control | Keys.Alt | Keys.K):
MessageBox.Show("You pressed ctrl + alt + k");
break;
//This does not work. It seems you can only check single character along with CTRL and ALT.
//case (int)(Keys.Control | Keys.Alt | Keys.K | Keys.P):
// MessageBox.Show("You pressed ctrl + alt + k + p");
// break;
case (int)(Keys.Control | Keys.C): MessageBox.Show("You pressed ctrl+c");
break;
case (int)(Keys.Control | Keys.V): MessageBox.Show("You pressed ctrl+v");
break;
case (int)Keys.Up: MessageBox.Show("You pressed up");
break;
}
}
return false;
}
#endregion
}
现在在您的 C# WindowsForm 中,注册 MessageFilter 以捕获击键和组合。
public partial class Form1 : Form
{
KeystrokMessageFilter keyStrokeMessageFilter = new KeystrokMessageFilter();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Application.AddMessageFilter(keyStrokeMessageFilter);
}
}
不知何故,它只检测到 Ctrl + Alt + K。请阅读 MessageFilter 代码中的注释。
【讨论】:
我不确定你是否可以。但是,您可以做的是 Visual Studio 的做法。 它有 Ctrl + K、C 等快捷键。您首先按 Ctrl+K,然后按住 Ctrl 并按 C。在您的情况下,您可以检查 Ctrl+Alt+K,P。
您可以首先检查 Ctrl+Alt+K 就像在其他答案中所做的那样,然后将成员变量/标志设置为表示已按下 Ctrl+Alt+K。在检查 K 的相同方法中,您可以检查 P,如果您刚刚设置的标志设置为 true,则执行您需要执行的任何操作。否则将标志设置回 false。
粗略的伪代码:
private bool m_bCtrlAltKPressed = false;
public void KeyDown() {
if (Ctrl+Alt+K)
{
m_bCtrlAltKPressed = true;
}
else if (Ctrl+Alt+P && m_bCtrlAltKPressed) {
//do stuff
}
else {
m_bCtrlAltKPressed = false;
}
}
希望这已经足够清楚了。
【讨论】:
这是一个和弦,如果不记住和弦的第一个键击,您就无法检测到它。这有效:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private bool prefixSeen;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (prefixSeen) {
if (keyData == (Keys.Alt | Keys.Control | Keys.P)) {
MessageBox.Show("Got it!");
}
prefixSeen = false;
return true;
}
if (keyData == (Keys.Alt | Keys.Control | Keys.K)) {
prefixSeen = true;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
【讨论】:
当组合中的一个键被按下时,您可以使用GetKeyState 来获取其他键的状态。这是表单上的示例。
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace DetectKeyChord
{
public partial class Form1 : Form
{
private const int WM_KEYDOWN = 0x100;
private const int KEY_PRESSED = 0x80;
public Form1()
{
InitializeComponent();
}
public void ShortcutAction()
{
MessageBox.Show("Ctrl+Alt+K+P has been pressed.");
}
private bool IsKeyDown(Keys key)
{
return (NativeMethods.GetKeyState(key) & KEY_PRESSED) == KEY_PRESSED;
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_KEYDOWN)
{
//If any of the keys in the chord have been pressed, check to see if
//the entire chord is down.
if (new[] { Keys.P, Keys.K, Keys.ControlKey, Keys.Menu }.Contains((Keys)m.WParam))
{
if (IsKeyDown(Keys.ControlKey) && IsKeyDown(Keys.Menu) && IsKeyDown(Keys.K) && IsKeyDown(Keys.P))
{
this.ShortcutAction();
}
}
}
base.WndProc(ref m);
}
}
public static class NativeMethods
{
[DllImport("USER32.dll")]
public static extern short GetKeyState(Keys nVirtKey);
}
}
【讨论】: