我在WPF中开发了一个屏幕键盘。我需要捕获按键事件(通过键盘)以便跟踪大写锁定、Shift等是否被按下。
请注意,当打开其他应用程序(比如记事本)时,我的应用程序会失去焦点。
有人能否建议如何在WPF中实现这一点? 简而言之,我的WPF应用程序需要捕获按键事件,即使它没有焦点。
有人能否建议如何在WPF中实现这一点? 简而言之,我的WPF应用程序需要捕获按键事件,即使它没有焦点。
如果您希望您的WPF应用程序能够在当前未被激活或焦点在屏幕上时检测和处理按键操作,您可以在Windows中实现所谓的全局热键。
以下两种方法可以添加到一个C#类中,以便注册和注销全局热键:
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
namespace Mm.Wpf.GlobalHotKeys
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private const int HOTKEY_ID = 9000;
//Modifiers:
private const uint MOD_NONE = 0x0000; //(none)
private const uint MOD_ALT = 0x0001; //ALT
private const uint MOD_CONTROL = 0x0002; //CTRL
private const uint MOD_SHIFT = 0x0004; //SHIFT
private const uint MOD_WIN = 0x0008; //WINDOWS
//CAPS LOCK:
private const uint VK_CAPITAL = 0x14;
public MainWindow()
{
InitializeComponent();
}
private IntPtr _windowHandle;
private HwndSource _source;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
_windowHandle = new WindowInteropHelper(this).Handle;
_source = HwndSource.FromHwnd(_windowHandle);
_source.AddHook(HwndHook);
RegisterHotKey(_windowHandle, HOTKEY_ID, MOD_CONTROL, VK_CAPITAL); //CTRL + CAPS_LOCK
}
private IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int WM_HOTKEY = 0x0312;
switch (msg)
{
case WM_HOTKEY:
switch (wParam.ToInt32())
{
case HOTKEY_ID:
int vkey = (((int)lParam >> 16) & 0xFFFF);
if (vkey == VK_CAPITAL)
{
tblock.Text += "CapsLock was pressed" + Environment.NewLine;
}
handled = true;
break;
}
break;
}
return IntPtr.Zero;
}
protected override void OnClosed(EventArgs e)
{
_source.RemoveHook(HwndHook);
UnregisterHotKey(_windowHandle, HOTKEY_ID);
base.OnClosed(e);
}
}
}
<Window x:Class="Mm.Wpf.GlobalHotKeys.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock x:Name="tblock"></TextBlock>
</Grid>
</Window>
<Window x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
KeyDown="myTestKey" >
这是键盘按下事件的代码,我在其中检查数字1:
private void myTestKey(object sender, KeyEventArgs e)
{
if ((e.Key == Key.D1) || (e.Key == Key.NumPad1))
{
//do some stuff here
return;
}
}
这是一个轻松的方法,可以快速找到任何键。希望这有所帮助。