Re: Access main window of other Applications
Re: Access main window of other Applications
- Subject: Re: Access main window of other Applications
- From: Florian Pilz <email@hidden>
- Date: Sun, 17 Apr 2011 16:47:49 +0200
Thanks again Peter!
I have a working solution now (see below). It doesn't rely on the
Accessibility API, whereby AppleScript functions like `set size` or `ser
position` does. However, I am still not sure if I should in fact rely on the
Accessibility API as Apple explains that this API is enabled in most
applications. I don't know if every application support `set bounds`.
At the moment I am happy with my solution, in case new problems bubble up, I
will write a new question. Thanks again!
My solution:
NSDictionary* errorDict;
NSAppleEventDescriptor* returnDescriptor = NULL;
NSString *getBoundsScript = @"\
tell application \"System Events\"\n\
set appName to name of the first process whose frontmost is true\n\
end tell\n\
tell application appName\n\
set appBounds to bounds of front window\n\
end tell\n\
{bounds:appBounds}";
NSAppleScript* scriptObject = [[NSAppleScript alloc] initWithSource
:getBoundsScript];
returnDescriptor = [scriptObject executeAndReturnError: &errorDict];
NSLog(@"%@", returnDescriptor);
[scriptObject release];
NSAppleEventDescriptor *bounds = [returnDescriptor descriptorForKeyword:
pBounds];
NSLog(@"%@", [bounds descriptorAtIndex:1]);
int x1 = [[bounds descriptorAtIndex:1] int32Value];
int y1 = [[bounds descriptorAtIndex:2] int32Value];
int x2 = [[bounds descriptorAtIndex:3] int32Value];
int y2 = [[bounds descriptorAtIndex:4] int32Value];
NSDictionary* errorDict2;
NSAppleEventDescriptor* returnDescriptor2 = NULL;
NSString *content = [NSString stringWithFormat:@"\
tell application \"System Events\"\n\
set appName to name of the first process whose frontmost is true\n\
end tell\n\
\n\
tell application appName\n\
set bounds of front window to {%i, %i, %i, %i}\n\
end tell", x1 - 20, y1, x2 - 20, y2];
NSAppleScript* scriptObject2 = [[NSAppleScript alloc] initWithSource
:content];
returnDescriptor2 = [scriptObject2 executeAndReturnError: &errorDict2];
NSLog(@"%@", returnDescriptor2);
[scriptObject2 release];
Best wishes
Florian
PS: The solution using the Accessibility API can be found here:
http://stackoverflow.com/questions/1730859/controlling-osx-windows
2011/4/11 Peter Lübke <email@hidden>
>
> Am 11.04.2011 um 16:20 schrieb Florian Pilz:
>
> @Eric: I don't search for a solution in another scripting language,
> but thanks. :)
>
> @Peter: I want to manipulate the position and size of the window,
> nothing else. Thus I will most likely use the `frame`,
> `setFrame:display` and `setFrameOrigin`.
>
>
> I don't see any way to manipulate position or size of a window that is not
> owned by your application with the Quartz Window Services Api or NSScreen.
> The way to do this is via Interapplication Communication, as there are
> AppleScript / AppleEvents and Accessibility.
>
> @Bill: You are right, I don't intend to write an assistive
> application. Thus I would misuse the NSAccessibility protocol to reach
> my goal (of finding the main window). I just wanted to list all
> possibilities. Thanks for the advice concerning the Mac App Store,
> though.
>
> @all: As Bill pointed out (and due to the miscomfort for the user),
> using the NSAccessibility protocol is inappropriate. During my
> research how to access the current screen size etc. I found out, that
> historically one would use Quartz Display Services -- nowadays
> NSScreen should be preferred. Therefore I came to the conclusion that
> using the Quartz Window Services is in fact a natural way to perform
> my task. I even found a working solution
> (
> http://stackoverflow.com/questions/1754160/how-do-i-get-the-details-of-an-application-using-objective-c
> ).
>
> This leaves my with 3 short questions:
> - Is there another solution I haven't listed, preferably in
> Objective-C and shorter than the solution using the Quartz Window
> Services?
> - Are there reasons to avoid Quartz Window Services, e.g. do they
> require some switch as well?
>
>
> See above. Quartz WindowID even doesn't match the application specific
> window id you get with AppleScript, so none of the informations you get
> from Quartz Window Services will be of any use in AppleScript.
>
> - How well integrates AppleScript into Objective-C?
>
>
> I think I don't get this question right. It's just code that is executed.
> It works. Objective-C is calling C functions behind the scenes... I can't
> see any reason not to use a language your computer understands.
>
> I think using
> AppleScript would make the solution shorter, but I probably want to
> extend the functionality of resizing / moving the window in the
> future.
>
>
> You can set any settable property of an application's window. You can find
> out about which properties are settable by dragging the application's icon
> on the ScriptEditor application; ScriptEditor will then show the
> application's scripting terminology.
>
> Thus the question: Can I return the main window found by
> AppleScript to my Objective-C code?
>
>
> You store an object specifier ( the window you received from sending an
> AppleScript command or an AppleEvent ) in an
> NSAppleEventDescriptor. NSAppleEventDescriptor is the Cocoa wrapper class
> for AppleEvents. You can send AppleEvents or AppleScript commands to this
> object specifier.
>
> Is it fast enough?
>
>
> AppleScript is based on AppleEvents, it's very simple to use and you can
> easily test your commands in the Script Editor application, but it's
> considerably slower than directly sending AppleEvents.
>
>
>
> When should one
> try to solve the task at hand with AppleScript and when not?
>
>
> If it is an Interapplication Communication task, use AppleScript /
> AppleEvents.
>
> Consider the following:
>
> *(**
> *-- Version 1: *
> * First get the front window, so you can store it for later use, i.e. the
> window is no more front when you want to access it.*
> * Also get the window's bounds to restore them later on.*
> **)*
> *--** Get window bounds:*
> *tell application "**<someApp"*
> * set *theFrontWindow* to window *1
> * set *wBounds* to bounds of *theFrontWindow
> *end tell*
> **
> *--** Set window bounds:*
> *tell application "**<someApp"*
> * set bounds of *theFrontWindow* to {*20*, *20*, *420*, *420*}*
> *end tell*
> *
> *
> *(**
> *-- Version 2: *
> * You just want to set the window's bounds but don't need to keep track of
> the window object.*
> **)*
> **
> *--** Set window bounds:*
> *tell application "*Mail*"*
> * set bounds of window *1* to {*20*, *20*, *420*, *420*}*
> *end tell*
>
> If you want to do this with AppleEvents rather than NSAppleScript for
> performance reasons, let me know. I could send you code snippets if this
> helps.
>
> Cheers,
>
> Peter
>
>
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden