Objective c 了解NSView/NSWindow鼠标捕获和调度
我试图了解当按下鼠标按钮时,Cocoa如何发送鼠标消息 我的背景是在窗口的编程,所以这是我的观点来自Objective c 了解NSView/NSWindow鼠标捕获和调度,objective-c,macos,cocoa,nsview,nswindow,Objective C,Macos,Cocoa,Nsview,Nswindow,我试图了解当按下鼠标按钮时,Cocoa如何发送鼠标消息 我的背景是在窗口的编程,所以这是我的观点来自 窗口发送鼠标按下事件 该应用程序可以调用SetCapture(hWnd)请求将所有未来的鼠标事件传递到该窗口,而不是鼠标下的窗口 完成后,应用程序将调用ReleaseCapture以恢复正常的鼠标调度 应用程序可能会收到WM_CANCELMODE消息,指示其释放捕获并取消任何跟踪模式。(例如:如果在鼠标拖动操作中按住Alt Tab键,Windows会发送此消息) 所以我学习可可的方法,我理解它的
- 有“运行循环”,基本上是监听和处理事件。每个运行循环都与一个线程相关联
- 与主线程关联的运行循环是接收鼠标事件和键盘事件的循环
- 收到事件后,通过消息
(在-sendEvent:
中签出NSApplication
类别)将其传递给活动应用程序NSEvent
- 应用程序确定关键窗口,并确定事件的相应消息(鼠标左键单击将获得
事件)-mouseDown:
- 接收事件的窗口确定“第一响应者”。请注意,任何
实际上都是从NSView
继承的,任何NSResponder
都可以位于响应器链中NSResponder
和其他AppKit对象也属于子类NSWindow
NSResponder
- 如果该事件是鼠标事件,它实际上会将该事件发送到鼠标下方的最顶部视图
- 您可以覆盖
或-mouseDown:
或任何获取事件的内容(唯一参数),并且可以将其传递给您想要的任何-mouseDragged:
,当然,只要您有对它的引用即可NSResponder
- 如果对象不响应事件,它会将其传递给响应器链
- 响应者链实际上就像一个单链表。头部节点将是
,每个[NSWindow firstResponder]
都有一个名为nsrresponder
nextResponder
-mouseDown:
事件断点的屏幕截图
注意,我们在主线程中,在运行循环中,我们的应用程序首先获取事件,将其传递给窗口,窗口确定第一个响应者(CanvasMaskView
,因为这是鼠标单击,这是鼠标下最顶部的视图),我们实际上手动将事件传递给响应者链
然后在响应器链上进行枚举,直到我们最终在顶部的ImageController
中找到处理-mouseDown:
的对象
最后一件事,请注意调用堆栈中所有的forwardMethods
?这是传递给nextResponder
的nextResponder
的nextResponder
等的事件
这可以通过检查每个堆栈帧上的$r13
寄存器来证明,其中包含事件的当前接收器。请注意,在这个屏幕截图中,我单击了一个堆栈框架,并使用了po$r13<