Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
411 views
in Technique[技术] by (71.8m points)

objective c - Controlling OSX windows

I'm trying to control windows of a foreign OSX applications from my application. I'd like to 1. move the windows on the screen 2. resize the windows on the screen 3. change the currently active window of the application 4. get the currently active window.

(And I'd like to do this either through ObjC/C/C++ apis).

What are the API calls that I should be looking for, considering that I have the CGWindowIDs of the windows that I want to control? That is, I'd expect to find functions with signatures of something like: MoveWindow(CGWindowID winId, int x, int y), ResizeWindow(CGWindowID winId, int width, int height), Activatewindow(CGWindowID winId), CGWindowID GetCurrentlyActivatedWindow().

For 3, I'm already using SetFrontProcess to pull a process to be up front, but this doesn't let me select the specific window of a process if it has multiple.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One way of doing this is indeed to use the accessibility APIs.

An application I'm developing is doing just this to get the front window, the document path of the front window and many other attributes.

The way I'm doing this is through AppleScript. It can be clumsy at times, but it seems to be fairly reliable. I use AppScript to send AppleScript from within my Cocoa app. It's thread safe and more stable than the alternatives - either Scripting Bridge or NSAppleScript.

The difficult bit will be identifying a window using it's window ID in AppleScript - AppleScript doesn't seem to have a window ID property that matches up to CGWindowID. However, you can get any window you want using AppleScript.

  1. Move frontmost window to 100, 100

    tell application "System Events"
     set theprocess to the first process whose frontmost is true
     set thewindow to the value of attribute "AXFocusedWindow" of theprocess
        set position of thewindow to {100, 100}
    end tell
    
  2. Resize frontmost window to 200, 300

    tell application "System Events"
      set theprocess to the first process whose frontmost is true
      set thewindow to the value of attribute "AXFocusedWindow" of theprocess
         set size of thewindow to {200, 300}
    end tell
    
  3. Change current window of the frontmost application

    tell application "System Events"
      set theprocess to the first process whose frontmost is true
      set thewindow to the value of attribute "AXFocusedWindow" of theprocess
         set size of thewindow to {200, 300}
         windows of theprocess
         -- Code to get ID of window you want to activate
         tell window 2 of theprocess -- assuming it's window 2
               perform action "AXRaise"
         end tell
    end tell
    
  4. Window that's active

    tell application "System Events"
     set theprocess to the first process whose frontmost is true
     set thewindow to the value of attribute "AXFocusedWindow" of theprocess
    end tell
    

There's an application available for AppScript called ASTranslate that will turn this AppleScript into the Objective C code that calls the relevant commands in AppScript.

For more information on how to get the size and bounds of windows (these are read only as far as I'm aware) see the Son of Grab sample application.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...