【问题标题】:Why a form is needed for a SetWinEventHook callback?为什么 SetWinEventHook 回调需要表单?
【发布时间】:2013-07-17 09:53:28
【问题描述】:

目前,我正在使用强大的 SetWinEventHook() 函数来捕获一些用户界面的操作,例如最小化和最大化计算机上程序运行的其他窗口的一些操作。

所以我通过使用 BrendanMcK 在 this post 上提供的代码来启发自己,并且它确实有效(我的意思是:当事件发生时调用回调函数)直到行

MessageBox.Show("Something")

存在。但我不想为这个程序使用任何形式或窗口..

some research 之后,我发现这种钩子需要一个消息循环来允许重定向来自其他窗口句柄的消息。显然,使用 Application.Run() should do the trick 调用线程,但我更喜欢在 C# 对象本身中更干净的东西。

所以我的问题是:是否可以在对象的方法中创建消息循环?

http://bytes.com/topic/c-sharp/answers/557342-thread-message-loop-c

【问题讨论】:

    标签: forms winapi hook


    【解决方案1】:

    不,该函数不需要窗口句柄,因此不需要“表单”。但是该功能的 MSDN 文档非常明确:

    调用 SetWinEventHook 的客户端线程必须有一个消息循环才能接收事件。

    消息循环在任何想要接收由其他进程或线程在外部生成的通知的程序中都是通用的。这是producer-consumer problem 的常见解决方案。显然,任何 GUI 应用程序都需要这样的解决方案,Windows 消息是由操作系统生成的。 SetWinEventHook() 没有什么不同,可访问性事件源自其他程序。没有干净的机制来“中断”一个线程并使其运行其他代码,导致的重入问题非常难以处理。线程必须合作,它必须处于空闲状态并准备好接收通知以安全地处理它。消息循环解决了这个问题。

    在方法中注入消息循环(调用 Application.Run)当然是可能的。但请记住,在您使用 Application.ExitThread 显式停止循环之前,该方法不会返回。因此,该调用通常只有一个好地方,即程序的 Main() 方法。

    使用 Winforms 或 WPF 项目模板开始您的项目是实现此目的的好方法。在 pinvoking SetWinEventHook 之后,您无需实际创建窗口,调用 Application.Run() 而不带参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-03
      • 1970-01-01
      • 2016-02-27
      • 2017-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多