.NET的SuppressKeypress是如何工作的?
[这个问题是WinAPI编程的核心]
在.NET术语中: 当Keydown事件在WinForms中触发时,您可以设置KeyEventArgs.SuppressKeypress = true,然后不将后续的Keypress / Character发送给控件. 我找到了以下SO答案,详细说明了Control如何做到: 但现在我不明白,这怎么能正常工作?如果程序在其队列中构建了几个keydown消息,并且你通过的前几个消息会发生什么,但是最后一个你使用上面的方法抑制,那么RemovePendingMessages函数不会从队列中删除所有字符,而不仅仅是最后一个? 在Windows API术语中: 考虑一个典型的消息循环,它调用TranslateMessage从键盘输入中获取WM_CHAR消息.在WM_KEYDOWN上检查密钥是否被识别为命令,在这种情况下它不应生成字符.如何去除可能发布到消息队列的WM_CHAR消息以有效地抑制按键? .NET中的现有解决方案似乎使用循环PeekMessage(..,WM_CHAR,PM_REMOVE)从队列中删除所有字符,但如果队列中有多个keydown消息,则不会删除太多字符吗? 解决方法
你的直觉是正确的,事实上它确实是你所描述的行为不端.一些代码可以看到这个错误:
public partial class Form1 : Form { public Form1() { InitializeComponent(); } int keycnt = 0; protected override void OnKeyDown(KeyEventArgs e) { keycnt++; if (keycnt == 3) e.SuppressKeyPress = true; base.OnKeyDown(e); } protected override void OnKeyPress(KeyPressEventArgs e) { Debug.Print("Press {0}",e.KeyChar); base.OnKeyPress(e); } protected override void WndProc(ref Message m) { if (m.Msg >= 0x100 && m.Msg <= 0x109) Debug.WriteLine(m); base.WndProc(ref m); } [System.Runtime.InteropServices.DllImport("user32.dll")] private static extern IntPtr PostMessage(IntPtr hwnd,int msg,IntPtr wp,IntPtr lp); protected override void OnMouseClick(MouseEventArgs e) { for (int ix = 0; ix < 5; ++ix) { PostMessage(this.Handle,0x100,(IntPtr)Keys.A,IntPtr.Zero); } } } 单击表单以触发测试.请注意OnKeyDown如何仅抑制第3次击键.但只有前2个通过,其余的吞下去. 我从来没有见过有人抱怨过这个. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows – 在NSIS中复制文件
- windows – Detours替代Registry拦截
- 如何从rootkit /后门/僵尸网络等检查Linux服务器是否干净?
- Office 365 – 垃圾邮件过滤的“敏感词列表”中有什么?
- Windows的System.Control是什么颜色的? (Visual Studio设计
- winforms – Form1.Designer.cs很难保持版本控制
- windows-server-2008-r2 – 2008 R2 DC拒绝与外部NTP服务器
- 在windows上编译32位和64位mono
- windows-installer – 如何在Installshield 2018中添加发布
- 如何在Windows Azure虚拟机上强制进行IP更改?
- windows-7 – 使用GlusterFS和Windows避免SPOFS
- windows-phone-7 – Windows Phone 7设置
- windows – 128GB RAM的页面错误
- 适用于Windows Vista的Subversion客户端
- Microsoft office 2019 正式版镜像下载
- windows-server-2003 – 重新启动后Windows 2003
- 在Windows Vista上,有没有办法允许应用程序始终以
- Windows – 事件ID 9331 MSExchangeSA和事件ID 9
- 如何在Windows服务中运行APScheduler …我几乎就
- 制作一个拦截Windows中网络流量的程序