2

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

因此,我通过在这篇文章中使用 BrendanMcK 提供的代码来启发自己,并且它确实有效(我的意思是:当事件发生时调用回调函数)直到行

MessageBox.Show("Something")

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

经过一番研究,我发现这种钩子需要一个消息循环来允许重定向来自其他窗口句柄的消息。显然,使用 Application.Run() 调用线程应该可以解决问题,但我更喜欢在 C# 对象本身中使用更干净的东西。

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

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

4

1 回答 1

2

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

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

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

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

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

于 2013-07-17T14:06:55.543 回答