2017-03-15 9 views
1

Ich entwickle gerade eine Cross-Plattform-Anwendung für iOS und MacOS, die Ihr iOS-Gerät als Trackpad funktionieren lässt.Cocoa-Anwendung: Programmgesteuertes Scrollen?

Mit CGDisplayMoveCursorToPoint kann ich den Cursor auf dem Bildschirm bewegen. Klappt wunderbar. Mit diesem Stück Code in der "Host" Anwendung (das heißt auf macOS ausgeführt wird), kann ich Mausklicks tun:

let currentPosition = foo() // call to my helper function 
          // that translates NSEvent.mouseLocation() 
let downEvent = CGEvent(
    mouseEventSource: nil, 
    mouseType: .leftMouseDown, 
    mouseCursorPosition: currentPosition, 
    mouseButton: .left 
) 
let upEvent = CGEvent(
    mouseEventSource: nil, 
    mouseType: .leftMouseUp, 
    mouseCursorPosition: currentPosition, 
    mouseButton: .left 
) 
downEvent?.post(tap: CGEventTapLocation.cghidEventTap) 
upEvent?.post(tap: CGEventTapLocation.cghidEventTap) 

So weit, so gut.

Jetzt möchte ich das Scrollen mit zwei Fingern auf dem iOS-Gerät implementieren. Das Problem ist nicht die Kommunikation zwischen iOS und MacOS (übrigens, PeerTalk ist genial), es ist die Tatsache, dass ich nicht scheinen kann, ein Scroll-Ereignis auf dem Host auszulösen.

Zuerst habe ich versucht, so etwas wie dieses:

let eventSource = CGEventSource(stateID: .hidSystemState) 
let event = CGEvent(
    mouseEventSource: eventSource, 
    mouseType: .scrollWheel, 
    mouseCursorPosition: currentPosition, 
    mouseButton: .left 
) 

Leider event ist immer nil, und ich kann nicht herausfinden, warum. Die andere Methode, die ich wollte versuchen, das ist (ja, ich bin mit hartcodierte Werten, die ich von einem globalen Ereignis-Listener bekam, für Testzwecke):

NSEvent.mouseEvent(
    with: NSEventType.scrollWheel, 
    location: NSPoint(x: 671.0, y: 568.0), 
    modifierFlags: .init(rawValue: 0), 
    timestamp: 198223.19430632601, 
    windowNumber: 14389, 
    context: nil, 
    eventNumber: 0, 
    clickCount: 1, 
    pressure: 1.0 
) 

Aber meine Anwendung abstürzt, wenn das Ereignis zu erstellen:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: _NSEventMask64FromType(type) & (MouseMask|NSEventMaskMouseMoved)'

Hat jemand eine Idee hat, wie ich meine Scroll-Funktion erreichen könnte? Danke im Voraus!

Antwort

0

I löste es durch

a) unter Verwendung eines überbrück Header:

#ifndef Header_h 
#define Header_h 
void createScrollWheelEvent(); 
#endif /* Header_h */ 

b) Schreiben einer Funktion das Ereignis in plain old C zu erzeugen:

#include <stdio.h> 
#include <ApplicationServices/ApplicationServices.h> 

void createScrollWheelEvent() { 
    CGEventRef upEvent = CGEventCreateScrollWheelEvent(
     NULL, 
     kCGScrollEventUnitPixel, 
     2, 1, 1); 
    CGEventPost(kCGHIDEventTap, upEvent); 
    CFRelease(upEvent); 
} 

c) und Rufen Sie es direkt von meinem Swift-Code:

createScrollWheelEvent() 

Die Verwendung von CGEventCreateScrollWheelEvent in Swift ist wegen der variadischen Funktionen nicht möglich. Der Code muss offensichtlich optimiert werden, aber es sollte jemandem, der über diesen Beitrag stolpert, eine Idee geben, wie er ihn lösen kann.

// bearbeiten

Ich habe auch bemerkt, dass CGDisplayMoveCursorToPoint nicht "richtig". Ja, es bewegt den Cursor, aber wenn ich den Cursor auf die Symbole im Dock setze, gibt es kein Popup für den Namen der Anwendung. Daher wechselte ich zu CGEvent, um den Cursor zu bewegen.

Verwandte Themen