2012-03-18 8 views
1

私は、CocoaプロジェクトでいくつかのAppleイベントを使用して、ターミナルアプリケーションにアクセスしようとしています。埋め込みAppleScriptやコンパイル済みスクリプトを使用したくないので、NSAppleEventDescriptorを調べ始めました。NSAppleEventDescriptorのAppleScriptプロパティを取得する

do scriptコマンドを使用して新しいウィンドウを作成するのに成功し、戻り値からウィンドウを取得することに成功しました。私が今したいことは、そのウィンドウのプロパティを取得することだけです。

私はこのようなプロパティを取得する方法を今考えていたので、私はグーグルを始めました。残念なことに、Apple Eventsの使い方の良い例はあまりなく、私が探していたものを見つけることができませんでした。

私は深く掘り始めました。そして私がやった最初のことは、端末.sdefファイルのgetコマンドのコードを探していた。私はそれを見つけることができなかったので、私は私の/System/ディレクトリに行ったと私は/System/Library/Frameworks/AppleScriptKit.framework/Versions/A/Resources/AppleScriptKit.sdefを発見した。私は明らかにAppleScriptの構文の核心を見つけました。そのファイルは実際にはgetdの4文字コードでした。

これで、Core Suiteのgetdイベントを使用する必要があることが分かりました。しかし、そのget-commandの引数はobjectSpecifierでした。私はkAEGetDataを使用した例について、高低を検索しました。しかし、私は何かを学ぶことができるコードを見つけることに失敗しました。

私はここにお尋ねします:このようなobjectSpecifier記述子を作成するにはどうすればよいですか?

これは私がすでに持っているものです:

NSAppleEventDescriptor *createEvent; 
NSAppleEventDescriptor *scriptParam; 
AppleEvent aeReply; 
OSErr err; 

/* Make the do script event */ 
createEvent = [NSAppleEventDescriptor 
       appleEventWithEventClass:kAECoreSuite 
       eventID:kAEDoScript 
       targetDescriptor:_applicationDescriptor 
       returnID:kAutoGenerateReturnID 
       transactionID:kAnyTransactionID]; 
