Я хотел бы создать (подделать) NSEvent типа NSScrollWheel. Существуют методы конструктора NSEvent для нескольких других типов событий NSEvent (mouseEvent, keyEvent, enterExitEvent, otherEvent), но ни один из них не позволяет мне установить, например, deltaX.
Как создать NSEvent типа NSScrollWheel?
Ответы (4)
NSEvent не предоставляет способа сделать это, но вы можете создать CGEvent и создать вокруг него оболочку NSEvent. Событие будет автоматически использовать текущее местоположение курсора. См. CGEventCreateScrollWheelEvent. Однако публикация этого события с помощью postEvent:atStart:
NSApplication не работает (вероятно, потому, что для него не определено окно). Вы можете отправить 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];
Вы можете создать CGEventRef
, используя CGEventCreateScrollWheelEvent
и преобразовать его в NSEvent
с помощью eventWithCGEvent:
. Чтобы добавить информацию в CGEvent
, используйте CGEventSetIntegerValueField
-- среди возможных поля: kCGScrollWheelEventDeltaAxis1
, ...2
и ...3
.
Попробуйте следующий код:
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);
Это пришло мне в голову в 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)
}
}
}