我正在尝试理解在按下鼠标按钮时Cocoa如何发送鼠标消息。
我的背景是在Window的编程中,所以这是我来自的视角......
所以我在Cocoa上学习,我理解的方式是......
这是我的问题:
为了解释我想要实现的目标,我的应用程序中有一个滑块控件:
鼠标按下时会在弹出窗口中显示更大的版本:
当它弹出时,鼠标光标会自动移动到较大的滑块手柄并跟踪鼠标,直到它被释放,然后移除弹出窗口并将光标移回较小的滑块。 (Here's a video显示)
我需要将捕获的鼠标事件重定向到弹出窗口NSWindow,或者我的鼠标跟踪循环已知哪个NSWindow当前捕获了鼠标。我可以通过跟踪鼠标事件来解决这个问题但是认为可能有一个API来获取它(例如:像Window的GetCapture()API)。
顺便说一句:我实际上有这个工作,但我做的事情感觉有点hacky,我想更好地理解OSX的方法 - 并确保我不会错过任何明显/更容易的事情。答案 0 :(得分:3)
注意: 我开始回答这个问题,结果却离我而去了。很抱歉长篇大论,但我相信我已经涵盖了您需要知道的有关事件和响应者的所有内容,以及一些我随着时间的推移遇到的问题的提示。希望我的解释简单易懂,如果您需要更多详细说明,请告诉我^^
我打算说 - 基于你的视频看起来你有它的工作:)
所以有很多文档可以解释我将要解释的内容,但是我将尝试分享我对关键点的简化理解,希望这比Apple Reference更有用
首先,更粗略的操作系统概念,有人可能会纠正我(对你的问题不是那么重要):
然后,我更积极的概念是:
-sendEvent:
(结帐NSEvent
中的NSApplication
类别)-mouseDown:
事件)NSView
实际上都是从NSResponder
继承的,任何NSResponder
都可以在响应者链中。 NSWindow
和其他AppKit对象也是NSResponder
的子类 -mouseDown:
或-mouseDragged:
或其他任何事件(唯一参数),并且您可以将其传递给您想要的任何NSResponder
,只要您当然可以参考[NSWindow firstResponder]
,每个NSResponder
都有一个名为nextResponder
的属性最后,这是我们的一个对象中-mouseDown:
事件的断点的屏幕截图
注意我们在主线程中,在运行循环中,我们的应用程序首先获取事件,将其传递给窗口,窗口确定第一个响应者(CanvasMaskView
因为这是鼠标单击,这个是鼠标下的最顶层视图,我们实际上手动将事件传递给响应者链
然后在响应者链上进行枚举,直到我们最终找到一个处理-mouseDown:
的对象,在顶部的ImageController
最后,请注意调用堆栈中的所有forwardMethods
?这是在nextResponder
nextResponder
的{{1}} nextResponder
等传递的事件。
这可以通过在每个堆栈帧检出$r13
寄存器来证明,该堆栈帧包含事件的当前接收者。请注意,在此屏幕截图中,我单击了堆栈帧,并在lldb中使用了po $r13
,然后单击下一个堆栈帧,并执行相同的操作:
这一点很重要,因为你可能会在你不知道的链中有一个响应者,它会消耗这个事件并且不会传递它,除非你调查这个链,否则你不会知道。通过“传递”,我的意思是你需要调用[super mouseDown]
,如果需要,它将自动传递事件。
哦是的,最后的注意!如果你压倒-mouseDown
我发现你必须打电话给super mouseDown
。否则-mouseUp:
事件将消失。虽然这是轶事,我很确定[super mouseDown]
可能会在操作系统中注册视图,因此它知道在哪里发送-mouseUp:
猜测