在我的 NSView 窗口之外获取 mouseMoved/mouseDragged

发布于 2024-11-15 10:35:39 字数 659 浏览 7 评论 0原文

我目前正在将一个应用程序(或更准确地说,一个 VST 插件)从 Windows 移植到 OSX。我对 OSX 编程有点陌生,但我使用的是使用 HICOcoaCreateView 添加到 Carbon 窗口(我从主机获得)的 Cocoa NSView。

Anywhoo...在这个视图中我想要 mouseMoved & mouseDragged 事件,但是当拖动时,即使鼠标离开我的 NSView (以及父窗口),我也想获取这些事件,但我似乎无法实现这一点。

在 Windows 上,我会在 mouseDown 上执行 SetCapture 来暂时获取所有鼠标事件。我在 Cocoa 中发现的最接近的东西是“addGlobalMonitorForEventsMatchingMask”,但这只是 10.6+,我很难相信这是之前不可能做到的事情。 (毕竟,这是通常用于可拖动组件(例如滚动条等)的东西。)

这让我发疯!

更新:

还有一个叫做 CGEventTapCreate 的东西,据我从稀缺的文档中可以看出,它类似于 addGlobalMonitor...但在 Carbon 中。我还没有完全了解 Carbon 和 Cocoa 之间的关系以及它们在哪里起作用。即使我的主要材料是可可,它也可以使用吗? (我从主机得到的窗口既可以是Cocoa,也可以是Carbon。真是一团糟。)

I'm currently porting an application (or to be more exact, a VST Plugin) from windows to OSX. I'm kinda new to OSX programming, but I'm using a Cocoa NSView added to a Carbon window (that I get from the host) using HICocoaCreateView.

Anywhoo... Inside this view I want to get mouseMoved & mouseDragged events, but when dragging I also want to get these events even when the mouse leaves my NSView (and also the parent window), but I just can't seem to make this happen.

On windows I would do a SetCapture on mouseDown to get all mouse events for a while. The closest thing I've found in Cocoa is "addGlobalMonitorForEventsMatchingMask", but this is 10.6+ only and I have a hard time believing this is something that wasn't possible to do before that. (After all, this is something that is commonly used for draggable components like scroll bars etc.)

This is driving me insane!

UPDATE:

There's something called CGEventTapCreate as well which, as far as I can tell from scarce docs, is similar to addGlobalMonitor... but in Carbon. I haven't gotten a hang of exactly how Carbon and Cocoa relate to eachother and what's working where. Is it usuable even though my main stuff is Cocoa? (The window I get from the host can be both Cocoa and Carbon. It's really all a mess.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

愛上了 2024-11-22 10:35:39

CGEventTap 东西并不是真正的 Carbon。它是在 Quartz 中,它可以被视为 Cocoa 的子框架(无论如何,Cocoa 实际上只是其他框架的集合)。 Carbon 是一个遗留(且已弃用)的框架,它的创建是为了简化 Mac OS 9(应用程序编程主要使用 C 语言完成)和 Mac OS X(使用 Objective-C)之间的过渡。并非 Apple 提供的所有 C 函数都是 Carbon;人们立即想到 Quartz 和 Grand Central Dispatch 作为使用 C 的现代框架(我相信是因为速度略有优势)。

在了解了背景之后,这些函数可以与 Cocoa 代码一起正常工作。据我所知, addGlobalEventMonitor...addLocalEventMonitor... 只是 CGEventTap 的 Obj-C 包装器。

我认为 CGEventTap 是正确的选择。是的,他们的文档很少,但很简单。 Dave DeLong 对 这个问题的回答问题可能会让您走上正确的道路。

The CGEventTap stuff isn't really Carbon. It's in Quartz, which can be treated as a sub-framework of Cocoa (which is really just a conglomeration of other frameworks anyways). Carbon is a legacy (and deprecated) framework that was created to ease the transition between Mac OS 9, where applications programming was mostly done in C, and Mac OS X, where Objective-C is used. Not every C function that Apple provides is Carbon; Quartz and Grand Central Dispatch spring to mind immediately as modern frameworks that use C (I believe for the slight speed advantage).

Having gotten the background out of the way, those functions work just fine with Cocoa code. So far as I can figure out, addGlobalEventMonitor... and addLocalEventMonitor... are just Obj-C wrappers around CGEventTaps.

I think a CGEventTap is the way to go. The docs for them are sparse, yes, but they're straightforward. Dave DeLong's answer to this SO question may put you on the right path.

北方的韩爷 2024-11-22 10:35:39

我想你需要做这样的事情...

EventHandlerRef     m_ApplicationMouseDragEventHandlerRef;          
EventHandlerRef     m_MonitorMouseDragEventHandlerRef;

{
    OSStatus ErrStatus;

    static const EventTypeSpec kMouseDragEvents[] =
      {
        { kEventClassMouse, kEventMouseDragged }
      };

    ErrStatus = InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_MonitorMouseDragEventHandlerRef);

    ErrStatus = InstallApplicationEventHandler(NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_ApplicationMouseDragEventHandlerRef);

    return true;
}

//implement these functions
OSStatus MouseHasDragged(EventHandlerCallRef inCaller, EventRef inEvent, void *pUserData){}

EventTypeSpec 需要更新/更改以进行移动,休息应该相同。
这是碳码。但您也可以查看石英桌面服务。

干杯!

I guess you need to do something like this...

EventHandlerRef     m_ApplicationMouseDragEventHandlerRef;          
EventHandlerRef     m_MonitorMouseDragEventHandlerRef;

{
    OSStatus ErrStatus;

    static const EventTypeSpec kMouseDragEvents[] =
      {
        { kEventClassMouse, kEventMouseDragged }
      };

    ErrStatus = InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_MonitorMouseDragEventHandlerRef);

    ErrStatus = InstallApplicationEventHandler(NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_ApplicationMouseDragEventHandlerRef);

    return true;
}

//implement these functions
OSStatus MouseHasDragged(EventHandlerCallRef inCaller, EventRef inEvent, void *pUserData){}

EventTypeSpec needs to be updated/changed for moving and rest should be same.
This is a carbon code. But you may also look at quartz desktop services.

Cheers!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文