如何在未聚焦时如何检测keyPress?

问题描述 投票:14回答:3

我正在尝试检测该窗体不是当前活动应用程序时按下Print Screen按钮的情况。

如果可能,该怎么做?

c# forms keypress
3个回答
11
投票

是的,它叫做“系统挂钩”,请看Global System Hooks in .NET


20
投票

嗯,如果您在使用系统挂钩时遇到问题,这是现成的解决方案(基于http://www.dreamincode.net/forums/topic/180436-global-hotkeys/:]

在您的项目中定义静态类:

public static class Constants
{
    //windows message id for hotkey
    public const int WM_HOTKEY_MSG_ID = 0x0312;
}

在您的项目中定义类:

public class KeyHandler
{
    [DllImport("user32.dll")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    private int key;
    private IntPtr hWnd;
    private int id;

    public KeyHandler(Keys key, Form form)
    {
        this.key = (int)key;
        this.hWnd = form.Handle;
        id = this.GetHashCode();
    }

    public override int GetHashCode()
    {
        return key ^ hWnd.ToInt32();
    }

    public bool Register()
    {
        return RegisterHotKey(hWnd, id, 0, key);
    }

    public bool Unregiser()
    {
        return UnregisterHotKey(hWnd, id);
    }
}

添加用法:

using System.Windows.Forms;
using System.Runtime.InteropServices;

现在,在您的表单中,添加字段:

private KeyHandler ghk;

以及在Form构造函数中:

ghk = new KeyHandler(Keys.PrintScreen, this);
ghk.Register();

将这两种方法添加到表单中:

private void HandleHotkey()
{
        // Do stuff...
}

protected override void WndProc(ref Message m)
{
    if (m.Msg == Constants.WM_HOTKEY_MSG_ID)
        HandleHotkey();
    base.WndProc(ref m);
}

HandleHotkey是您的按钮按下处理程序。您可以通过在此处传递不同的参数来更改按钮:ghk = new KeyHandler(Keys.PrintScreen, this);

现在,即使未聚焦,您的程序也会对按钮输入做出反应。


1
投票

API GetAsyncKeyState()可能是设置Windows Hook的理想选择。

这取决于您希望如何接收输入。如果您更喜欢事件驱动的通知,那么可以使用钩子。但是,如果您更喜欢polling键盘来更改状态,则可以使用上面的API。

以下是有关如何使用GetAsyncKeyState()的简单演示:源自GetAsyncKeyState] >>

Pinvoke.NET
© www.soinside.com 2019 - 2024. All rights reserved.