您的位置:首页 > 其它

在WPF中如何注册热键(转)

2013-01-05 10:43 246 查看
/article/4886563.html

WPF注册热键大荟萃

源码下载:/article/4886567.html

研究了一晚上,终于搞定了啦~~~~~

首先完整复制下面的第一篇文章中的代码

然后以下代码是


private
void Register(object sender, RoutedEventArgs e)



{


IntPtr handle=new WindowInteropHelper(this).Handle;



int id = 1000;



bool r=HotKey.RegisterHotKey(handle, id,(uint)HotKey.KeyFlags.MOD_CONTROL, (uint)System.Windows.Forms.Keys.F12);


MessageBox.Show(r.ToString()+" "+handle.ToString()+"
");


HotKey.InstallHotKeyHook(this);


}

其中Id随意取值,好像都没有问题

一直受第三篇文章干扰(说实在的,确实让人恼火,它的RegisterHotkey(Keys Key, KeyFlags keyflags)

明明是Key在前 keyflags在后,可是带入APi的

结底还是自己不够细心,足足浪费了半小时,郁闷!)

RegisterHotKey后却是反过来的,结果我也跟着他的弄反了control和F12,归根

然后反注册就很简单了,唉,累死了~~

在WPF中如何注册热键

来源:/article/5960740.html
不说废话,直接看代码吧

,其关键就是 System.Windows.Interop.HwndSource类。
第一步:注册热键,需要使用API函数,具体的参照网上的其它文章。唯一需要注意的是需要使用KeyInterop.VirtualKeyFromKey函数将
WPF的Key枚举转化为API函数可以使用的VirtualKeyCode :



///
<summary>

/// 注册热键处理函数

///
</summary>

///
<param name="hWnd">用于处理热键消息的窗体句柄</param>

///
<param name="id">热键的编号</param>

///
<param name="controlKey">控制键</param>

///
<param name="virtualKey">热键的虚键编码</param>

///
<returns>

///
<c>true</c>:注册成功<br/>

///
<c>false</c>:注册失败

///
</returns>

///
<remarks></remarks>

///
<history>

/// [ZengE] 2009-7-8 22:28 创建

///
</history>

[System.Runtime.InteropServices.DllImport("user32")]

public
static
extern
bool RegisterHotKey(IntPtr hWnd,
int id,
uint controlKey,
uint virtualKey);

///
<summary>

/// 注销指定的热键

///
</summary>

///
<param name="hWnd">用于处理热键消息的窗体句柄</param>

///
<param name="id">要注销的热键编号</param>

///
<returns>

///
<c>true</c>:注销成功<br/>

///
<c>false</c>:注销失败

///
</returns>

///
<remarks></remarks>

///
<history>

/// [ZengE] 2009-7-8 22:30 创建

///
</history>

[System.Runtime.InteropServices.DllImport("user32")]

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

第二步:注册热键处理函数,主要的难点就在这里,在.NET的WinForm程序中一般使用重写Form的WinProc方法或者注册IMessageFilter来实现的,
但是在WPF中以上两种方式都无法获得热键消息的处理机会,除非是在WPF程序中隐藏一个常规的Form

(最开始就是这么弄得,后来觉得实在是太丑陋了)



1


///
<summary>

2


/// 安装热键处理挂钩

3


///
</summary>

4


///
<param name="window">The window.</param>

5


///
<returns>

6


///
<c>true</c>:安装成功<br/>

7


///
<c>false</c>:安装失败

8


///
</returns>

9


///
<value>消息源</value>

10


///
<remarks></remarks>

11


///
<history>

12


/// [ZengE] 2009-7-8 23:57 创建

13


///
</history>

14


public
static
bool InstallHotKeyHook( Window window )

15


{

16


//判断组件是否有效

17


if (
null
== window )

18


{

19


//如果无效,则直接返回

20


return
false;

21


}

22


23


//获得窗体的句柄

24


System.Windows.Interop.WindowInteropHelper helper =
new System.Windows.Interop.WindowInteropHelper( window );

25


26


//判断窗体句柄是否有效

27


if ( IntPtr.Zero
== helper.Handle )

28


{

29


//如果句柄无效,则直接返回

30


return
false;

31


}

32


33


//获得消息源

34


System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd( helper.Handle );

35


36


//判断消息源是否有效

37


if (
null
== source )

38


{

39


//如果消息源无效,则直接返回

40


return
false;

41


}

42


43


//挂接事件

44


source.AddHook( HotKeyHook );

45


46


//返回安装成功

47


return
true;

48


}

49


50


///
<summary>

51


/// 热键处理过程

52


///
</summary>

53


///
<param name="hwnd">触发消息的窗口句柄</param>

54


///
<param name="msg">要被处理的消息编号</param>

55


///
<param name="wParam">消息参数</param>

56


///
<param name="lParam">消息参数</param>

57


///
<param name="handled">消息是否被处理</param>

58


///
<returns></returns>

59


///
<remarks></remarks>

60


///
<history>

61


/// [ZengE] 2009-7-8 23:54 创建

62


///
</history>

63


private
static IntPtr HotKeyHook( IntPtr hwnd,
int msg, IntPtr wParam, IntPtr lParam,
ref
bool handled )

64


{

65


//判断是否为热键消息

66


if ( msg
== WM_HOTKEY )

67


{

68


69


}

70


71


//返回

72


return IntPtr.Zero;

73


}

74


75


///
<summary>

76


/// 热键消息编号

77


///
</summary>

78


private
const
int WM_HOTKEY
=
0x0312;

以上代码在Windows2008下测试通过。

在c#中使用全局快捷键

来源:http://hi.baidu.com/55csharp/blog/item/de6fef88efcebdbb0e24442f.html

由于.net并没有提供快捷键的库,所以要使用该功能得通过api实现。

在winapi中,注册和注销全局快捷键分别是通过RegisterHotKey和UnregisterHotKey函数实现。在c#中直接使用该api显得不够简洁,这里我提供了一个友好点的封装。

代码如下:

static class Hotkey

{

系统api#region 系统api

[DllImport("user32.dll")]

[return: MarshalAs(UnmanagedType.Bool)]

static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, Keys vk);

[DllImport("user32.dll")]

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

#endregion

/**//// <summary>

/// 注册快捷键

/// </summary>

/// <param name="hWnd">持有快捷键窗口的句柄</param>

/// <param name="fsModifiers">组合键</param>

/// <param name="vk">快捷键的虚拟键码</param>

/// <param name="callBack">回调函数</param>

public static void Regist(IntPtr hWnd, HotkeyModifiers fsModifiers, Keys vk, HotKeyCallBackHanlder callBack)

{

int id = keyid++;

if (!RegisterHotKey(hWnd, id, fsModifiers, vk))

throw new Exception("regist hotkey fail.");

keymap[id] = callBack;

}

/**//// <summary>

/// 注销快捷键

/// </summary>

/// <param name="hWnd">持有快捷键窗口的句柄</param>

/// <param name="callBack">回调函数</param>

public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack)

