第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > .net中关于增加快捷键(热键)的方法 及UserControl中类似form的Active和Deactive事件

.net中关于增加快捷键(热键)的方法 及UserControl中类似form的Active和Deactive事件

时间:2019-08-17 18:51:33

相关推荐

.net中关于增加快捷键(热键)的方法 及UserControl中类似form的Active和Deactive事件

一、增加快捷键

1、使用windows api,主要的api及解释如下:

RegisterHotKey(IntPtr hWnd, int id,uint fsModifiers, uint vk);

UnregisterHotKey(IntPtr hWnd, int id);

其中关于id中在msdn中的描述如下:

An application must specify an id value in the range 0x0000 through 0xBFFF.

A shared DLL must specify a value in the range 0xC000 through 0xFFFF (the range returned by the GlobalAddAtom function).

To avoid conflicts with hot-key identifiers defined by other shared DLLs,

a DLL should use the GlobalAddAtom function to obtain the hot-key identifier.

完整的代码段:

public partial class frmKeybordShortcuts : Form

{

int _myFindHotKeyId = 100;

int _mySaveHotKeyId = 200;

public frmKeybordShortcuts()

{

InitializeComponent();

this.Load += frmKeybordShortcuts_Load;

this.FormClosed += frmKeybordShortcuts_FormClosed;

}

/// <summary>

/// 在这里进行快捷键注册工作

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

void frmKeybordShortcuts_Load(object sender, EventArgs e)

{

KeybordShortcutsWapper.RegisterHotKey(this, Keys.Control | Keys.F, this._myFindHotKeyId);

KeybordShortcutsWapper.RegisterHotKey(this, Keys.Control | Keys.S, this._mySaveHotKeyId);

}

/// <summary>

/// 在这里释放快捷键

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

void frmKeybordShortcuts_FormClosed(object sender, FormClosedEventArgs e)

{

KeybordShortcutsWapper.UnregisterHotKey(this,this._myFindHotKeyId);

KeybordShortcutsWapper.UnregisterHotKey(this, this._mySaveHotKeyId);

}

/// <summary>

/// 这里的进行快捷键分派的处理方法

/// </summary>

/// <param name="m"></param>

protected override void WndProc(ref Message m)

{

if (m.Msg == KeybordShortcutsWapper.WM_HOTKEY

&& m.HWnd == this.Handle)

{

if (m.WParam.ToInt32() == this._myFindHotKeyId) //根据注册时候不同id 对应的不同的快捷键进行快捷键分派

{

MessageBox.Show("Control+F is pressed");

}

else if (m.WParam.ToInt32() == this._mySaveHotKeyId)

{

MessageBox.Show("Control + S is pressed");

}

}

base.WndProc(ref m);

}

}

/// <summary>

/// windows api 的一个包装器

/// </summary>

public class KeybordShortcutsWapper

{

private static int MOD_ALT = 0x1;

private static int MOD_CONTROL = 0x2;

private static int MOD_SHIFT = 0x4;

private static int MOD_WIN = 0x8;

public static int WM_HOTKEY = 0x312;

/// <summary>

/// Define a system-wide hot key.

/// </summary>

/// <param name="hWnd">

/// A handle to the window that will receive WM_HOTKEY messages generated by the

/// hot key. If this parameter is NULL, WM_HOTKEY messages are posted to the

/// message queue of the calling thread and must be processed in the message loop.

/// </param>

/// <param name="id">

/// The identifier of the hot key. If the hWnd parameter is NULL, then the hot

/// key is associated with the current thread rather than with a particular

/// window. If a hot key already exists with the same hWnd and id parameters,

/// see Remarks for the action taken.

/// </param>

/// <param name="fsModifiers">

/// The keys that must be pressed in combination with the key specified by the

/// uVirtKey parameter in order to generate the WM_HOTKEY message. The fsModifiers

/// parameter can be a combination of the following values.

/// MOD_ALT 0x0001

/// MOD_CONTROL 0x0002

/// MOD_SHIFT 0x0004

/// MOD_WIN 0x0008

/// </param>

/// <param name="vk">The virtual-key code of the hot key.</param>

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

private static extern bool RegisterHotKey(IntPtr hWnd, int id,

uint fsModifiers, uint vk);

/// <summary>

/// Frees a hot key previously registered by the calling thread.

/// </summary>

/// <param name="hWnd">

/// A handle to the window associated with the hot key to be freed. This parameter

/// should be NULL if the hot key is not associated with a window.

/// </param>

/// <param name="id">

/// The identifier of the hot key to be freed.

/// </param>

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]

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

public static void RegisterHotKey(Form f, Keys key,int keyId)

{

int modifiers = 0;

if ((key & Keys.Control) == Keys.Control)

modifiers = modifiers | MOD_CONTROL;

if ((key & Keys.Shift) == Keys.Shift)

modifiers = modifiers | MOD_SHIFT;

Keys k =

key

& ~Keys.Control //~符号表示按位取反,也会用在析构函数前对析构函数进行标识

& ~Keys.Shift;

RegisterHotKey(f.Handle, keyId, (uint)modifiers, (uint)k);

}

public static void UnregisterHotKey(Form f,int keyId)

{

try

{

UnregisterHotKey(f.Handle, keyId);

}

catch (Exception ex)

{

Debug.WriteLine(ex.ToString());

}

}

2、重写ProcessCmdKey方法:

无论在窗体还是UserControl中都可以对ProcessCmdKey进行重写以达到自己想要的快捷键;

具体代码如下:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)

{

var key = keyData & Keys.KeyCode;

var modeifierKey = keyData & Keys.Modifiers;

if(modeifierKey == Keys.Control && key==Keys.F)

{

MessageBox("Control+F is pressed");

return true;

}

//if ((keyData & Keys.Control) == Keys.Control

//&&(keyData & Keys.F) == Keys.F)

//{

//MessageBox.Show("Control + F is pressed");

//return true;

//}

return base.ProcessCmdKey(ref msg, keyData);

}

注意:快捷键能够被正常激活的条件是:这个窗体或者控件是焦点窗体或者控件

这里有个参考网址:/csharp/.net/net_general/keyboard/article.php/c4639/Building-Keyboard-Accelerators-into-NET-Windows-Forms-Applications.htm

综上所述:

设置快捷键时,要看快捷键是应用程序级的,还是系统级,如果是系统级的则用api方法,否则尽量使用重写方法实现;

再有,需要注意使用api注册快捷键(热键)时,可能会和系统中已经存在的其他应用的快捷键冲突,从而导致快捷键设置不起作用;

在重写ProcessCmdKey方法时,如果子容器和父容器(比如一个user control和一个form)中定义的快捷键相同(冲突),那么

当子容器中获得焦点后,父容器的快捷键将会被子容器的淹没;

==============================================================================================================

关于UserControl中类似Form的Active和Deactive事件:

分别是:Enter,Leave

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。