How can I move/resize windows programmatically from another application?

前端 未结 3 1758
滥情空心
滥情空心 2020-12-19 15:15

I know, that I can use Apple Event Object Model for moving and resizing windows of Cocoa applications. But what can I use for Carbon applications?

相关标签:
3条回答
  • 2020-12-19 15:36

    You can also use the Accessibility API. This is how I think Optimal Layout is doing it.

    First you have make sure your app has permission to use it.

    BOOL checkForAccessibility()
    {
        NSDictionary *options = @{(__bridge id) kAXTrustedCheckOptionPrompt : @YES};
        return AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef) options);
    }
    

    Next, use the NSWorkspace::RunningApplications to get the PID of the app whose window you want to manipulate.

    NSArray<NSRunningApplication *> *runningApps =[[NSWorkspace sharedWorkspace] runningApplications];
    for( NSRunningApplication *app in runningApps )
    {
        if( [app bundleIdentifier] != nil && [[app bundleIdentifier] compare:@"IdentifierOfAppYouWantToFindHere"] == 0 )
        {
            PID = [app processIdentifier];
        }
    }
    

    Then use the PID to get access to the main window reference using the Accessibility API.

    AXUIElementRef app = AXUIElementCreateApplication( PID );
    AXUIElementRef win;
    AXError error = AXUIElementCopyAttributeValue( app, kAXMainWindowAttribute, ( CFTypeRef* )&win );
    while( error != kAXErrorSuccess )   // wait for it... wait for it.... YaY found me a window! waiting while program loads.
        error = AXUIElementCopyAttributeValue( app, kAXMainWindowAttribute, ( CFTypeRef* )&win );
    

    Now you can set the size and position using something like this:

    CGSize windowSize;
    CGPoint windowPosition;
    windowSize.width = width;
    windowSize.height = height;
    windowPosition.x = x;
    windowPosition.y = y;
    AXValueRef temp = AXValueCreate( kAXValueCGSizeType, &windowSize );
    AXUIElementSetAttributeValue( win, kAXSizeAttribute, temp );
    temp = AXValueCreate( kAXValueCGPointType, &windowPosition );
    AXUIElementSetAttributeValue( win, kAXPositionAttribute, temp );
    CFRelease( temp );
    CFRelease( win );
    
    0 讨论(0)
  • 2020-12-19 15:52

    Peter was right, you can access to bounds of any window using the following AppleScript:

    tell application "System Events"
        set allProcesses to application processes
        repeat with i from 1 to count allProcesses
            tell process i
                repeat with x from 1 to (count windows)
                    position of window x
                    size of window x
                end repeat
            end tell
        end repeat
    end tell
    
    0 讨论(0)
  • 2020-12-19 15:57

    Same thing. You can use Apple Events on any scriptable application, and Apple Events and scriptability are a lot older than Carbon.

    0 讨论(0)
提交回复
热议问题