我正在尝试使用Accessibility API来更改其他应用程序窗口的位置。我希望做的是从所有应用程序中获取屏幕上的所有窗口,然后将它们全部移动给定的偏移量(比如说5或10)或任何值)。我很难做到这一点,因为这对我来说是Objective-C编程的第一天。
这是我现在正在做的事情。首先,我使用找到窗口及其PID的列表CGWindowListCopyWindowInfo
。然后,对每个窗口我用AXUIElementCreateApplication
得到的AXUIElementRef
窗口。之后,我应该将AXUIElementCopyAttributeValue
其与属性一起使用(该属性kAXPositionAttribute
未能获得正确的位置,始终为零)。最后,我应该将所需的偏移量添加到位置,并AXUIElementSetAttributeValue
与属性kAXPositionAttribute
和新的位置点一起使用(即使我将绝对值设置为0,0,也会出现运行时错误)。
有人可以帮我做上面介绍的内容,因为我尝试了很多事情却没有运气。另外,它不必完全像我决定在上面实现它一样。如果有更好的方法可以做到这一点,那么我很乐意对其进行更改。
更新:根据注释中的要求,以下是其中一种尝试的代码段:
// Get all the windows
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSArray* arr = CFBridgingRelease(windowList);
// Loop through the windows
for (NSMutableDictionary* entry in arr)
{
// Get window PID
pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
// Get AXUIElement using PID
AXUIElementRef elementRef = AXUIElementCreateApplication(pid);
CFTypeRef position;
CGPoint point;
// Get the position attribute of the window (maybe something is wrong?)
AXUIElementCopyAttributeValue(elementRef, kAXPositionAttribute, (CFTypeRef *)&position);
AXValueGetValue(position, kAXValueCGPointType, &point);
// Debugging (always zeros?)
NSLog(@"point=%@", point);
// Create a point
NSPoint newPoint;
newPoint.x = 0;
newPoint.y = 0;
position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&newPoint));
// Set the position attribute of the window (runtime error over here)
AXUIElementSetAttributeValue(elementRef, kAXPositionAttribute, (CFTypeRef *)&position);
}
根据您的示例代码(稍作修改,因为您发布的内容将无法编译,并且崩溃后不会被修改),我做了一些实验。
以下是一些警告:
CGWindowListCopyWindowInfo
当询问您的调用方式时,它将返回“屏幕上的所有窗口”,但不能保证这些窗口是“用户窗口”或具有辅助功能的窗口。大多数菜单栏项目都有一个“在屏幕上”的根窗口,并且其中大多数是不可访问的(当您尝试遍历检索到的PID的可访问性树时会显示该窗口)。我在此处包括对您的代码的修改(此修改将在不崩溃的情况下运行),它将从您通过PID检索的应用程序中获取相关的窗口信息,然后移动窗口。我有一个sleep语句,因此我可以停止执行,因为我只是在测试运动的效果:
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <ApplicationServices/ApplicationServices.h>
int main(int argc, char *argv[]) {
@autoreleasepool {
// Get all the windows
CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
NSArray* arr = CFBridgingRelease(windowList);
// Loop through the windows
for (NSMutableDictionary* entry in arr)
{
// Get window PID
pid_t pid = [[entry objectForKey:(id)kCGWindowOwnerPID] intValue];
// Get AXUIElement using PID
AXUIElementRef appRef = AXUIElementCreateApplication(pid);
NSLog(@"Ref = %@",appRef);
// Get the windows
CFArrayRef windowList;
AXUIElementCopyAttributeValue(appRef, kAXWindowsAttribute, (CFTypeRef *)&windowList);
NSLog(@"WindowList = %@", windowList);
if ((!windowList) || CFArrayGetCount(windowList)<1)
continue;
// get just the first window for now
AXUIElementRef windowRef = (AXUIElementRef) CFArrayGetValueAtIndex( windowList, 0);
CFTypeRef role;
AXUIElementCopyAttributeValue(windowRef, kAXRoleAttribute, (CFTypeRef *)&role);
CFTypeRef position;
CGPoint point;
// Get the position attribute of the window (maybe something is wrong?)
AXUIElementCopyAttributeValue(windowRef, kAXPositionAttribute, (CFTypeRef *)&position);
AXValueGetValue(position, kAXValueCGPointType, &point);
// Debugging (always zeros?)
NSLog(@"point=%f,%f", point.x,point.y);
// Create a point
CGPoint newPoint;
newPoint.x = 0;
newPoint.y = 0;
NSLog(@"Create");
position = (CFTypeRef)(AXValueCreate(kAXValueCGPointType, (const void *)&newPoint));
// Set the position attribute of the window (runtime error over here)
NSLog(@"SetAttribute");
AXUIElementSetAttributeValue(windowRef, kAXPositionAttribute, position);
sleep(5);
}
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句