最近,对wpf添加快捷键的方式进行了整理。主要用到的三种方式如下:

一、wpf命令:

资源中添加命令
<Window.Resources>
<RoutedUICommand x:Key="ToolCapClick" Text="截屏快捷键" />
</Window.Resources> 输入命令绑定
<Window.InputBindings>
<KeyBinding Gesture="Ctrl+Alt+Q" Command="{StaticResource ToolCapClick}"/>
</Window.InputBindings> 命令执行方法绑定
<Window.CommandBindings>
<CommandBinding Command="{StaticResource ToolCapClick}"
CanExecute="CommandBinding_ToolCapClick_CanExecute"
Executed="CommandBinding_ToolCapClick_Executed"/>
</Window.CommandBindings>

需要注意的是,绑定命令的时候,也可以<KeyBinding Modifiers="Ctrl+Alt" Key="Q" Command="{StaticResource ToolCapClick}"/>,建议用前者,以免造成混乱。

执行方法实现

  #region 截屏快捷键
private void CommandBinding_ToolCapClick_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
} private void CommandBinding_ToolCapClick_Executed(object sender, ExecutedRoutedEventArgs e)
{
try
{
CaptureImageTool capture = new CaptureImageTool();
capture.CapOverToHandWriting += Capture_CapOverToHandWriting;
capture.CapOverToBlackboard += Capture_CapOverToBlackboard;
string saveName = String.Empty;
if (capture.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{ //保存截取的内容
System.Drawing.Image capImage = capture.Image;
//上课存班级内部,不上课存外部
string strSavePath = DataBusiness.GetCurrentTeachFilePath(SystemConstant.PATH_CAPS);
if (!String.IsNullOrEmpty(strSavePath))
{
if (!Directory.Exists(strSavePath))
{
Directory.CreateDirectory(strSavePath);
}
saveName = strSavePath + DateTime.Now.ToString(SystemConstant.FORMAT_CAPS);
}
else
{ saveName = PathExecute.GetPathFile(SystemConstant.PATH_SAVE + Path.DirectorySeparatorChar + SystemConstant.PATH_CAPS, DateTime.Now.ToString(SystemConstant.FORMAT_CAPS));
} capImage.Save(saveName + SystemConstant.EXTENSION_PNG, System.Drawing.Imaging.ImageFormat.Png);
}
}
catch (Exception ex)
{
new Exception("capscreen module error:" + ex.Message);
}
}

二、利用windows钩子(hook)函数

第一步 引入到Winows API

   1: [DllImport("user32.dll")]

   2: public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

   3: [DllImport("user32.dll")]

   4: public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

这边可以参考两个MSDN的链接

第一个是关于RegisterHotKey函数的,里面有关于id,fsModifiers和vk 的具体说明

http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309%28v=vs.85%29.aspx

第二个是Virtual-Key 的表,即RegisterHotKey的最后一个参数

http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx

第二步 注册全局按键

这里先介绍一个窗体的事件SourceInitialized,这个时间发生在WPF窗体的资源初始化完毕,并且可以通过WindowInteropHelper获得该窗体的句柄用来与Win32交互。

具体可以参考MSDN http://msdn.microsoft.com/en-us/library/system.windows.window.sourceinitialized.aspx

我们通过重载OnSourceInitialized来在SourceInitialized事件发生后获取窗体的句柄,并且注册全局快捷键

 private const Int32 MY_HOTKEYID = 0x9999;
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
IntPtr handle = new WindowInteropHelper(this).Handle;
RegisterHotKey(handle, MY_HOTKEYID, 0x0001, 0x72);
}

关于几个常熟的解释

MY_HOTKEYID 是一个自定义的ID,取值范围在0x0000 到 0xBFFF。之后我们会根据这个值来判断事件的处理。

RegisterHotKey的第三或第四个参数可以参考第一步

第三步 添加接收所有窗口消息的事件处理程序

上面只是在系统中注册了快捷键,但是还要获取消息的事件,并筛选消息。

继续在OnSourceInitialized函数中操作

 protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e); IntPtr handle = new WindowInteropHelper(this).Handle;
RegisterHotKey(handle, MY_HOTKEYID, 0x0001, 0x72); HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}

下面来完成WndProc函数

 IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handle)
{
//Debug.WriteLine("hwnd:{0},msg:{1},wParam:{2},lParam{3}:,handle:{4}"
// ,hwnd,msg,wParam,lParam,handle);
if(wParam.ToInt32() == MY_HOTKEYID)
{
//全局快捷键要执行的命令
}
return IntPtr.Zero;
}

三、给button控件添加快捷键

