最近遇到一个问题,在一个WinForm窗口中,按ALT+Z能够实现最小化到托盘及从托盘回复正常窗口。
刚开始,试着在窗口的KeyPress事件中添加,但是当窗口最小化到托盘后,焦点已经不在窗口上了,因此将不能捕捉键盘按键按下的事件,因此不能从托盘弹出。经测试,这种方法是错误的。
既然KeyPress事件不能解决问题,那么为什么不能添加热键呢?
添加热键的方法是
BOOL RegisterHotKey(
HWND hWnd,
int id,
UINT fsModifiers,
UINT vk
);
其中参数hWnd是注册热键的窗口句柄,id是热键的标识符,fsModifiers是在创建WM_HOTKEY消息时必须跟用户定义的按键一同按下的特殊组合键,他的值为:
Value |
Description |
MOD_ALT |
Either ALT key must be held down. |
MOD_CONTROL |
Either CTRL key must be held down. |
MOD_KEYUP |
Both key up events and key down events generate a WM_HOTKEY message. |
MOD_SHIFT |
Either SHIFT key must be held down. |
MOD_WIN |
Either WINDOWS key was held down. These keys are labeled with the Microsoft Windows logo. |
我们可以使用这个函数注册我们的热键。
在C#中使用这个函数,我们必须从user32.dll中将此函数导入,而且必须重写WndProc函数来捕捉热键消息。
以下为示例代码:
[DllImport("user32.dll")]
public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint control, Keys vk);
[DllImport("user32.dll")]
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private void Form1_Load(object sender, EventArgs e)
{
RegisterHotKey(this.Handle, 888, 1, Keys.Z);
this.Hide();
this.ShowInTaskbar = true;
this.comboBox1.SelectedIndex = 0;
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case 0x0312:
if (m.WParam.ToString().CompareTo("888") == 0)
{
if (bIsShowed)
{
this.Hide();
this.ShowInTaskbar = true;
this.WindowState = FormWindowState.Minimized;
this.notifyIcon1.Visible = true;
this.bIsShowed = false;
}
else
{
this.Visible = true;
this.ShowInTaskbar = false;
this.WindowState = FormWindowState.Normal;
this.Activate();
this.notifyIcon1.Visible = false;
bIsShowed = true;
}
UnregisterHotKey(this.Handle, 888);
RegisterHotKey(this.Handle, 888, 1, Keys.Z);
}
break;
default:
break;
}
base.WndProc(ref m);
}