有没有办法为鼠标按钮设置全局热键?

问题描述 投票:0回答:2

我想看看用户是否按下了例如鼠标左键+ ctrl 键并为其调用一个事件。

我已经尝试过了,但没有成功:

[DllImport("user32.dll")]
static extern short GetAsyncKeyState(int VirtualKeyPressed);

while (true)
{
  if (GetAsyncKeyState(0x01)>0)
  {
     DoJob();
  }
  else
  {
  }
}

此代码的问题是它第一次会捕获它,但第二次不会(这是在 while 循环中运行)

c# wpf global-hotkey
2个回答
0
投票

我相信您可以通过附加

Window.InputBind
MouseBinding
来完成您想要完成的任务,例如
Gesture="Ctrl+LeftClick"

如果您采用这种方法,您可以避免使用

user32.dll
并且必须处理检测隐藏代码中的输入。

这是一个将命令绑定到整个

Window
的输入的简单示例:

    <Window.InputBindings>
        <MouseBinding Command="{Binding CtrlLeftClickCommand}"
                      Gesture="Ctrl+LeftClick">
        </MouseBinding>
    </Window.InputBindings>

代码隐藏

public partial class GlobalHotKey : Window
{
    public MouseGesture CtrlLeftClick = new MouseGesture(MouseAction.LeftClick, ModifierKeys.Control);
    public ICommand CtrlLeftClickCommand { get; set; } = new CtrlLeftClickCommand();
    public GlobalHotKey()
    {
        DataContext = this;
        InitializeComponent();
    }
}

ICommand
实施,以防万一您不熟悉这种方法

public class CtrlLeftClickCommand : ICommand
{
    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter) => true;
    public void Execute(object parameter)
    {
        MessageBox.Show("You did the thing!");
    }
}

0
投票

在 WPF 中,您可以使用路由命令定义

KeyBinding
。如果您在应用程序的视觉根上处理它,您就有一个全局输入手势。

以下示例注册应用程序范围手势 Ctrl + left_mousebutton 并启动进程(用于演示目的)。

解决方案1

您可以定义和处理

CommandBing
(推荐)或
InputBinding

通常,您会将

CommandBinding
添加到定义
UIElement.Commandings
集合中以注册与实例的绑定。
但因为该命令必须是全局的,所以我们必须用类型来注册它。这是因为应用程序可以有多个
Window
实例,其中每个实例定义其自己的可视化树的根。现在,我们不必为每个实例显式注册
CommandBinding
,而是在 WPF 的
Window
帮助器类的帮助下为
CommandManager
类型注册一次绑定:

MainWindow.xaml.cs

partial class MainWindow : Window
{
  // Define as public so that the command can be used directly e.g., with a Button
  public static RoutedCommand StartProcessCommand { get; }

  public static MainWindow()
  {
    // Initialize a routed command with associated input gestures.
    // In this case the input gesture is a MouseGesture with a pressed modifier key (Ctrl).
    // Alternative track the CTRL key and create a KeyGesture instead.
    // Then, when executing the command, 
    // we can check if 'Mouse.LeftButton == MouseButtonState.Pressed' 
    var startProcessHotKey = new MouseGesture(MouseAction.LeftClick, ModifierKeys.Control);
    MainWindow.StartProcessCommand = new RoutedCommand(nameof(MainWindow.StartProcessCommand), typeof(MainWindow));
    _ = MainWindow.StartProcessCommand.InputGestures.Add(startProcessHotKey);
  }
   
  public MainWindow()
  {
    InitializeComponent();

    // Create a CommandBinding to register the input event handlers
    var startProcessCommandBinding = new CommandBinding(
      MainWindow.StartProcessCommand, 
      ExecutedStartProcessCommand, 
      CanExecuteStartProcessCommand);

    // Register the command with every Window of this application.
    // The Window is always the root of a visual tree.
    CommandManager.RegisterClassCommandBinding(typeof(Window), startProcessCommandBinding);
  }

  private void CanExecuteStartProcessCommand(object sender, CanExecuteRoutedEventArgs e) 
    => e.CanExecute = true;

  private void ExecutedStartProcessCommand(object sender, ExecutedRoutedEventArgs e)
  {
    // TODO::Execute StartProcessCommand
  }
}

MainWindow.xaml
Ctrl + LMouseButton 将从当前应用程序的每个

MainWindow.StartProcessCommand
实例执行
Window

此外,还可以显式调用
StartProcessCommand
,例如通过
Button

<Window>
  <Button Command="{x:Static MainWindow.StartProcessCommand}" />
</Window>

解决方案2

您可以为鼠标按下事件注册一个类处理程序,并检查相关按键是否被按下。
代码明显更短,但您失去了功能或灵活性,例如全局命令和显式命令手势的路由,允许每个元素处理它(无需显式检查确切的输入手势)。

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();

    EventManager.RegisterClassHandler(
      typeof(Window), 
      PreviewMouseLeftButtonUpEvent, 
      new RoutedEventHandler(OnGlobalPreviewMouseLeftButtonUp));
  }

  private void OnGlobalPreviewMouseLeftButtonUp(object sender, RoutedEventArgs e)
  {
    if (Keyboard.IsKeyDown(Key.LeftCtrl))
    {
      // TODO::Execute global input gesture
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.