我注意到,WinForms有许多处理命令或键( Process*()
)和(预)过滤系统消息的方法,但是他们各自的目的对我来说还不清楚。
官方文件有些模糊,我还没有find明确而完整的答复。
我讲下面的方法:
PreFilterMessage(ref Message m)
ProcessCmdKey(ref Message msg, Keys keyData)
WndProc(ref Message m)
ProcessDialogKey(Keys keyData)
PreProcessMessage(ref Message msg)
ProcessKeyMessage(ref Message m)
ProcessKeyPreview(ref Message m)
一些用于拦截密钥(如ProcessCmdKey
或ProcessDialogKey
),另一些用于拦截消息(相互之间)。 但为什么有多less方法呢? 他们的目的和用例是什么?
我想每个方法的执行顺序是不同的。
这是我所知道的(或者我认识的):
PreFilterMessage
:首先拦截消息。 您可以在这里停止所有以下方法的消息分发! ProcessCmdKey
:拦截所有按键,甚至是组合键,特殊键和命令键。 很好地检测整个表单上的快捷键(如Ctrl + D)。 您可以在这里停止密钥的分配。 WndProc
:第二个筛选后拦截消息? 我只用它来检测用户是否点击右上angular的“X”,但我想这是可能的另一种方法! ProcessDialogKey
:只拦截ONE键,可能在ProcessCmdKey
之后,所有键的控件事件之前。 PreProcessMessage
:在WndProc
之前和PreFilterMessage
之后? 我不知道为什么它被使用。 ProcessKeyMessage
:截获关键信息。 它似乎很less使用。 ProcessKeyPreview
:截取预览事件之前的键? 也很less使用。 深入的,我认为这是正确的执行顺序:
为什么这么多步骤?
任何信息或具体的用例将不胜感激!
本地Windows GUI应用程序通常有一个消息循环,底层winapi调用是GetMessage()。 但有很多窗口获取消息,底层的winapi调用是DispatchMessage()。 在你的.NET应用程序中,你只有一个对Application.Run()的调用,但是每个控件都有一个WndProc()方法。 它们大多数都隐藏在.NET Framework代码中,只有在覆盖它时才会公开。
一般来说,需要挂钩到消息循环中,在将消息发送到控件并到达WndProc()之前截取消息。 最显而易见的原因是键盘快捷键,无论哪个控件都有焦点,您都要对其执行操作。 如果您必须在每个控件上使用KeyDown来检测快捷方式,那当然是非常痛苦的。 不太明显的原因,例如,ActiveX控件与主机进行协商是值得注意的。
Winforms提供了很多扩展点来拦截消息。 太多了,实际上,却是一个不可避免的副作用,不想预测在什么情况下可能有用。 为了:
确实是一个曲折的迷宫。
试图保持它的理智,总是覆盖ProcessCmdKey()来实现快捷键。 重写IsInputKey()让您的控件看到导航键。 而且只能覆盖WndProc()来自定义现有的控件。