How to create an NSEvent of type NSScrollWheel?
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, en开发者_运维知识库terExitEvent, otherEvent), but none allows me to set, for example, deltaX.
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];
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
.
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);
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)
}
}
}
精彩评论