【问题标题】:Cocoa Message Pump?可可消息泵?
【发布时间】:2013-04-11 02:00:23
【问题描述】:

我正在尝试实现一个 Cocoa 消息泵。我对 Cocoa API 没有太多经验,但我设法使用 NSApp nextEventMatchingMask 实现了一个基本的泵。

这种方法的问题是我没有得到所有的事件,而且我得到的事件似乎只适用于主窗口,而不是窗口上的任何小部件。

我的 UI 是在代码中生成的(没有 nib),我没有使用 Cocoa runLoop(因此需要消息泵)。我正在尝试将所有 Objective-C++ 和 Cocoa 代码保持在最低限度。

需要循环所有传入的事件并将它们分派给适当的函数以根据对象和事件处理它们。

这是显示我的意思的伪代码(以及我所拥有的,主要是,除了它只执行“主窗口”事件)

event = GetNextEvent();
while (event)
{
    if(event->type == MOUSE_DOWN) 
    { mouse_down(event->target); }
    event = GetNextEvent();
}

在 OS X 上有什么技巧吗?

【问题讨论】:

  • 使用没有运行循环的 NSApp 不太可能成功。几乎可以保证不会使用 AppKit 窗口和控件。
  • 这只是猜测还是你有什么具体的东西?对于父窗口的所有消息,当前使用没有 runLoop 的 NSApp 是成功的,所以它已经是大部分的方式了。如果我也能得到孩子们的消息(这似乎是一个合理的要求),那就完全成功了。
  • AppKit 中使用 NSTimer、-performSelectorAfterDelay:、CFRunLoopPerformBlock 等的所有部分都需要运行循环才能运行。我不是在猜测,但您可能需要拆开 Hopper 并进行一些分解才能看到它的证据。
  • (例如 NSAnimation 是基于计时器的)
  • @Catfish_Man 除了“通用”小部件(即按钮、标签、列表等)之外,我不需要任何其他东西。我不能允许“控制”传递给任何阻塞函数,如 runLoop。如果我可以“ping”(运行一次)一个 runLoop(与“do events”非常相似),那也足够了。

标签: c++ macos cocoa objective-c++


【解决方案1】:

抱歉,正如 cmets 中已经提到的那样 -

尝试使用 Cocoa 模仿 Classic Mac OS 7 样式的运行循环并不是一个好主意,因为 AppKit 中的几乎所有内容(计时器、通知、事件、队列...)都依赖于在 Cocoa 应用程序的每个线程中存在一个“正确的”NSRunLoop

您可以查看this page on CocoaDevNSRunLoop docs 了解更深入的信息。

有关简约的 Cocoa 示例应用,请查看“Cocoa With Love”博客上的这篇精彩博文:
Minimalist Cocoa programming

【讨论】:

  • 我对使用 Cocoa runLoop 不感兴趣。我的应用程序中没有(显式)运行循环,因此“执行事件”消息泵是唯一(最佳)解决方案。除了窗口和小部件的交互事件“单击、鼠标移动等...”之外,我不关心计时器、通知或任何其他内容。我并不是在“构建一个 Cocoa 应用程序”,而是我允许(可选地)以与平台无关的方式(尽可能)在现有应用程序中创建/操作窗口和小部件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-25
  • 1970-01-01
  • 2016-03-29
  • 2015-06-16
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
相关资源
最近更新 更多