但这没有用。我该如何解决这个问题?
你是什么意思“它不起作用”?您问题中的代码对我来说看起来是正确的。
它可能不起作用的唯一原因是因为RegisterHotKey http://msdn.microsoft.com/en-us/library/windows/desktop/ms646309.aspx函数返回错误,而您没有检查它。为了使其工作,您需要添加SetLastError属性 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.setlasterror.aspx到它的声明,这会导致运行时缓存它设置的 Win32 错误代码。完成此操作后,您可以检查错误代码(如果函数返回false
)通过调用GetLastWin32Error功能 http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getlastwin32error.aspx。我建议使用这个函数的结果来生成并抛出一个Win32Exception http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx.
修改您的声明RegisterHotKey
如下:
[DllImport("user32.dll", PreserveSig = false)]
public static extern bool RegisterHotKey(IntPtr hWnd,
int id,
uint fsModifiers,
Keys key);
您对该函数的调用如下:
if (!RegisterHotKey(this.Handle, MYACTION_HOTKEY_ID, 0, Keys.F12))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
完成后,我怀疑您会看到抛出异常并显示错误消息:
热键已注册
好吧,这使得调试问题变得更加简单,不是吗!您可能需要选择不同的热键,因为RegisterHotKey
函数文档明确告诉我们:
The F12 key is reserved for use by the debugger at all times, so it should not be registered as a hot key. Even when you are not debugging an application, F12 is reserved in case a kernel-mode debugger or a just-in-time debugger is resident.
When I run the code and register F11 as a hotkey, it works just fine for me.
在这里我无法理解一些行,例如:
const int MYACTION_HOTKEY_ID = 1;
m.Msg == 0x0312 && m.WParam.ToInt32() == MYACTION_HOTKEY_ID
base.WndProc(ref m);
谁能帮我理解这些线条?
Sure:
第一行声明一个常量值,该值唯一标识您使用RegisterHotKey
功能。更具体地说,它对应于id
函数的参数。您在初次通话时传递了它。
-
这会检查窗口过程(WndProc
) 查看消息是否 (Msg
)正在处理的是WM_HOTKEY message http://msdn.microsoft.com/en-us/library/windows/desktop/ms646279.aspx. The WM_HOTKEY
每当您使用注册的热键时,消息都会自动发布到您的窗口RegisterHotKey
功能被按下。
你不应该真正使用魔法数字0x0312
不过,直接说吧,因为你不是唯一一个不确定这意味着什么的人。相反,定义一个常量并使用它:
const int WM_HOTKEY = 0x0312;
m.Msg == WM_HOTKEY
该条件测试的第二部分(在&&
)检查wParam
消息字段以查看按下的热键是否是您注册的热键。请记住MYACTION_HOTKEY_ID
是您的热键的唯一 ID。这WM_HOTKEY
消息文档告诉我们检查wParam
这就是我们确定按下了哪个热键的方法。
这调用基类的窗口过程。换句话说,你所做的就是覆盖虚拟的WndProc
方法,允许您添加一些额外的代码(您的处理WM_HOTKEY
)。当您完成附加逻辑后,您想要继续基类的逻辑,因此您继续转发消息。