Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 了解NSView/NSWindow鼠标捕获和调度_Objective C_Macos_Cocoa_Nsview_Nswindow - Fatal编程技术网

Objective c 了解NSView/NSWindow鼠标捕获和调度

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会发送此消息) 所以我学习可可的方法,我理解它的

我试图了解当按下鼠标按钮时,Cocoa如何发送鼠标消息

我的背景是在窗口的编程,所以这是我的观点来自

  • 窗口发送鼠标按下事件
  • 该应用程序可以调用SetCapture(hWnd)请求将所有未来的鼠标事件传递到该窗口,而不是鼠标下的窗口
  • 完成后,应用程序将调用ReleaseCapture以恢复正常的鼠标调度
  • 应用程序可能会收到WM_CANCELMODE消息,指示其释放捕获并取消任何跟踪模式。(例如:如果在鼠标拖动操作中按住Alt Tab键,Windows会发送此消息)
  • 所以我学习可可的方法,我理解它的方式是

  • NSWindow/NSView接收NSLeftMouseDown事件
  • Cocoa自动“捕获”鼠标并发送NSLeftMouseDragged事件,同时将鼠标按钮保持在单击的窗口/视图上
  • NSWindow/NSView接收NSLeftMouseUp事件
  • 以下是我的问题:

  • 窗口是否有办法取消捕获的鼠标并显式地将其重新捕获到另一个窗口
  • 有没有办法找出当前“捕获”鼠标的窗口(和/或视图)
  • 是否存在视图可能接收不平衡鼠标向下/向上事件的场景
  • 是否有类似WM_CANCELMODE的事件需要我关注以取消当前的跟踪操作
  • 为了解释我试图实现的目标,我的应用程序中有一个滑块控件:

    鼠标按下时在弹出窗口中显示较大的版本:

    当它弹出时,鼠标光标会自动移动到较大滑块的手柄上并跟踪鼠标,直到鼠标被释放,然后弹出窗口被移除,光标移回较小滑块。(展示)

    我需要将捕获的鼠标事件重定向到弹出的NSWindow,或者在我的鼠标跟踪循环中知道哪个NSWindow当前捕获了鼠标。我可以通过跟踪鼠标事件来解决这个问题,但我认为可能会有一个API来获取它(例如:像Window的GetCapture()API)

    顺便说一句:我确实在工作,但我所做的感觉有点粗糙,我想更好地理解OSX的方法——并且确保我没有遗漏任何明显/更简单的东西。

    注意:我开始回答这个问题,但最终它离开了我。很抱歉读了这么长时间,但我相信我已经介绍了您需要了解的有关事件和响应者的所有信息,以及一些关于我经历的问题的提示。希望我的解释简单易懂,如果你需要更详细的说明,请告诉我^^

    我想说的是——根据你的视频,看起来你已经成功了:)

    因此,有大量的文档涵盖了我将要解释的内容,但我将尝试分享我对关键点的简化理解,希望这比苹果的参考更有帮助

    首先,有人可能会纠正我的更粗糙的操作系统概念(无论如何,对你的问题来说并不那么重要):

    • 有“运行循环”,基本上是监听和处理事件。每个运行循环都与一个线程相关联
    • 与主线程关联的运行循环是接收鼠标事件和键盘事件的循环
    然后,我对更重要的概念持肯定态度:

    • 收到事件后,通过消息
      -sendEvent:
      (在
      NSApplication
      中签出
      NSEvent
      类别)将其传递给活动应用程序
    • 应用程序确定关键窗口,并确定事件的相应消息(鼠标左键单击将获得
      -mouseDown:
      事件)
    • 接收事件的窗口确定“第一响应者”。请注意,任何
      NSView
      实际上都是从
      NSResponder
      继承的,任何
      NSResponder
      都可以位于响应器链中
      NSWindow
      和其他AppKit对象也属于子类
      NSResponder
    • 如果该事件是鼠标事件,它实际上会将该事件发送到鼠标下方的最顶部视图
    • 您可以覆盖
      -mouseDown:
      -mouseDragged:
      或任何获取事件的内容(唯一参数),并且可以将其传递给您想要的任何
      NSResponder
      ,当然,只要您有对它的引用即可
    • 如果对象不响应事件,它会将其传递给响应器链
    • 响应者链实际上就像一个单链表。头部节点将是
      [NSWindow firstResponder]
      ,每个
      nsrresponder
      都有一个名为
      nextResponder
    最后,这里是一个对象中
    -mouseDown:
    事件断点的屏幕截图

    注意,我们在主线程中,在运行循环中,我们的应用程序首先获取事件,将其传递给窗口,窗口确定第一个响应者(
    CanvasMaskView
    ,因为这是鼠标单击,这是鼠标下最顶部的视图),我们实际上手动将事件传递给响应者链

    然后在响应器链上进行枚举,直到我们最终在顶部的
    ImageController
    中找到处理
    -mouseDown:
    的对象

    最后一件事,请注意调用堆栈中所有的
    forwardMethods
    ?这是传递给
    nextResponder
    nextResponder
    nextResponder
    等的事件

    这可以通过检查每个堆栈帧上的
    $r13
    寄存器来证明,其中包含事件的当前接收器。请注意,在这个屏幕截图中,我单击了一个堆栈框架,并使用了
    po$r13<