[因此,我试图在有人按下热键时也从表单(在本例中为SHIFT + A)之外获取用户输入。现在,由于我想将标签添加到表单应用程序中,所以我决定使用usercontrols,现在的问题是,我无法访问usercontrol上的formcloses事件(来自form1),这意味着我必须以某种方式解析我想要的任何内容在formcloses事件中执行。
用户控件(命名为首页)
public partial class Home : UserControl
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);
[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
enum KeyModifier
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
WinKey = 8
}
public Home()
{
InitializeComponent();
int id = 0; // The id of the hotkey.
RegisterHotKey(this.Handle, id, (int)KeyModifier.Shift, Keys.A.GetHashCode()); //Register Shift + A as global hotkey.
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0x0312)
{
/* Note that the three lines below are not needed if you only want to register one hotkey.
* The below lines are useful in case you want to register multiple keys, which you can use a switch with the id as argument, or if you want to know which key/modifier was pressed for some particular reason. */
Keys key = (Keys)(((int)m.LParam >> 16) & 0xFFFF); // The key of the hotkey that was pressed.
KeyModifier modifier = (KeyModifier)((int)m.LParam & 0xFFFF); // The modifier of the hotkey that was pressed.
int id = m.WParam.ToInt32(); // The id of the hotkey that was pressed.
MessageBox.Show("Hotkey has been pressed!");
// do something
}
}
}
现在,我希望解析unregisterHotKey方法以在程序关闭后清除所有热键(这样,当应用程序关闭时,您将无法按SHIFT-A键]
UnregisterHotKey(this.Handle, 0);
现在我的问题是:您怎么将用户控件中的内容解析为我的主窗体上的formclosing事件,以便在有意义的情况下成功清除所有键...
我找到了一个解决方案(部分起作用)。
我只是添加了一个将取消注册密钥并从formclosing事件内部的主表单中调用密钥的公共void
在IDE中,有时无法正常工作。但是,在构建解决方案时,它似乎可以正常工作
这是我建议的处理方式:
因为您已经覆盖了WndProc
以处理WM_HOTKEY
,所以也要处理WM_DESTROY。当UserControl Windows由于其父窗体已关闭而将被销毁时,将发送此消息。当您的UserControl收到此消息时,您可以调用UnregisterHotKey()
。
UserControls不需要了解有关其ParentForm
容器的任何信息:热键在创建UserControl时注册,而在销毁UserControl时取消注册。
比处理Dispose()
更好,因为除非应用程序关闭,除非父窗体明确调用Dispose()
,否则可能不会真正处理UserControl。
我已经对原始代码进行了一些修改,因为它缺少了几段。
public partial class Home : UserControl
{
[DllImport("user32.dll")]
private static extern bool RegisterHotKey(IntPtr hWnd, int id, KeyModifier fsModifiers, int vk);
[DllImport("user32.dll")]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
private const int WM_DESTROY = 0x0002;
private const int WM_HOTKEY = 0x0312;
private const int baseHotKeyID = 0x100;
enum KeyModifier : int
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
WinKey = 8,
NoRepeat = 0x4000
}
public Home() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!RegisterHotKey(this.Handle, baseHotKeyID, KeyModifier.Shift | KeyModifier.NoRepeat, (int)Keys.F11)) {
MessageBox.Show("RegisterHotKey Failed");
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
switch (m.Msg) {
case WM_DESTROY:
UnregisterHotKey(this.Handle, baseHotKeyID);
m.Result = IntPtr.Zero;
break;
case WM_HOTKEY:
int hotKeyID = m.WParam.ToInt32();
var keyPressed = (Keys)(m.LParam.ToInt32() >> 16);
var modifier = (KeyModifier)(m.LParam.ToInt32() & 0xFF);
switch (hotKeyID) {
case baseHotKeyID:
// Handle single HotKey
if (modifier == KeyModifier.Shift) {
MessageBox.Show("Hotkey has been pressed!");
}
break;
}
m.Result = IntPtr.Zero;
break;
}
}
}