在 Objective-C 中自动点击 iTunes 鼠标

发布于 2024-11-17 08:08:06 字数 4142 浏览 3 评论 0原文

我正在尝试从 Objective-C 自动化在 iTunes 中单击鼠标左键。我正在做以下事情。

  1. 首先我正在收听 iTunes 事件

    [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                     选择器:@selector(allDistributedNotifications:)
                                                     姓名:无
                                                     对象:无];
    
  2. 当调用 allDistributedNotifications 时,我执行以下操作:

    - (void) allDistributedNotifications:(NSNotification *)note {
        NSString *object = [注释对象];
        NSString *name = [注释名称];
        NSDictionary *userInfo = [注意 userInfo];
        NSLog(@"对象:%@ 名称:%@ 用户信息:%@",对象,名称,用户信息);
    
        if([object isEqualToString:@"com.apple.iTunes.dialog"]&[userInfo objectForKey:@"显示对话框"] == 0){
            NSLog(@"*** 结束 iTunes 对话");
        }
    
        if([name isEqualToString:@"com.apple.iTunes.sourceSaved"]){
            NSLog(@"*** iTunes 已保存到文件");
            当前URL索引+=1;
            [self loadWithData:[itmsURLs objectAtIndex:currentURLIndex] fromBot:YES];
        }
    }
    
  3. LoadWithData 看起来像这样

    -(void) loadWithData:(NSURL*) url fromBot:(BOOL)aBot
    {
        BOOL 成功;
    
        成功= [[NSWorkspace共享工作空间] openURLs:[NSArray arrayWithObject:url]
                  withAppBundleIdentifier:@“com.apple.itunes”
                  选项:NSWorkspaceLaunchDefault
                  附加事件参数描述符:nil
                  启动标识符:nil];
        如果(成功){
            [numAppsDownloaded setStringValue:[NSString stringWithFormat: @"%lu",currentURLIndex+1]];
        }
        if(成功 && aBot){
            [self PerformSelector:@selector(clickDownload) withObject:nil afterDelay:0.5];
        }
     }
    
  4. clickdownload 又看起来像这样

    -(void) clickDownload
    {
        NSPoint 鼠标定位;
    
        mouseLoc = [NSEvent mouseLocation]; //获取当前鼠标位置
        CGPoint点 = CGPointMake(mouseLoc.x, mouseLoc.y);
    
        CGEventRef theEvent;
        CGEventType 类型;
    
        CGMouseButton 按钮 = kCGMouseButtonLeft;
    
        类型 = kCGEventLeftMouseDown; // kCGEventLeftMouseDown = NX_LMOUSEDOWN,
        theEvent = CGEventCreateMouseEvent(NULL,类型,点,按钮);
    
        NSEvent* downEvent = [NSEvent eventWithCGEvent:theEvent];
        [自我转发事件:downEvent];
    
        [NSThread sleepForTimeInterval:0.2];
    
        类型 = kCGEventLeftMouseUp;
        theEvent = CGEventCreateMouseEvent(NULL,类型,点,按钮);
        NSEvent* upEvent = [NSEvent eventWithCGEvent:theEvent];
        [自我转发事件:upEvent];
    }
    

    5.最后,forwardEvent 看起来像这样

    - (void)forwardEvent: (NSEvent *)事件
    {
        NSLog(@"事件:%@",事件);
    
        pid_t PID;
        NSInteger WID;
    
        // 获取 iTunes 窗口 ID
    
        NSArray* windows = (NSArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
    
        NSEnumerator* windowEnumerator = [windows objectEnumerator];
    
        while( (窗口 = [windowEnumerator nextObject] ) )
        {
            if([[(NSDictionary*) 窗口 objectForKey:@"kCGWindowName"] isEqualToString:@"iTunes"])
                WID = (NSInteger)[(NSDictionary*) 窗口 objectForKey:@"kCGWindowNumber"];
        }
    
        进程序列号 psn;
        CGEventRef CGEvent;
        NSEvent *自定义事件;
    
        NSPoint mouseLoc = [NSEvent mouseLocation]; //获取当前鼠标位置
        NSPoint clickpoint = CGPointMake(mouseLoc.x, mouseLoc.y);
    
        customEvent = [NSEvent mouseEventWithType: [事件类型]
                                   位置:点击点
                              修饰符标志:[事件修饰符标志] | NSCommandKeyMask
                                  时间戳:[事件时间戳]
                               窗口号:WID
                                    上下文:无
                                事件编号:0
                                 点击次数:1
                                   压力:0];
    
        CGEvent = [自定义事件CGEvent];
    
        // 获取 iTunes PID
    
        NSRunningApplication* 应用程序;
    
        NSArray* runningApps = [[NSWorkspace共享工作空间] runningApplications];
    
        NSEnumerator* appEnumerator = [runningApps objectEnumerator];
    
        while ((app = [appEnumerator nextObject]))
        {
            if ([[应用程序包标识符] isEqualToString:@"com.apple.iTunes"])
    
                PID = [应用程序进程标识符];
        }
        NSLog(@"找到 iTunes: %d %@",(int)PID,WID);
    
        NSAssert(GetProcessForPID(PID, &psn) == noErr, @"GetProcessForPID 失败!");
    
        CGEventPostToPSN(&psn, CGEvent);
    }
    

问题是我看不到正在执行的鼠标单击。

I am trying to automate a left mouse click in iTunes from Objective-C. I am doing the following.

  1. first I am listening to iTunes events

    [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(allDistributedNotifications:)
                                                     name:nil
                                                     object:nil];
    
  2. when the allDistributedNotifications is called I do the following:

    - (void) allDistributedNotifications:(NSNotification *)note {
        NSString *object = [note object];
        NSString *name = [note name];
        NSDictionary *userInfo = [note userInfo];
        NSLog(@"object: %@ name: %@ userInfo: %@",object, name, userInfo);
    
        if([object isEqualToString:@"com.apple.iTunes.dialog"]&& [userInfo objectForKey:@"Showing Dialog"] == 0){
            NSLog(@"*** ended iTunes Dialogue");
        }
    
        if([name isEqualToString:@"com.apple.iTunes.sourceSaved"]){
            NSLog(@"*** iTunes saved to file");
            currentURLIndex +=1;
            [self loadWithData:[itmsURLs objectAtIndex:currentURLIndex] fromBot:YES];
        }
    }
    
  3. LoadWithData looks like this

    -(void) loadWithData:(NSURL*) url fromBot:(BOOL)aBot
    {
        BOOL success;
    
        success = [[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObject:url]
                  withAppBundleIdentifier:@"com.apple.itunes"
                  options:NSWorkspaceLaunchDefault
                  additionalEventParamDescriptor:nil
                  launchIdentifiers:nil];
        if(success){
            [numAppsDownloaded setStringValue:[NSString stringWithFormat:   @"%lu",currentURLIndex+1]];
        }
        if(success && aBot){
            [self performSelector:@selector(clickDownload) withObject:nil afterDelay:0.5];
        }
     }
    
  4. clickdownload in turn looks like this

    -(void) clickDownload
    {
        NSPoint mouseLoc;
    
        mouseLoc                = [NSEvent mouseLocation]; //get current mouse position
        CGPoint point           = CGPointMake(mouseLoc.x, mouseLoc.y);
    
        CGEventRef theEvent;
        CGEventType type;
    
        CGMouseButton button    = kCGMouseButtonLeft;
    
        type                    = kCGEventLeftMouseDown; // kCGEventLeftMouseDown = NX_LMOUSEDOWN,
        theEvent                = CGEventCreateMouseEvent(NULL,type, point, button);
    
        NSEvent* downEvent      = [NSEvent eventWithCGEvent:theEvent];
        [self forwardEvent:downEvent];
    
        [NSThread sleepForTimeInterval:0.2];
    
        type                    = kCGEventLeftMouseUp;
        theEvent                = CGEventCreateMouseEvent(NULL,type, point, button);
        NSEvent* upEvent        = [NSEvent eventWithCGEvent:theEvent];
        [self forwardEvent:upEvent];
    }
    

    5.Finally, forwardEvent looks like this

    - (void)forwardEvent: (NSEvent *)event
    {
        NSLog(@"event: %@",event);
    
        pid_t PID;
        NSInteger WID;
    
        // get the iTunes Window ID
    
        NSArray* windows    =  (NSArray*)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
    
        NSEnumerator* windowEnumerator = [windows objectEnumerator];
    
        while( (window = [windowEnumerator nextObject] ) )
        {
            if([[(NSDictionary*) window objectForKey:@"kCGWindowName"]  isEqualToString:@"iTunes"])
                WID = (NSInteger)[(NSDictionary*) window objectForKey:@"kCGWindowNumber"];
        }
    
        ProcessSerialNumber psn;
        CGEventRef CGEvent;
        NSEvent *customEvent;
    
        NSPoint mouseLoc        = [NSEvent mouseLocation]; //get current mouse position
        NSPoint clickpoint      = CGPointMake(mouseLoc.x, mouseLoc.y);
    
        customEvent = [NSEvent mouseEventWithType: [event type]
                                   location: clickpoint
                              modifierFlags: [event modifierFlags] | NSCommandKeyMask
                                  timestamp: [event timestamp]
                               windowNumber: WID
                                    context: nil
                                eventNumber: 0
                                 clickCount: 1
                                   pressure: 0];
    
        CGEvent = [customEvent CGEvent];
    
        // get the iTunes PID
    
        NSRunningApplication* app;
    
        NSArray* runningApps = [[NSWorkspace sharedWorkspace] runningApplications];
    
        NSEnumerator* appEnumerator = [runningApps objectEnumerator];
    
        while ((app = [appEnumerator nextObject]))
        {
            if ([[app bundleIdentifier] isEqualToString:@"com.apple.iTunes"])
    
                PID = [app processIdentifier];
        }
        NSLog(@"found iTunes: %d %@",(int)PID,WID);
    
        NSAssert(GetProcessForPID(PID, &psn) == noErr, @"GetProcessForPID failed!");
    
        CGEventPostToPSN(&psn, CGEvent);
    }
    

The problem is that I cannot see the mouse click being performed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

赴月观长安 2024-11-24 08:08:06

您正在使用 NSCommandKeyMask 发送鼠标左键事件。对于右键单击等效项(即按住 Control 单击),您需要使用 NSControlKeyMask。或者,您可以只使用鼠标右键事件,而不使用修饰符掩码。

You are sending left mouse button events with NSCommandKeyMask. For right click equivalent (i.e. control-click) you would want to use NSControlKeyMask. Alternatively you could just use right mouse button events without a modifier mask.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文