{

foreach (KeyValuePair<int, HotKeyCallBackHanlder> var in keymap)

{

if (var.Value == callBack)

UnregisterHotKey(hWnd, var.Key);

}

}

/**//// <summary>

/// 快捷键消息处理

/// </summary>

public static void ProcessHotKey(System.Windows.Forms.Message m)

{

if (m.Msg == WM_HOTKEY)

{

int id = m.WParam.ToInt32();

HotKeyCallBackHanlder callback;

if (keymap.TryGetValue(id, out callback))

{

callback();

}

}

}

const int WM_HOTKEY = 0x312;

static int keyid = 10;

static Dictionary<int, HotKeyCallBackHanlder> keymap = new Dictionary<int, HotKeyCallBackHanlder>();

public delegate void HotKeyCallBackHanlder();

}

enum HotkeyModifiers

{

MOD_ALT = 0x1,

MOD_CONTROL = 0x2,

MOD_SHIFT = 0x4,

MOD_WIN = 0x8

}

这里通过Hotkey类实现功能的封装,使用非常简单。下面为参考测试代码。

void Test()

{

MessageBox.Show("Test");

}

protected override void WndProc(ref Message m)

{

base.WndProc(ref m);

Hotkey.ProcessHotKey(m);

}

private void button1_Click(object sender, EventArgs e)

