1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Windows;
  8. using System.Windows.Forms;
  9. using System.Windows.Interop;
  10.  
  11. namespace WpfHotKey
  12. {
  13. public class HotKeyHelper
  14. {
  15.  
  16. /// <summary>
  17. /// 如果函数执行成功,返回值不为0。
  18. /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error()
  19. /// </summary>
  20. /// <param name="hWnd">要定义热键的窗口的句柄</param>
  21. /// <param name="id">定义热键ID(不能与其它ID重复) </param>
  22. /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
  23. /// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换,
  24. /// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param>
  25. /// <returns></returns>
  26. [DllImport("user32.dll", SetLastError = true)]
  27. static extern bool RegisterHotKey(
  28. IntPtr hWnd,
  29. int id,
  30. KeyModifiers fsModifiers,
  31. int vk
  32. );
  33.  
  34. /// <summary>
  35. /// 取消注册热键
  36. /// </summary>
  37. /// <param name="hWnd">要取消热键的窗口的句柄</param>
  38. /// <param name="id">要取消热键的ID</param>
  39. /// <returns></returns>
  40. [DllImport("user32.dll", SetLastError = true)]
  41. static extern bool UnregisterHotKey(
  42. IntPtr hWnd,
  43. int id
  44. );
  45.  
  46. /// <summary>
  47. /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
  48. /// </summary>
  49. /// <param name="lpString"></param>
  50. /// <returns></returns>
  51. [DllImport("kernel32", SetLastError = true)]
  52. static extern short GlobalAddAtom(string lpString);
  53.  
  54. [DllImport("kernel32", SetLastError = true)]
  55. static extern short GlobalDeleteAtom(short nAtom);
  56.  
  57. /// <summary>
  58. /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
  59. /// </summary>
  60. [Flags()]
  61. public enum KeyModifiers
  62. {
  63. None = ,
  64. Alt = ,
  65. Ctrl = ,
  66. Shift = ,
  67. WindowsKey =
  68. }
  69. /// <summary>
  70. /// 热键的对应的消息ID
  71. /// </summary>
  72. public const int WM_HOTKEY = 0x312;
  73. static Dictionary<int, Action> keymap = new Dictionary<int, Action>(); //每一个key对于一个处理函数
  74.  
  75. /// <summary>
  76. /// 注册快捷键
  77. /// </summary>
  78. /// <param name="window">主体窗体</param>
  79. /// <param name="action">回调的方法</param>
  80. /// <returns>热键的标识</returns>
  81. public static void Regist(Window window, Action action)
  82. {
  83. HwndSource hWndSource;
  84. WindowInteropHelper wih = new WindowInteropHelper(window);
  85. hWndSource = HwndSource.FromHwnd(wih.Handle);
  86. //添加处理程序
  87. hWndSource.AddHook(MainWindowProc);
  88. int KeyCodes = -;
  89. if (!RegisterHotKey(wih.Handle, KeyCodes, HotKeyHelper.KeyModifiers.Ctrl, (int)Keys.S))
  90. {
  91. throw new Exception("注册失败");
  92. }
  93. else
  94. {
  95. if (keymap.Where(p => p.Key == KeyCodes).Count() > )
  96. throw new Exception("注册失败,应为这个组合键已经注册!!");
  97. else
  98. {
  99. keymap.Add(KeyCodes, action);
  100. }
  101. }
  102. }
  103. /// <summary>
  104. /// 卸载快捷键
  105. /// </summary>
  106. /// <param name="window">主体窗体</param>
  107. /// <param name="callBack">注册时回调的方法</param>
  108. public static void UnRegist(Window window, Action callBack)
  109. {
  110. foreach (KeyValuePair<int, Action> var in keymap)
  111. {
  112. WindowInteropHelper wih = new WindowInteropHelper(window);
  113. if (var.Value == callBack)
  114. {
  115. UnregisterHotKey(wih.Handle, var.Key);
  116. keymap.Remove(var.Key);
  117. return;
  118. }
  119. }
  120. }
  121.  
  122. private static IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
  123. {
  124. switch (msg)
  125. {
  126. case HotKeyHelper.WM_HOTKEY:
  127. {
  128. int sid = wParam.ToInt32();
  129. if (keymap.Where(p => p.Key == sid).Count() > )
  130. {
  131. keymap.Where(p => p.Key == sid).FirstOrDefault().Value.Invoke();
  132. }
  133. handled = true;
  134. break;
  135. }
  136. }
  137. return IntPtr.Zero;
  138. }
  139. }
  140. }

