8

iPhoneにタッチイベントを挿入したい。ネットワークソケット経由でタッチイベントの座標を取得します。GSSendEvent は良い選択のようです。ただし、入力の 1 つとして GSEventRecord が必要です。

GSEventRecord の準備方法を知っている人はいますか? いくつかの例に基づいて準備しましたが、GSSendEvent 呼び出し後にアプリがクラッシュします。

どんな助けにも感謝します。

-(void) handleMouseEventAtPoint:(CGPoint) point
{
static mach_port_t port_;

// structure of touch GSEvent
struct GSTouchEvent {
    GSEventRecord record;
    GSHandInfo    handInfo;
} ;

struct GSTouchEvent *touchEvent = (struct GSTouchEvent *) malloc(sizeof(struct GSTouchEvent));

bzero(touchEvent, sizeof(touchEvent));

// set up GSEvent
touchEvent->record.type = kGSEventHand;
touchEvent->record.windowLocation = point;
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->handInfo.type = getHandInfoType(0, 1);
touchEvent->handInfo.pathInfosCount = 1;
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
touchEvent->handInfo.pathInfos[0].pathIndex     = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity  = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = 1 ? 0x03 : 0x00;
touchEvent->handInfo.pathInfos[0].pathLocation  = point;

port_ = GSGetPurpleSystemEventPort();

GSSendEvent((GSEventRecord*)touchEvent ,port_);


}
static GSHandInfoType getHandInfoType(int touch_before, int touch_now){
if (!touch_before) {
    return (GSHandInfoType) kGSHandInfoType2TouchDown;
}
if (touch_now) {
    return (GSHandInfoType) kGSHandInfoType2TouchChange;
}
return (GSHandInfoType) kGSHandInfoType2TouchFinal;
}
4

2 に答える 2

6

iOS 6 でのみテスト済み

あなたは実際に正しい軌道に乗っています。問題は、これらの変数にどの値を割り当てる必要があるかを把握する必要があることです。

まず、GraphicsServices.h をインポートする必要があります。次に、 IOS 5 以降で最前面のアプリケーションの紫色のポートを見つける方法から取得できるポートを使用して、次のコードを試すことができます。.

私は iOS の専門家ではなく、Apple はドキュメントを提供していないため、ここで何が起こっているのかを説明することはできません。(たまたま私にとってはうまくいきます。)

とにかく、xcode デバッグ モードを使用して遊んで、内部で何が起こっているかを確認できます。

struct GSTouchEvent * touchEvent = (struct GSTouchEvent*) &gsTouchEvent;
bzero(touchEvent, sizeof(touchEvent));
touchEvent->record.type = kGSEventHand;
touchEvent->record.subtype = kGSEventSubTypeUnknown;
touchEvent->record.location = point;
touchEvent->record.windowLocation = point;
touchEvent->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
touchEvent->record.timestamp = GSCurrentEventTimestamp();
touchEvent->record.window = winRef;
touchEvent->record.senderPID = 919;
bzero(&touchEvent->handInfo, sizeof(GSHandInfo));
bzero(&touchEvent->handInfo.pathInfos[0], sizeof(GSPathInfo));
GSHandInfo touchEventHandInfo;
touchEventHandInfo._0x5C = 0;
touchEventHandInfo.deltaX = 0;
touchEventHandInfo.deltaY = 0;
touchEventHandInfo.height = 0;
touchEventHandInfo.width = 0;
touchEvent->handInfo = touchEventHandInfo;
touchEvent->handInfo.type = handInfoType;
touchEvent->handInfo.deltaX = 1;
touchEvent->handInfo.deltaY = 1;
touchEvent->handInfo.pathInfosCount = 0;
touchEvent->handInfo.pathInfos[0].pathIndex = 1;
touchEvent->handInfo.pathInfos[0].pathIdentity = 2;
touchEvent->handInfo.pathInfos[0].pathProximity = (handInfoType == kGSHandInfoTypeTouchDown || handInfoType == kGSHandInfoTypeTouchDragged || handInfoType == kGSHandInfoTypeTouchMoved) ? 0x03: 0x00;
touchEvent->handInfo.x52 = 1;
touchEvent->handInfo.pathInfos[0].pathLocation = point;
touchEvent->handInfo.pathInfos[0].pathWindow = winRef;
GSEventRecord* record = (GSEventRecord*) touchEvent;
record->timestamp = GSCurrentEventTimestamp();
GSSendEvent(record, port);

このコードを使用するには、複数回呼び出す必要があります。1回のタップには、タッチダウン、タッチドラッグ、タッチアップがあります。

また、タッチがアップしている場合、pathProximity は 0 であることに注意してください。

私が覚えている限りでは、winRef は問題ではありません。

お役に立てれば。

編集:Bugivoreのコメントから、問題は次のとおりです。

malloc を介して touchEvent を割り当てる方法が間違っていました。EntryLevelDev が示したように実行する必要があります - 「static uint8_t handJob[sizeof(GSEventRecord) + sizeof(GSHandInfo) + sizeof(GSPathInfo)];」

于 2013-04-24T02:08:50.353 に答える
3

EntryLevelDev からの回答は正しいですが、一部の値はそれほど重要ではありません。私は別の場所から以下のコードを取得し、いくつかの試行錯誤を行いました。これが私のコードです(最新のios6まで動作しました)。

現在、IOS7 でこれに取り組んでいる人はいますか? 私はそれを働かせることができませんでした。ここで私の投稿を参照してください: IOS7 で廃止された GraphicsServices の GSCopyPurpleNamedPort(appId) では、代替アプローチは何ですか?

static int prev_click = 0;

if (!click && !prev_click)
{
    //which should never enter
    NSLog(@"***error, postHandEvent cancel");
    return;
}

CGPoint location = CGPointMake(x, y);

struct GSTouchEvent {
    GSEventRecord record;
    GSHandInfo    handInfo;
} * event = (struct GSTouchEvent*) &touchEvent;
bzero(touchEvent, sizeof(touchEvent));

event->record.type = kGSEventHand;
event->record.windowLocation = location;
event->record.timestamp = GSCurrentEventTimestamp();
//NSLog(@"Timestamp GSCurrentEventTimestamp: %llu",GSCurrentEventTimestamp());
event->record.infoSize = sizeof(GSHandInfo) + sizeof(GSPathInfo);
event->handInfo.type = getHandInfoType(prev_click, click);

//must have the following line
event->handInfo.x52 = 1;

//below line is for ios4
//event->handInfo.pathInfosCount = 1;


bzero(&event->handInfo.pathInfos[0], sizeof(GSPathInfo));
event->handInfo.pathInfos[0].pathIndex     = 2;
//following 2 lines, they are by default
event->handInfo.pathInfos[0].pathMajorRadius = 1.0;
event->handInfo.pathInfos[0].pathPressure = 1.0;

//event->handInfo.pathInfos[0].pathIdentity  = 2;
event->handInfo.pathInfos[0].pathProximity = click ? 0x03 : 0x00;
//event->handInfo.pathInfos[0].pathProximity = action;
event->handInfo.pathInfos[0].pathLocation  = location;

// send GSEvent 
GSEventRecord *event1 = (GSEventRecord*) event;
sendGSEvent(event1);
于 2013-07-25T10:46:43.567 に答える