在 C# 中清除鼠标缓冲区

Posted

技术标签:

【中文标题】在 C# 中清除鼠标缓冲区【英文标题】:Clearing mouse buffer in C# 【发布时间】:2013-07-30 10:31:40 【问题描述】:

我在 winform 的代码隐藏文件中执行此操作时遇到问题:

// Waiting Cursor + disabling form
Cursor = Cursors.WaitCursor;
this.Enabled = false;

// Synchronous method
SomeWork();

// Re-enabling form
Cursor = Cursors.Default;
this.Enabled = true;

当前行为

例如在Somework() 期间单击按钮将在重新启用表单后执行与按钮关联的方法。

预期行为

我不希望表单在禁用表单时存储用户的点击事件。

问题

有没有办法清空表单的点击缓存(这样我会在重新启用表单之前这样做)?

重要编辑

一个可能的简单解决方案是在表单后面的代码中实现IMessageFilter 接口。使用 PreFilterMessage 禁用左侧似乎很容易:

public bool PreFilterMessage(ref Message m)

    // Blocks all the messages relating to the left mouse button.
    return (m.Msg >= 513 && m.Msg <= 515) ;

但再一次,禁用和重新启用鼠标左键不会清空鼠标缓冲区 ...

【问题讨论】:

表单在禁用时无法接收任何点击消息。你确定吗?您能否提供有关您的演示的更多信息,例如您单击了哪个控件?... 【参考方案1】:

问题是进程在同一个线程中运行,因此在进程开始运行之前表单实际上并没有被禁用。简单的做法是使用 Application.DoEvents() 强制它在启动进程之前将所有内容设置为禁用,但更专业(可能更安全)的方法是在另一个线程中运行耗时的进程。

注意:在我自己的编程中遇到另一个问题后,我发现您可能必须运行 Application.DoEvents() 才能再次启用所有内容 - 它会触发用户在禁用控件上所做的任何点击,而不是等待完成的过程 - 启用控件 - 然后触发点击。

显然 DoEvents 很乱,我应该使用线程。

【讨论】:

如果不将 button.Enabled 属性设置为 false,它仍然会注册点击。上面的一小段代码禁用了我表单上的所有控件,它们不会注册点击。我把它放在运行一个长进程的按钮的点击事件中,就在进程运行之前,它完全按照你的要求工作......我在这个过程中点击了其他几个控件、按钮等,但什么也没有完成时发生。它到底有什么问题?在进程开始运行之前,您可能必须使用Application.DoEvents() 将控件设置为禁用。 DoEvents() 确实有效。但是很多cmets说这个方法很邪恶…… 您也可以在另一个线程中运行耗时的过程。 Application.DoEvents() 如果您以错误的方式使用它,可能会很危险。但它确实有一个目的。对此的最高评论是很好的阅读:***.com/questions/5181777/use-of-application-doevents 我编辑了我的答案。最初我的印象是您的表单实际上已设置为禁用,但控件没有。我的不好——我还没有在表单本身上使用 Enabled 属性,只是单独的控件,所以我不确定它做了什么。如果您在进程运行时禁用所有内容,则使用 Application.DoEvents() 可能非常安全。这就像使用 ShowDialog() 并从对话框表单运行进程一样。 当然!事实上,在另一个线程中运行进程是最初的想法。后来,我发现线程解决方案不是最好的。那是因为该进程一次启动 4 / 5 个线程。所以我必须等待所有线程终止才能启动另一个最终用户进程。这绝对不容易处理。这就是为什么我认为如果表单冻结是个好主意..

以上是关于在 C# 中清除鼠标缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

清除/释放 OpenGL ES 缓冲区

是否可以在间接绘图调用中清除模板缓冲区?

OpenGL:清除模板缓冲区,除了某些位?

CWE-14:编译器删除代码以清除缓冲区

删除/清除以前的缓冲区/流视频 mpmovieplayer iphone

在 C 中连接字符串:函数调用后字符串缓冲区没有被清除