我注意到,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方法呢? 他们的目的和用例是什么?
单声道.NET项目是否包含在最stream行的Linux发行版的最新版本中?
写入Windows应用程序事件日志,无需注册事件源
如何使用c + +或vb.net获取当前打开的应用程序在Windows中?
有没有去确定在Windows进程中可用的内存剩余量?
我想每个方法的执行顺序是不同的。
这是我所知道的(或者我认识的):
PreFilterMessage :首先拦截消息。 您可以在这里停止所有以下方法的消息分发!
ProcessCmdKey :拦截所有按键,甚至是组合键,特殊键和命令键。 很好地检测整个表单上的快捷键(如Ctrl + D)。 您可以在这里停止密钥的分配。
WndProc :第二个筛选后拦截消息? 我只用它来检测用户是否点击右上angular的“X”,但我想这是可能的另一种方法!
ProcessDialogKey :只拦截ONE键,可能在ProcessCmdKey之后,所有键的控件事件之前。
PreProcessMessage :在WndProc之前和PreFilterMessage之后? 我不知道为什么它被使用。
ProcessKeyMessage :截获关键信息。 它似乎很less使用。
ProcessKeyPreview :截取预览事件之前的键? 也很less使用。
深入的,我认为这是正确的执行顺序:
预过滤
过滤
预处理
处理
活动
为什么这么多步骤?
任何信息或具体的用例将不胜感激!
如何检测串口是否在使用.net
通过多台机器时间戳数据 – 时间已closures?
.NET中是否有CalDAV + CardDAV服务器实现?
安装程序自定义操作无法读取所有registry值
错误MSB3147:找不到所需的文件“setup.bin”发布到本地失败
本地Windows GUI应用程序通常有一个消息循环,底层winapi调用是GetMessage()。 但有很多窗口获取消息,底层的winapi调用是dispatchMessage()。 在你的.NET应用程序中,你只有一个对Application.Run()的调用,但是每个控件都有一个WndProc()方法。 它们大多数都隐藏在.NET Framework代码中,只有在覆盖它时才会公开。
一般来说,需要挂钩到消息循环中,在将消息发送到控件并到达WndProc()之前截取消息。 最显而易见的原因是键盘快捷键,无论哪个控件都有焦点,您都要对其执行操作。 如果您必须在每个控件上使用KeyDown来检测快捷方式,那当然是非常痛苦的。 不太明显的原因,例如,ActiveX控件与主机进行协商是值得注意的。
Winforms提供了很多扩展点来拦截消息。 太多了,实际上,却是一个不可避免的副作用,不想预测在什么情况下可能有用。 为了:
IMessageFilter.PreFilterMessage()让您在GetMessage()检索到消息后立即查看消息。 请记住,只能看到发送到消息队列的消息,底层调用是PostMessage(),您看不到已发送的消息。 这限制了用户输入,键盘和鼠标消息的可用性。 很少去修补这个,但你可以用它来使鼠标的行为不同,并检测到用户正在与你的程序进行交互。 希望自动注销用户经过一段时间不活动的程序员使用它。
OnPreviewKeyDown()和PreviewKeyDown事件。 具体到有重点的控制。 在测试快捷方式之前,控件拦截按键的一种方法。 例如,您可以在使用光标键移动焦点之前检测光标键。 重写IsInputKey()的替代方法。
PreProcessMessage()。 非常类似于PreFilterMessage,但特定于具有焦点的控件。 对于ActiveX控件很重要,我个人从来没有使用它。
ProcessCmdKey()。 这是实现您自己的快捷键操作的主力方法。
IsInputKey(),允许控件投票是否应该将通常用于导航的键发送给控件。 例如,当您使用光标键时,可以覆盖此方法。
ProcessDialogKey()。 就像ProcessCmdKey()一样,但是对于应该像输入键一样对待的按键进行过滤。 默认实现使键盘消息冒泡到父控件,让您选择重写ProcessCmdKey()的位置。 我想不出一个很好的理由,为什么你要重写它,而且从来没有这样做,除了停止冒泡。
IsInputChar()与IsInputKey非常相似,但对于KeyPress事件。 从来没有使用过它自己,但一种方式来过滤输入提前。
ProcessDialogChar(),可以用来给键入快捷键的按键行为。 这是不寻常的。
WndProc(),处理消息的主要方法。 您可以覆盖它以允许控件响应现有事件未覆盖的消息。 或者自定义现有的本地控件的行为。
ProcessKeyEventArgs(),这是生成键盘事件(OnKeyDown,OnKeyUp,OnKeyPress)的一般方法,由Control.WndProc()调用。 我想不出一个理由来重写它,值得注意的是实现了古怪的Form.KeyPreview属性,一个VB6的compat属性,可能是它暴露的原因。
确实是一个曲折的迷宫。
试图保持它的理智,总是覆盖ProcessCmdKey()来实现快捷键。 重写IsInputKey()让您的控件看到导航键。 而且只能覆盖WndProc()来自定义现有的控件。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。