<UserControl.Resources>
<RoutedUICommand x:Key="ClickCommand" Text="点击快捷键" />
</UserControl.Resources> <UserControl.CommandBindings>
<CommandBinding Command="{StaticResource ClickCommand}"
Executed="ClickHandler" />
</UserControl.CommandBindings> <UserControl.InputBindings>
<KeyBinding Key="C" Modifiers="Ctrl" Command="{StaticResource ClickCommand}" />
</UserControl.InputBindings> <Grid>
<Button Content="button" Command="{StaticResource ClickCommand}"/>
</Grid>

执行方法:

private void ClickHandler(object sender, RoutedEventArgs e)
{
Message.Show("命令执行!");
}
 

WPFの三种方式实现快捷键的更多相关文章

  1. WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式

    原文:WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式 由于WPF中没有提供PropertyGrid控件,有些业务需要此类的控件.这篇文章介绍在WPF中实现PropertyGr ...

  2. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件

    精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件 内容简介:本文介绍 Spring Boot 的配置文件和配置管理,以及介绍了三种读取配置文 ...

  3. 监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile

    大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...

  4. iOS字体加载三种方式

    静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...

  5. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  6. 【整理】Linux下中文检索引擎coreseek4安装,以及PHP使用sphinx的三种方式(sphinxapi,sphinx的php扩展,SphinxSe作为mysql存储引擎)

          一,软件准备 coreseek4.1 (包含coreseek测试版和mmseg最新版本,以及测试数据包[内置中文分词与搜索.单字切分.mysql数据源.python数据源.RT实时索引等测 ...

  7. JDBC的批处理操作三种方式 pstmt.addBatch()

    package lavasoft.jdbctest; import lavasoft.common.DBToolkit; import java.sql.Connection; import java ...

  8. 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】

    一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...

  9. Java设置session超时(失效)的三种方式

    1. 在web容器中设置(此处以tomcat为例) 在tomcat-6.0\conf\web.xml中设置,以下是tomcat 6.0中的默认配置: <!-- ================= ...

随机推荐

  1. 2016huasacm暑假集训训练三 B-Frogger

    题目链接:http://acm.hust.edu.cn/vjudge/contest/123674#problem/B 题意:一只青蛙在湖中一颗石头上, 它想去有另一只青蛙的石头上,但是 湖里的水很脏 ...

  2. vi/vim初步接触

    vi和vim一直被人津津乐道,到底是什么使得它们如此受欢迎? vi分为3种模式:一般模式,编辑模式,命令行模式. (1)一般模式: 进入vi后,默认就是一般模式. 用处:方便地移动光标,删除字符/整行 ...

  3. IOS第18天(6,CAKeyframeAnimation关键帧动画)

    ******* #import "HMViewController.h" @interface HMViewController () @property (weak, nonat ...

  4. 用session实现简单的购物

    package cn.itcast.shopping; import java.io.IOException; import java.io.PrintWriter; import java.util ...

  5. Windows2003中IIS的安全设置技巧

    在Windows Server 2003中对于IIS的安全设置具有十分重要的意义,所以掌握IIS安全设置的六大技巧是一个网管员必备的基本技能.下面就是对IIS的安全设置的六大技巧. 技巧1.安装系统补 ...

  6. RHEL/CentOS/Fedora各种源(EPEL、Remi、RPMForge、RPMFusion)配置

    最新文章:Virson’s Blog CentOS默认自带CentOS-Base.repo源,但官方源中去除了很多有版权争议的软件,而且安装的软件也不是最新的稳定版.Fedora自带的源中也找不到很多 ...

  7. m=m++,结果让你大吃一惊。

    如图,本来以为m=m++和m++是同一个效果,没想到m的值居然还是0. 原来m++是一个表达式,是有返回值的,它的返回值就是m自加前的值,Java对自加是这样处理的:首先把m的值(注意是值,不是引用) ...

  8. AFNetworking 3.0+ 启用完整、严格的https证书较验参考代码

    // 1.初始化单例类      AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];     manager.securit ...

  9. JS之对象

    每个对象的属性有两种,每种属性有4中特征描述符 1.数据属性 1.1 [[configurable]]:表示不能通过delete删除属性,不能修改属性的特性,不能将数据属性改为访问器属性,默认值fal ...

  10. thinkphp的钩子的两种配置和两种调用方法

    thinkphp的钩子行为类是一个比较难以理解的问题,网上有很多写thinkphp钩子类的文章,我也是根据网上的文章来设置thinkphp的钩子行为的,但根据这些网上的文章,我在设置的过程中,尝试了十 ...