if(createEvent == nil) { 
    NSLog(@"%s Failed to create a do script event", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

/* Make script parameter */ 
scriptParam = [NSAppleEventDescriptor descriptorWithString:@"echo Hello World"]; 
if(scriptParam == nil) { 
    NSLog(@"%s Failed to create the script parameter", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

/* Set parameter */ 
[createEvent setParamDescriptor:scriptParam forKeyword:keyDirectObject]; 

/* Send event */ 
err = AESendMessage([createEvent aeDesc], &aeReply, 
        kAEWaitReply | kAENeverInteract, kAEDefaultTimeout); 
if(err != noErr) { 
    NSLog(@"%s Failed to send the create command", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

/* Retrieve information */ 
{ 
    /* SEE BELOW TO SEE HOW I GET THE WINDOW DESCRIPTOR */ 
} 

タブディスクリプタを作成し、取得する

コードを今、私はそのタブ

のウィンドウを取得して試してみて、成功
// NSAppleEventDescriptor *ansr is set to the result of the code above 

NSAppleEventDescriptor *mainObj; 
NSAppleEventDescriptor *desiredClass; 
NSAppleEventDescriptor *window; 

mainObj = [ansr paramDescriptorForKeyword:keyDirectObject]; 
if([mainObj descriptorType] != typeObjectSpecifier) { 
    NSLog(@"%s Main object was not an object specifier", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

desiredClass = [mainObj paramDescriptorForKeyword:keyAEDesiredClass]; 
if([desiredClass typeCodeValue] != kAETerminalTab) { 
    NSLog(@"%s Main object's desired class was not a Terminal tab", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

window = [mainObj paramDescriptorForKeyword:keyAEContainer]; 
if(window == nil) { 
    NSLog(@"%s Couldn't get container of the tab", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

desiredClass = [window paramDescriptorForKeyword:keyAEDesiredClass]; 
if([desiredClass typeCodeValue] != cWindow) { 
    NSLog(@"%s The container of the tab was not a window", 
      __PRETTY_FUNCTION__); 
    return nil; 
} 

return window; 

これで私はgettiに失敗しましたNG、

// _windowDescriptor is the result of the code above 

NSAppleEventDescriptor *getEvent; 
NSAppleEventDescriptor *prop; 
AppleEvent aeReply; 
NSAppleEventDescriptor *reply; 
FourCharCode propName; 
OSErr err; 

propName = keyAEBounds; 

/* Create get event */ 
getEvent = [NSAppleEventDescriptor 
      appleEventWithEventClass:kAECoreSuite 
      eventID:kAEGetData 
      targetDescriptor:_windowDescriptor 
      returnID:kAutoGenerateReturnID 
      transactionID:kAnyTransactionID]; 
if(getEvent == nil) { 
    NSLog(@"%s Failed to create a get event", 
      __PRETTY_FUNCTION__); 
    return NSZeroRect; 
} 

/* Get property */ 
prop = [NSAppleEventDescriptor 
     descriptorWithDescriptorType:typeProperty 
     bytes:&propName length:sizeof(propName)]; 
if(prop == nil) { 
    NSLog(@"%s Failed to create the bounds property", 
      __PRETTY_FUNCTION__); 
    return; 
} 

/* Set parameter */ 
[getEvent setParamDescriptor:prop forKeyword:keyDirectObject]; 

/* Exectue */ 
err = AESendMessage([getEvent aeDesc], &aeReply, 
        kAEWaitReply | kAENeverInteract, kAEDefaultTimeout); 
if(err != noErr) { 
    NSLog(@"%s Failed to send the get message", 
      __PRETTY_FUNCTION__); 
    return; 
} 

reply = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&aeReply]; 
[reply autorelease]; 

NSLog(@"Bounds: %@", reply); 

boundsプロパティ、のは言わせとしては、ちょうど最後のブロックまで、上記のコードの動作を説明しました。
ご協力いただきありがとうございます。

答えて

2

Rob Kenigerのおかげで、私は欲しかったことに成功しました。

は、どうやら私はtypeObjectSpecifierにそれを、レコード記述子を作成し、私の希望のプロパティを設定して、その後、強制しなければなりませんでした。

また、Appleのイベントの受信者としてウィンドウ記述子を設定するのは間違っていました。アプリケーション自体には常に対処し、直接オブジェクトのfromkeyAEContainer)プロパティを目的のウィンドウに設定する必要があります。ここで

NSLog -statementsの少しで作業コード、次のとおりです。

- (NSRect)bounds { 

    // ! ! ! 
    // _windowDescriptor is an instance variable which points to a valid 
    // window NSAppleEventDescriptor 
    // ! ! ! 

    NSAppleEventDescriptor *getEvent; 
    NSAppleEventDescriptor *objSpec; 
    NSAppleEventDescriptor *propEnum, *propType, *propSeld; 
    AppleEvent aeReply; 
    NSAppleEventDescriptor *reply; 
    FourCharCode propName; 
    OSErr err; 

    propName = keyAEBounds; 

    /* Create get event */ 
    getEvent = [NSAppleEventDescriptor 
       appleEventWithEventClass:kAECoreSuite 
       eventID:kAEGetData 
       targetDescriptor:[[FTMTerminalApp sharedApp] AEDescriptor] 
       returnID:kAutoGenerateReturnID 
       transactionID:kAnyTransactionID]; 
    if(getEvent == nil) { 
     NSLog(@"%s Failed to create a get event", 
       __PRETTY_FUNCTION__); 
     return NSZeroRect; 
    } 

    /* Get property */ 
    /* create object specifier main ojcect */ 
    objSpec = [[[NSAppleEventDescriptor alloc] initRecordDescriptor] 
       autorelease]; 
    if(objSpec == nil) { 
     NSLog(@"%s Failed to create the object specifier", 
       __PRETTY_FUNCTION__); 
     return NSZeroRect; 
    } 
    NSLog(@"%s Created object specifier %@", 
      __PRETTY_FUNCTION__, objSpec); 

    /* create property enum, we want a property */ 
    propEnum = [NSAppleEventDescriptor 
       descriptorWithEnumCode:formPropertyID]; 
    if(propEnum == nil) { 
     NSLog(@"%s Failed to create the property enum", 
       __PRETTY_FUNCTION__); 
     return NSZeroRect; 
    } 
    NSLog(@"%s Created property enum %@", 
      __PRETTY_FUNCTION__, propEnum); 
    [objSpec setDescriptor:propEnum forKeyword:keyAEKeyForm]; 

    /* create prop type */ 
    propType = [NSAppleEventDescriptor 
       descriptorWithTypeCode:typeProperty]; 
    if(propType == nil) { 
     NSLog(@"%s Failed to create the property type", 
       __PRETTY_FUNCTION__); 
     return NSZeroRect; 
    } 
    NSLog(@"%s Created property type %@", 
      __PRETTY_FUNCTION__, propType); 
    [objSpec setDescriptor:propType forKeyword:keyAEDesiredClass]; 

    /* create property key data */ 
    propSeld = [NSAppleEventDescriptor 
       descriptorWithTypeCode:keyAEBounds]; 
    if(propSeld == nil) { 
     NSLog(@"%s Failed to create the bounds property type", 
       __PRETTY_FUNCTION__); 
     return NSZeroRect; 
    } 
    NSLog(@"%s Created property key data %@", 
      __PRETTY_FUNCTION__, propSeld); 
    [objSpec setDescriptor:propSeld forKeyword:keyAEKeyData]; 

    /* Set destination */ 
    NSLog(@"%s Setting from key %@", 
      __PRETTY_FUNCTION__, _windowDescriptor); 
    [objSpec setDescriptor:_windowDescriptor forKeyword:keyAEContainer]; 

    /* Send message */ 
    objSpec = [objSpec coerceToDescriptorType:typeObjectSpecifier]; 
    NSLog(@"Coerced: %@", objSpec); 
    [getEvent setParamDescriptor:objSpec forKeyword:keyDirectObject]; 
    err = AESendMessage([getEvent aeDesc], &aeReply, 
         kAEWaitReply | kAENeverInteract, kAEDefaultTimeout); 
    if(err != noErr) { 
     NSLog(@"%s Failed to send the message (event = %@)", 
       __PRETTY_FUNCTION__, getEvent); 
     return NSZeroRect; 
    } 

    reply = [[NSAppleEventDescriptor alloc] initWithAEDescNoCopy:&aeReply]; 
    NSLog(@"BOUNDS = %@", reply); 
    [reply autorelease]; 

    return NSZeroRect; 
} 

私はこれが誰かを助けることを願っています。

1

アップルイベントは、使用するのが複雑です。畳み込まれた一般的に厄介なAPIを使って時間を費やしたいのでない限り、Mike Ashの優れたAEVTBuilderクラスを使用することで、多くの時間と心配を省くことをおすすめします。

すべての厄介なCarbon Apple Eventコードのための素晴らしいココアラッパーです。

+0

実際、Apple Event APIのコアを使用したいと思います。 – v1Axvw

+0

それは素晴らしいです、私は少し助けることができてうれしいです。 –

関連する問題