如何创建 NSScrollWheel 类型的 NSEvent?

问题描述 投票:0回答:5

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

objective-c cocoa macos
5个回答
12
投票

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];

3
投票

这个问题在 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)
        }
    }
}

2
投票

您可以使用

CGEventRef
 创建 
CGEventCreateScrollWheelEvent
并使用
NSEvent
 将其转换为 
eventWithCGEvent:
。要向
CGEvent
添加信息,请使用
CGEventSetIntegerValueField
- 可能的 字段 包括
kCGScrollWheelEventDeltaAxis1
...2
...3


2
投票

尝试以下代码:

  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);

0
投票
func scrollEvent(wheel: Int32) -> NSEvent {
    CGEvent(scrollWheelEvent2Source: nil, units: .pixel, wheelCount: 1, wheel1: wheel, wheel2: 0, wheel3: 0)
        .flatMap{ NSEvent(cgEvent: $0) } ?? NSEvent()
}
© www.soinside.com 2019 - 2024. All rights reserved.