Xcode - 如何设置高度&使用AXUIElementSetAttributeValue的特定窗口(kCGWindowNumber)的宽度

时间:2013-04-16 16:53:13

标签: objective-c xcode cocoa

在Xcode 4.6.1中工作时,我希望得到所有窗口的列表,选择一个特定窗口(可能是windowID)并指定其大小(宽度和高度)和原点(X& Y)。

我可以获得屏幕大小,NSStringFromRect允许我在NSLog中查看结果。 NSRect是{NSPoint origin; NSSize size;}以及我的显示{{0,0},{2560,1440}}的上下文。

我使用以下内容来获取我的显示尺寸。 (感谢Guillaume关于C结构和铸造的评论):

-(void)awakeFromNib
{
    NSRect screenRect = [[NSScreen mainScreen] frame];
    CGSize myScreenSize = screenRect.size;
    NSLog(@"myScreenSize = %d x %d", (int)myScreenSize.width, (int)myScreenSize.height);

    // returns: myScreenSize = 2560 x 1440
}
@end

我想尝试设置尺寸&另一个已启动的应用程序窗口的源(不属于我的进程)。

首先,我获得所有正在运行的应用程序的列表,以及每个窗口的windowID,然后选择一个窗口来移动/调整大小。

基于其他搜索,可以使用CGSPrivate.h或Accessibility api完成。 我不知道如何使用其中任何一个来设置特定windowID / Number或PID

的大小等
#import "rsAppDelegate.h"

@implementation rsAppDelegate

-(void)awakeFromNib
{
    // get the size of the main screen
    NSRect screenRect = [[NSScreen mainScreen] frame];    
    // devrived fromGuillaume's suggestion
    CGSize myScreenSize = screenRect.size;
    CGPoint myScreenOrigin = screenRect.origin;
    NSLog(@"myScreenSize = %d x %d", (int)myScreenSize.width, (int)myScreenSize.height);
    NSLog(@"Origin = %d , %d", (int)myScreenOrigin.x, (int)myScreenOrigin.y);

    // To get a list of Application windows, the PID of the window, the window number, and the window bounds (origin, height, width)   
    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
    for (NSMutableDictionary* entry in (__bridge NSArray*)windowList)
    {
        NSArray *ownerName = [entry objectForKey:(id)kCGWindowOwnerName];
        NSInteger ownerPID = [[entry objectForKey:(id)kCGWindowOwnerPID] integerValue];
        NSInteger windowNumber = [[entry objectForKey:(id)kCGWindowNumber] integerValue];
        NSArray *ownerBounds = [entry objectForKey:(id)kCGWindowBounds];
        NSLog(@"\nApp = %@ \nAppPID = %ld \nwindowNumber = %ld \nProgramBounds = %@", ownerName, (long)ownerPID, (long)windowNumber, ownerBounds);
    }
    CFRelease(windowList);
    /*
    OUTPUT:
    myScreenSize = 2560 x 1440 | Origin = 0 , 0
    App = Xcode
    AppPID = 3260
    windowNumber = 4493
    ProgramBounds = {
        Height = 1285;
        Width = 1852;
        X = 339;
        Y = 32;
    }
    */

    // Knowing the name of the application, it's PID, window number, and bounds to a percentage of the screen:
    // Set it's origin and size

}
@end

所以现在我知道了屏幕大小,并且拥有每个应用程序中所有窗口的所有可用信息。 如何使用PID 3260,窗口编号4493指定应用程序的新原点,宽度,高度?

newPos = AXValueCreate(kAXValueCGPointType, windowOrigin);
AXUIElementSetAttributeValue(chosenWindow, kAXPositionAttribute, newPos)

newSize = AXValueCreate(kAXValueCGSizeType, windowSize);
AXUIElementSetAttributeValue(chosenWindow, kAXSizeAttribute, newSize);

如何指定selectedWindow? 我指定什么格式windowOrigin& windowSize?

以下是我发现的信息,但我不知道如何使用:

kAXValueCGPointType是CGPoint的包装器;请参阅CoreGraphics.h在AXValue.h中声明

kAXValueCGSizeType是CGSize的包装器;

这些是其他结构的AXValueType包装器。您必须使用AXValueCreate和AXValueGetValue函数在包装结构和本机结构之间进行转换。

1 个答案:

答案 0 :(得分:1)

首先,你需要找出窗户的位置。

来自 NSWindow Class Reference ...

<强>屏幕

  

返回窗口所在的屏幕。

- (NSScreen *)screen

返回值

  

大部分窗口所在的屏幕;窗户没有   屏幕外。

<强>讨论

  

当窗口部分在一个屏幕上而部分在另一个屏幕上时,   屏幕上的大部分内容都会被退回。

<强> deepestScreen

  

返回窗口所在的最深屏幕(可以在多个屏幕上分割)。

- (NSScreen *)deepestScreen

返回值

  

窗口最深的屏幕;当窗户在屏幕外时没有。

然后,如果且仅当您的窗口在一个屏幕上时,您能否确定其大小为某事物的百分比。

一般情况下,如果不将窗口限制在主屏幕或某个用户​​选择的屏幕上,您的方法就会遇到问题。

否则,您需要考虑如何处理不同的屏幕配置。

您还需要以下NSApplication委托方法

<强> applicationDidChangeScreenParameters:

  

当附加到&gt;的显示配置时,由默认通知中心发送更改计算机(以编程方式或当用户更改&gt;显示控制面板中的设置时)。

- (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification参数

  

aNotification   名为NSApplicationDidChangeScreenParametersNotification的通知。调用此通知的object方法将返回NSApplication对象本身。

NSScreen个实例使用frame方法返回NSRect,就像NSWindow一样。 从中您可以确定要设置尺寸宽度和宽度的合适高度和宽度。在创建用于设置窗口框架的NSRect时使用的高度。

获取屏幕框架并访问其高度的示例:

NSRect mainScreenFrameRect = [[NSScreen mainScreen] frame];
CGFloat screenHeight = mainScreenFrameRect.size.height;

从那里获得高度或宽度的百分比是很容易的数学。

我建议在您的applicationDidFinishLaunching或其他适当的地方使用NSWindow方法setFrame:display:animate:。 (考虑一下你可能想要的NSWindow子类。)