wpf程序热键的一个类的更多相关文章

  1. WPF程序只运行一个实例

    1.WPF程序在 启动窗口的构造函数执行InitializeComponent之前判断是否已经存在实例 不涉及服务器情况,可直接进行判断(不在mainwindow的构造函数中判断) // public ...

  2. 关于WPF程序只运行一个实例的方法

    找到的方法有两种: 1)http://www.cnblogs.com/liuyazhou/archive/2009/11/02/1594364.html 2)http://codereview.sta ...

  3. WPF 程序中启动和关闭外部.exe程序

    当需要在WPF程序启动时,启动另一外部程序(.exe程序)时,可以按照下面的例子来: C#后台代码如下: using System; using System.Collections.Generic; ...

  4. 如何在WPF程序中使用ArcGIS Engine的控件

    原文 http://www.gisall.com/html/47/122747-4038.html WPF(Windows Presentation Foundation)是美国微软公司推出.NET ...

  5. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

  6. 35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n); (2)编写一个类:ClassA来实现接口InterfaceA,实现int method(int n)接口方 法时,要求计算1到n的和; (3)编写另一个类:ClassB来实现接口InterfaceA,实现int method(int n)接口 方法时,要求计算n的阶乘(n

      35.按要求编写Java程序: (1)编写一个接口:InterfaceA,只含有一个方法int method(int n): (2)编写一个类:ClassA来实现接口InterfaceA,实现in ...

  7. Java基础-继承-编写一个Java应用程序,设计一个汽车类Vehicle,包含的属性有车轮个数 wheels和车重weight。小车类Car是Vehicle的子类,其中包含的属性有载人数 loader。卡车类Truck是Car类的子类,其中包含的属性有载重量payload。每个 类都有构造方法和输出相关数据的方法。最后,写一个测试类来测试这些类的功 能。

    #29.编写一个Java应用程序,设计一个汽车类Vehicle,包含的属性有车轮个数 wheels和车重weight.小车类Car是Vehicle的子类,其中包含的属性有载人数 loader.卡车类T ...

  8. java基础,继承类题目:编写一个Java应用程序,该程序包括3个类:Monkey类、People类和主类 E

    21.编写一个Java应用程序,该程序包括3个类:Monkey类.People类和主类 E.要求: (1) Monkey类中有个构造方法:Monkey (String s),并且有个public vo ...

  9. 在VS中手工创建一个最简单的WPF程序

    如果不用VS的WPF项目模板,如何手工创建一个WPF程序呢?我们来模仿WPF模板,创建一个最简单的WPF程序. 第一步:文件——新建——项目——空项目,创建一个空项目. 第二步:添加引用,Presen ...

随机推荐

  1. win8 C 盘 突然少了 十几G 空间 原因,解决方法

    原因: win8 默认最大虚拟内存为 16G多,但现在电脑本身内存就大,所以应该不用了.我现在电脑本身内存是16G. 如果C盘空间大,这个无所谓了,如果C盘空间小可以按以下操作,拿回16G空间: 解决 ...

  2. java语言实现的短信接入实例,各公司大同小异

    和几家短信平台接触过,都进行了接入测试.总体来说短信发送又快,覆盖率又全的,价格相对贵些.简易选两家分开使用,短信验证码的用一家贵的快的,普通的推广群发短信就用一个便宜的. 下面显示下测试代码 pub ...

  3. Start:at cnblogs firstDay

    C#旨在设计成为一种"简单.现代.通用",以及面向对象的程序设计语言,此种语言的实现,应提供对于以下软件工程要素的支持:强类型检查.数组维度检查.未初始化的变量引用检测.自动垃圾收 ...

  4. 阿里云搭建LAMP环境详细教程

    一.云服务器的选择 随着大数据时代的到来,为了满足更为复杂的运算和用户更为苛刻的需求,云计算应运而生,随之而来的就是云服务器.过去的服务器成本较高,运算模式较为单一,资源利用率不高,而云服务器的出现刚 ...

  5. opencv_协方差矩阵与协方差讲解

    统计学的基本概念 学过概率统计的孩子都知道,统计里最基本的概念就是样本的均值,方差,或者再加个标准差.首先我们给你一个含有n个样本的集合,依次给出这些概念的公式描述,这些高中学过数学的孩子都应该知道吧 ...

  6. svn执行clean up命令时报错

    svn执行clean up命令时报错“Previous operation has not finished; run 'cleanup' if it was interrupted”.无论你到那个父 ...

  7. BZOJ1002 轮状病毒

    Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...

  8. Material Design参考资料

    传送门: http://www.uisdc.com/comprehensive-material-design-note

  9. oracle查询使用频率和磁盘消耗需要缓存大小

    SELECT * FROM (SELECT Sql_Text, Sql_Id, Cpu_Time FROM V$sql ORDER BY Cpu_Time DESC) ORDER BY Rownum ...

  10. Unieap3.5-需要用到window.setTimeout的地方

    1.js大数据量操作且需要显示进度条 unieap.showLoading(true);//进度条 window.setTimeout(function(){ checkUtils.setAllRow ...