最近,对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. javascript中的删除方法

    可能呢再开发的过程中呢使用的不是很多,但是碰上呢可以注意下 1.比如: var x = 10; delete x; console.log(x); 结果是多少,是10,不是异常也不是undefined ...

  2. zabbix_agent 步骤

    Zabbix server 做好了,只要在安装一个zabbix-agent(监控端就可以啦) groupadd zabbix useradd -g zabbix zabbix 下载一个客户端的安装包: ...

  3. PowerDesigner V16.5 安装文件 及 破解文件

    之前在网上找个假的,只能看,不能创建自己的DB; 或者 不能破解的,比较伤脑筋. 偶在这里提供一个 可长期使用的版本. PowerDesigner165_破解文件.rar    链接:http://p ...

  4. 四个查找命令find,locate,whereis,which的区别

    find最强大,但是检索硬盘,比较慢: whereis只能查二进制文件.说明文档,源文件等: locate能查所有文件,但跟whereis一样都是查数据库里的内容,速度快,但有延时: which 只能 ...

  5. JS写的CRC16校验算法(查表法)

    var CRC = {}; CRC._auchCRCHi = [ 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0 ...

  6. SQL优化 1

    SQL_ID:fvdwtfv18yy0m 先看看sql的预估执行计划 select * from table(dbms_xplan.display_awr('fvdwtfv18yy0m')); sql ...

  7. CentOS7配置日志(VirtualBox)

    版本为CentOS-Minimal 1.VirtualBox下安装CentOS. 新建虚拟机 下载CentOS,放入盘片,启动虚拟机,按提示开始安装(建议内存1G,硬盘10G以上)   2. 设置网络 ...

  8. SynchronousQueue 的简单应用

    SynchronousQueue是这样一种阻塞队列,其中每个 put 必须等待一个 take,反之亦然.同步队列没有任何内部容量,甚至连一个队列的容量都没有.      不能在同步队列上进行 peek ...

  9. Maintaining Your Signing Identities and Certificates 维护你的签名标识和证书

    Code signing your app lets users trust that your app has been created by a source known to Apple and ...

  10. LeetCode Alien Dictionary

    原题链接在这里:https://leetcode.com/problems/alien-dictionary/ 题目: There is a new alien language which uses ...