6

大家好。我正在尝试了解如何在控制台应用程序中处理事件。我宁愿不使用静默 WinForms(尽管我知道这是一种方法)来做到这一点。我已经阅读了一个类似的问题及其回复。请参阅下面的响应文本(链接):

STA 线程的基本要求是它需要运行消息泵。在 Windows 窗体中,您可以使用 Application.Run。或者您可以使用 user32!GetMessage 和 DispatchMessage 手动编写消息泵。但在 WinForms 或 WPF 中使用它可能更容易。

使用“user32 -> GetMessage”和“user32 -> DispatchMessage”的程序的基本结构是什么?

4

3 回答 3

3

请参阅 MSDN 中的“使用消息和消息队列”主题(在 Win32 和 COM 开发 > 用户界面 > Windows 用户体验 > Windows 管理 > Windows 用户界面 > 窗口 > 消息和消息队列下;您可能需要查看同一节中的其他文章和示例)。快速总结,省略错误处理并使用 C 语法而不是 C#,原因如下所述:

RegisterClass(...);
CreateWindow(...);
ShowWindow(...);  // probably not in your case
while (GetMessage(&msg, NULL, 0, 0)) {
  TranslateMessage(&msg);
  DispatchMessage(&msg);
}

从窗口设置样板中可以看出,这仍然依赖于“静默窗口”,尽管它是通过 Win32 API 而不是通过 WinForms 创建和发送消息的。所以你这样做并没有真正获得任何东西。因此,我觉得将这些东西翻译成 C# 并没有多大意义——如果您的问题的唯一解决方案是一个不可见的窗口,那么您不妨使用一个不可见的 Windows 窗体以及该平台附带的所有友好包装器。

但是,如果您实际上没有像链接问题的海报那样使用 Windows 窗体控件,那么您可以很高兴地在控制台应用程序中使用 .NET 事件。对 STA 的限制和对消息泵的需求特定于从 WinForms 和 ActiveX 控件(如 WebBrowser)接收事件(或来自 Win32 HWND 的消息,尽管这不一定需要 STA)。

于 2009-04-19T05:43:59.307 回答
0

你想处理什么样的事件?设置消息泵将允许您处理 Windows API 消息。但由于这是一个控制台应用程序,我想不出任何感兴趣的 Windows API 消息。

我们倾向于将“事件”视为与 Windows 消息相关联,因为 Windows 窗体应用程序中的控件使用 EventHandler 委托来响应用户输入,这些委托被调用以响应 Windows API 消息。但是,没有理由不能在控制台应用程序中使用委托。而且您不需要消息泵。您甚至可以使用 EventHandler 委托,尽管它看起来不合适,因为它不会响应 Windows API 消息。

当然,还有其他类型的“事件”您可能会感兴趣。涉及控制台应用程序的最常见的事件场景是等待来自控制台(stdin)的输入。如果有多个线程在使用,阻塞 WaitHandle 或其他同步对象也很常见。这两种情况都可以被认为是一种事件处理。

如果您创建了一个隐藏的窗口(一个由来已久的做法),您仍然需要一条 Windows 消息来响应。所以问题是:你试图回应什么或回应谁?

于 2009-04-19T06:21:47.017 回答
0

我会使用 Application.Run 方法。我不认为它会自动创建一个隐藏窗口,它只是泵送消息,这是满足 STA 要求所需要的。

使用 PInvoke 编写您自己的消息泵并没有提供任何优势,并且引用 System.Windows.Forms 并没有太大的负担,因为它已经在您可能遇到的每台机器上。

于 2009-04-21T13:05:11.413 回答