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

一、wpf命令:

  1. 资源中添加命令
  2. <Window.Resources>
  3. <RoutedUICommand x:Key="ToolCapClick" Text="截屏快捷键" />
  4. </Window.Resources>
  5.  
  6. 输入命令绑定
  7. <Window.InputBindings>
  8. <KeyBinding Gesture="Ctrl+Alt+Q" Command="{StaticResource ToolCapClick}"/>
  9. </Window.InputBindings>
  10.  
  11. 命令执行方法绑定
  12. <Window.CommandBindings>
  13. <CommandBinding Command="{StaticResource ToolCapClick}"
  14. CanExecute="CommandBinding_ToolCapClick_CanExecute"
  15. Executed="CommandBinding_ToolCapClick_Executed"/>
  16. </Window.CommandBindings>

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

执行方法实现

  1. #region 截屏快捷键
  2. private void CommandBinding_ToolCapClick_CanExecute(object sender, CanExecuteRoutedEventArgs e)
  3. {
  4. e.CanExecute = true;
  5. }
  6.  
  7. private void CommandBinding_ToolCapClick_Executed(object sender, ExecutedRoutedEventArgs e)
  8. {
  9. try
  10. {
  11. CaptureImageTool capture = new CaptureImageTool();
  12. capture.CapOverToHandWriting += Capture_CapOverToHandWriting;
  13. capture.CapOverToBlackboard += Capture_CapOverToBlackboard;
  14. string saveName = String.Empty;
  15. if (capture.ShowDialog() == System.Windows.Forms.DialogResult.OK)
  16. {
  17.  
  18. //保存截取的内容
  19. System.Drawing.Image capImage = capture.Image;
  20. //上课存班级内部,不上课存外部
  21. string strSavePath = DataBusiness.GetCurrentTeachFilePath(SystemConstant.PATH_CAPS);
  22. if (!String.IsNullOrEmpty(strSavePath))
  23. {
  24. if (!Directory.Exists(strSavePath))
  25. {
  26. Directory.CreateDirectory(strSavePath);
  27. }
  28. saveName = strSavePath + DateTime.Now.ToString(SystemConstant.FORMAT_CAPS);
  29. }
  30. else
  31. {
  32.  
  33. saveName = PathExecute.GetPathFile(SystemConstant.PATH_SAVE + Path.DirectorySeparatorChar + SystemConstant.PATH_CAPS, DateTime.Now.ToString(SystemConstant.FORMAT_CAPS));
  34. }
  35.  
  36. capImage.Save(saveName + SystemConstant.EXTENSION_PNG, System.Drawing.Imaging.ImageFormat.Png);
  37. }
  38. }
  39. catch (Exception ex)
  40. {
  41. new Exception("capscreen module error:" + ex.Message);
  42. }
  43. }

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

第一步 引入到Winows API

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

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

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

  1. 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事件发生后获取窗体的句柄,并且注册全局快捷键

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

关于几个常熟的解释

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

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

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

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

继续在OnSourceInitialized函数中操作

  1. protected override void OnSourceInitialized(EventArgs e)
  2. {
  3. base.OnSourceInitialized(e);
  4.  
  5. IntPtr handle = new WindowInteropHelper(this).Handle;
  6. RegisterHotKey(handle, MY_HOTKEYID, 0x0001, 0x72);
  7.  
  8. HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
  9. source.AddHook(WndProc);
  10. }

下面来完成WndProc函数

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

三、给button控件添加快捷键

  1. <UserControl.Resources>
  2. <RoutedUICommand x:Key="ClickCommand" Text="点击快捷键" />
  3. </UserControl.Resources>
  4.  
  5. <UserControl.CommandBindings>
  6. <CommandBinding Command="{StaticResource ClickCommand}"
  7. Executed="ClickHandler" />
  8. </UserControl.CommandBindings>
  9.  
  10. <UserControl.InputBindings>
  11. <KeyBinding Key="C" Modifiers="Ctrl" Command="{StaticResource ClickCommand}" />
  12. </UserControl.InputBindings>
  13.  
  14. <Grid>
  15. <Button Content="button" Command="{StaticResource ClickCommand}"/>
  16. </Grid>

执行方法:

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

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. 一篇很全面的freemarker教程

    以下内容全部是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主要由如下4个部分组成:1,文本:直接输出的部分2,注释:<#-- ... --& ...

  2. GIT与SVN的区别

    1.GIT是分布式的,SVN不是: 这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别.如果你能理解这个概念,那么你就已经上手一半了.需要做一点声明,GIT并不是目前第一个或唯 ...

  3. js 随机数 洗牌算法

    function shuffle(arr){ var len = arr.length; for(var i = 0;i<len -1;i++) { var idx = Math.floor(M ...

  4. 解决Android调用https服务API时出错的问题

    今天同事告诉我说他的应用调用我开发的API报异常了,原因跟SSL有关系,因为之前调试一直调用的是HTTP服务API,今天调试HTTPS服务API时报错了,并且找到了一篇文章让我看了一眼,文章中提到了W ...

  5. 将CachedRowSet中的数据转储到对象中

    虽然还有很多bug,但凑合能用,就是将CachedRowSet中的数据转换成对象或List.省去了繁琐难看的一系列get/set方法. 先说调用: 注: cachedRowSet是查询的结果集 Stu ...

  6. java 正则表达式获取匹配和非获取匹配

    package test1; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestExp ...

  7. 有效的PhoneGap CSS: WebKit Tap Highlight Color

    原文链接:文章1:http://phonegap-tips.com/articles/essential-phonegap-css-webkit-tap-highlight-color.html(此文 ...

  8. 直观友好的单个memcache监控工具:phpmemcache.php

    上传phpmemcache.php到指定文件 修改文件中的: define('ADMIN_USERNAME','user');     // Admin Usernamedefine('ADMIN_P ...

  9. Nodejs开发(2.连接MongoDB)

    一.先配置MongoDB Win10下下载那个安装版,zip版的会报却各种DLL,安装在你希望的路径,实在安装错了,就剪切过来也行(本例E:\mongodb). 然后是配置启动脚本,就是写一个bat文 ...

  10. Wordpress 标题设置

    使用标题格式:首页(网站标题 - 网站副标题),其他页面(页面标题 | 网站标题) 在后台找到头部文件head.php <?php wp_title('|', true, 'right'); e ...