{

Hotkey.UnRegist(this.Handle, Test);

}

当程序form1启动时,注册了两个快捷键Alt+T和Ctrl+Shift+K,单击button1的时候会注销快捷键Alt+T。代码比较简单,这里就不多介绍了。

注:快捷键是通过消息触发的,因此要重载WndProc函数,在里面添加对快捷键回调消息的处理方法Hotkey.ProcessHotKey(m)。

C#
设置全局热键

来源:/article/6360213.html



using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

using System.Collections;

namespace HotKey1

{

public
partial
class Form1 : Form

{

public Form1()

{

InitializeComponent();

}

public
delegate
void HotkeyEventHandler(int
HotKeyID);

private
int Hotkey1;

public
class Hotkey : System.Windows.Forms.IMessageFilter

{

Hashtable keyIDs =
new Hashtable();

IntPtr hWnd;

public
event HotkeyEventHandler OnHotkey;

public
enum KeyFlags

{

MOD_ALT =
0x1,

MOD_CONTROL =
0x2,

MOD_SHIFT =
0x4,

MOD_WIN =
0x8

}

[DllImport("user32.dll")]

public
static
extern UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32
vk);

[DllImport("user32.dll")]

public
static
extern UInt32 UnregisterHotKey(IntPtr hWnd, UInt32 id);

[DllImport("kernel32.dll")]

public
static
extern UInt32 GlobalAddAtom(String lpString);

[DllImport("kernel32.dll")]

public
static
extern UInt32 GlobalDeleteAtom(UInt32 nAtom);

public Hotkey(IntPtr hWnd)

{

this.hWnd
= hWnd;

Application.AddMessageFilter(this);

}

public
int RegisterHotkey(Keys Key, KeyFlags keyflags)

{

UInt32 hotkeyid = GlobalAddAtom(System.Guid.NewGuid().ToString());

RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)Key);

keyIDs.Add(hotkeyid, hotkeyid);

return (int)hotkeyid;

}

public
void UnregisterHotkeys()

{

Application.RemoveMessageFilter(this);

foreach (UInt32 key
in keyIDs.Values)

{

UnregisterHotKey(hWnd, key);

GlobalDeleteAtom(key);

}

}

public
bool PreFilterMessage(ref
System.Windows.Forms.Message m)

{

if (m.Msg
==
0x312)

{

if (OnHotkey
!=
null)

{

foreach (UInt32 key
in keyIDs.Values)

{

if ((UInt32)m.WParam
== key)

{

OnHotkey((int)m.WParam);

return
true;

}

}

}

}

return
false;

}

}

public
void OnHotkey(int
HotkeyID) //Ctrl+F2隐藏窗体,再按显示窗体。

{

if (HotkeyID
== Hotkey1)

{

if (this.Visible
==
true)

this.Visible
=
false;

else

this.Visible
=
true;

}

else

{

this.Visible
=
false;

}

}

private
void Form1_Load(object
sender, EventArgs e)

{

Hotkey hotkey;

hotkey =
new Hotkey(this.Handle);

Hotkey1 = hotkey.RegisterHotkey(System.Windows.Forms.Keys.F2, Hotkey.KeyFlags.MOD_CONTROL);
//定义快键(Ctrl + F2)

hotkey.OnHotkey
+=
new HotkeyEventHandler(OnHotkey);

}

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: