WPF之1:注册热键

最近做一个自动截图工具(用WPF),其中用到了热键的一点知识,参照了网上前辈们得经验,

总结如下:

WPF Hot Key
using System;
using System.Collections.Generic;
using System.Text;

// new add
using System.Windows;
using System.Windows.Forms;
using System.Collections;
using System.Windows.Interop;

namespace RegisterHotKey
{
///<summary>
/// 直接构造类实例即可注册
/// 自动完成注销
/// 注意注册时会抛出异常
/// 注册系统热键类
/// 热键会随着程序结束自动解除,不会写入注册表
///</summary>
publicclass HotKey
{
#region Member

int KeyId; //热键编号
IntPtr Handle ; //窗体句柄
Window Window ; //热键所在窗体
uint ControlKey ; //热键控制键
uint Key ; //热键主键

publicdelegatevoid OnHotKeyEventHandler(); //热键事件委托
publicevent OnHotKeyEventHandler OnHotKey =null; //热键事件

static Hashtable KeyPair =new Hashtable(); //热键哈希表
privateconstint WM_HOTKEY =0x0312; // 热键消息编号

publicenum KeyFlags //控制键编码
{
MOD_ALT
=0x1,
MOD_CONTROL
=0x2,
MOD_SHIFT
=0x4,
MOD_WIN
=0x8
}

#endregion

///<summary>
/// 构造函数
///</summary>
///<param name="win">注册窗体</param>
///<param name="control">控制键</param>
///<param name="key">主键</param>
public HotKey(Window win, HotKey.KeyFlags control, Keys key)
{
Handle
=new WindowInteropHelper(win).Handle;
Window
= win;
ControlKey
= (uint)control;
Key
= (uint)key;
KeyId
= (int)ControlKey + (int)Key *10;

if (HotKey.KeyPair.ContainsKey(KeyId))
{
thrownew Exception("热键已经被注册!");
}

//注册热键
if (false== HotKey.RegisterHotKey(Handle, KeyId, ControlKey, Key))
{
thrownew Exception("热键注册失败!");
}

//消息挂钩只能连接一次!!
if(HotKey.KeyPair.Count==0)
{
if (false== InstallHotKeyHook(this))
{
thrownew Exception("消息挂钩连接失败!");
}
}

//添加这个热键索引
HotKey.KeyPair.Add(KeyId, this);
}

//析构函数,解除热键
~HotKey()
{
HotKey.UnregisterHotKey(Handle, KeyId);
}

#region core

[System.Runtime.InteropServices.DllImport(
"user32")]
privatestaticexternbool RegisterHotKey(IntPtr hWnd, int id, uint controlKey, uint virtualKey);

[System.Runtime.InteropServices.DllImport(
"user32")]
privatestaticexternbool UnregisterHotKey(IntPtr hWnd, int id);

//安装热键处理挂钩
staticprivatebool InstallHotKeyHook(HotKey hk)
{
if (hk.Window ==null|| hk.Handle == IntPtr.Zero)
{
returnfalse;
}

//获得消息源
System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd(hk.Handle);
if (source ==null)
{
returnfalse;
}

//挂接事件
source.AddHook(HotKey.HotKeyHook);
returntrue;
}

//热键处理过程
staticprivate IntPtr HotKeyHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, refbool handled)
{
if (msg == WM_HOTKEY)
{
HotKey hk
= (HotKey)HotKey.KeyPair[(int)wParam];
if (hk.OnHotKey !=null)
{
hk.OnHotKey();
}
}
return IntPtr.Zero;
}

#endregion
}
}

最后需要注意的是,在应用这个HotKey的时候,不能用在window的构造函数内, 需要放到loaded 事件里,因为要等到window构造完成才能够挂载系统热键,如下:

Window_Loaded
privatevoid Window_Loaded(object sender, RoutedEventArgs e)
{
HotKey hotKey
=new HotKey(this, HotKey.KeyFlags.MOD_CONTROL | HotKey.KeyFlags.MOD_SHIFT, System.Windows.Forms.Keys.F12);
hotKey.OnHotKey
+=new HotKey.OnHotKeyEventHandler(hotKey_OnHotKey);
}

privatevoid hotKey_OnHotKey()
{
if (this.WindowState == WindowState.Normal)
{
this.WindowState = WindowState.Minimized;
this.Hide();
}
else
{
this.Show();
this.WindowState = WindowState.Normal;
}
}


 

本文参考地址:http://www.cnblogs.com/dabaopku/archive/2010/02/21/1670793.html

posted @ 2011-08-03 11:58  Alvin Yue  阅读(2216)  评论(1编辑  收藏  举报