Cocoa プロジェクトでいくつかの Apple Events を使用して、ターミナル アプリケーションにアクセスしようとしています。埋め込みの AppleScript やコンパイル済みのスクリプトを使いたくなかったので、NSAppleEventDescriptor
.
コマンドを使用して新しいウィンドウを作成することにdo script
成功し、戻り値からウィンドウを取得することに成功しました。今やりたいことは、そのウィンドウのプロパティを取得することだけです。
そのようなプロパティを取得する方法がわかったので、グーグルを始めました。残念ながら、Apple Events の使用方法の良い例はあまりなく、探していたものを見つけることができませんでした。
それで、私はより深く掘り下げ始めました。get
そして、私が最初にしたことは、ターミナル.sdef
ファイルでコマンドのコードを探すことでした。見つからなかったので、grep
自分の/System/
ディレクトリで を実行したところ、 が見つかりまし/System/Library/Frameworks/AppleScriptKit.framework/Versions/A/Resources/AppleScriptKit.sdef
た。どうやら AppleScript 構文の核心を見つけたようです。そのファイルには確かにgetd
4 文字のコードが含まれていました。
getd
これで、Core Suiteのイベントを使用する必要があることがわかりました。ただし、その 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;
そして今、私は境界プロパティを取得できませんでした
// _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);
説明したように、上記のコードは最後のブロックまで機能します。
助けてくれてありがとう。