如何创建 NSScrollWheel 类型的 NSEvent?

发布于 2024-11-09 12:46:53 字数 145 浏览 0 评论 0原文

我想构造(假)一个 NSScrollWheel 类型的 NSEvent。还有一些其他类型的 NSEvent(mouseEvent、keyEvent、enterExitEvent、otherEvent)的 NSEvent 构造函数方法,但没有一个允许我设置,例如 deltaX。

I'd like to construct (fake) an NSEvent of type NSScrollWheel. There are NSEvent constructor methods for a few other types of NSEvents (mouseEvent, keyEvent, enterExitEvent, otherEvent), but none allows me to set, for example, deltaX.

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

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

发布评论

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

评论(5

月依秋水 2024-11-16 12:46:53

NSEvent 没有提供执行此操作的方法,但您可以创建一个 CGEvent 并围绕它创建一个 NSEvent 包装器。该事件将自动使用光标的当前位置。请参阅 CGEventCreateScrollWheelEvent。但是,使用 NSApplication 的 postEvent:atStart: 发布此事件不起作用(可能是因为它没有定义窗口)。您可以将 CGEvent 直接发布到事件流,也可以将 NSEvent 直接发送到视图的 scrollWheel: 方法。

CGWheelCount wheelCount = 2; // 1 for Y-only, 2 for Y-X, 3 for Y-X-Z
int32_t xScroll = −1; // Negative for right
int32_t yScroll = −2; // Negative for down
CGEventRef cgEvent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, wheelCount, yScroll, xScroll);

// You can post the CGEvent to the event stream to have it automatically sent to the window under the cursor
CGEventPost(kCGHIDEventTap, cgEvent);

NSEvent *theEvent = [NSEvent eventWithCGEvent:cgEvent];
CFRelease(cgEvent);

// Or you can send the NSEvent directly to a view
[theView scrollWheel:theEvent];

NSEvent doesn't provide a way to do this, but you can create a CGEvent and create an NSEvent wrapper around it. The event will automatically use the current location of the cursor. See CGEventCreateScrollWheelEvent. However, posting this event using NSApplication's postEvent:atStart: doesn't work (probably because it doesn't have a window defined). You can either post the CGEvent directly to the event stream, or send the NSEvent directly to a view's scrollWheel: method.

CGWheelCount wheelCount = 2; // 1 for Y-only, 2 for Y-X, 3 for Y-X-Z
int32_t xScroll = −1; // Negative for right
int32_t yScroll = −2; // Negative for down
CGEventRef cgEvent = CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, wheelCount, yScroll, xScroll);

// You can post the CGEvent to the event stream to have it automatically sent to the window under the cursor
CGEventPost(kCGHIDEventTap, cgEvent);

NSEvent *theEvent = [NSEvent eventWithCGEvent:cgEvent];
CFRelease(cgEvent);

// Or you can send the NSEvent directly to a view
[theView scrollWheel:theEvent];
青春有你 2024-11-16 12:46:53

这个问题在 2020 年就出现在我面前。我想我应该为找到这个答案的人发布 Swift 5 语法。如果按下 ⌘ 键,NSScrollView 子类中的此覆盖将交换上/下右/左滚动行为:

public override func scrollWheel(with event: NSEvent) {
    guard event.modifierFlags.contains(.command) else {
        super.scrollWheel(with: event)
        return
    }

    if let cgEvent: CGEvent = event.cgEvent?.copy() {
        cgEvent.setDoubleValueField(.scrollWheelEventDeltaAxis1, value: Double(event.scrollingDeltaX))
        cgEvent.setDoubleValueField(.scrollWheelEventDeltaAxis2, value: Double(event.scrollingDeltaY))

        if let nsEvent = NSEvent(cgEvent: cgEvent) {
            super.scrollWheel(with: nsEvent)
        }
    }
}

This has come up for me in 2020. I thought I'd post the Swift 5 syntax for anyone finding this answer. This override in an NSScrollView subclass will swap up/down right/left scroll behavior if the ⌘ key is down:

public override func scrollWheel(with event: NSEvent) {
    guard event.modifierFlags.contains(.command) else {
        super.scrollWheel(with: event)
        return
    }

    if let cgEvent: CGEvent = event.cgEvent?.copy() {
        cgEvent.setDoubleValueField(.scrollWheelEventDeltaAxis1, value: Double(event.scrollingDeltaX))
        cgEvent.setDoubleValueField(.scrollWheelEventDeltaAxis2, value: Double(event.scrollingDeltaY))

        if let nsEvent = NSEvent(cgEvent: cgEvent) {
            super.scrollWheel(with: nsEvent)
        }
    }
}
浮萍、无处依 2024-11-16 12:46:53

您可以使用 CGEventCreateScrollWheelEvent 并将其转换到 NSEventeventWithCGEvent:。要将信息添加到 CGEvent,请使用 CGEventSetIntegerValueField --其中可能的 字段kCGScrollWheelEventDeltaAxis1...2...3

You can create a CGEventRef using CGEventCreateScrollWheelEvent and convert it to an NSEvent with eventWithCGEvent:. To add information to the CGEvent, use CGEventSetIntegerValueField -- among the possible fields are kCGScrollWheelEventDeltaAxis1, ...2, and ...3.

长不大的小祸害 2024-11-16 12:46:53

尝试以下代码:

  int scrollingDeltaX =... //custom value

//if you have some NSEvent *theEvent 
  CGEventRef cgEvent = CGEventCreateCopy(theEvent.CGEvent);

  CGEventSetIntegerValueField(cgEvent, kCGScrollWheelEventDeltaAxis2, scrollingDeltaX);

  NSEvent *newEvent = [NSEvent eventWithCGEvent:cgEvent];
  CFRelease(cgEvent);

Try following code:

  int scrollingDeltaX =... //custom value

//if you have some NSEvent *theEvent 
  CGEventRef cgEvent = CGEventCreateCopy(theEvent.CGEvent);

  CGEventSetIntegerValueField(cgEvent, kCGScrollWheelEventDeltaAxis2, scrollingDeltaX);

  NSEvent *newEvent = [NSEvent eventWithCGEvent:cgEvent];
  CFRelease(cgEvent);
柠檬 2024-11-16 12:46:53

我们可以从 CGEvent 创建scrollWheel NSEvent:

func scrollEvent(wheel: Int32) -> NSEvent {
    CGEvent(scrollWheelEvent2Source: nil, units: .pixel, wheelCount: 1, wheel1: wheel, wheel2: 0, wheel3: 0)
        .flatMap { NSEvent(cgEvent: $0) } ?? NSEvent()
}

We can create scrollWheel NSEvent from CGEvent:

func scrollEvent(wheel: Int32) -> NSEvent {
    CGEvent(scrollWheelEvent2Source: nil, units: .pixel, wheelCount: 1, wheel1: wheel, wheel2: 0, wheel3: 0)
        .flatMap { NSEvent(cgEvent: $0) } ?? NSEvent()
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文