【问题标题】:Automating iTunes mouse click in Objective-C在 Objective-C 中自动点击 iTunes 鼠标
【发布时间】:2011-06-26 04:41:37
【问题描述】:

我正在尝试通过 Objective-C 在 iTunes 中自动单击鼠标左键。我正在执行以下操作。

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

    [[NSDistributedNotificationCenter defaultCenter] addObserver:self
                                                     selector:@selector(allDistributedNotifications:)
                                                     name:nil
                                                     object:nil];
    
  2. 当调用 allDistributedNotifications 时,我会执行以下操作:

    - (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 看起来像这样

    -(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. 依次点击下载是这样的

    -(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.最后forwardEvent是这样的

    - (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);
    }
    

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

【问题讨论】:

  • 您为什么要注册所有分布式通知?有许多与 iTunes 无关;如果您按名称注册您感兴趣的特定 iTunes 通知,您的代码将更简单,您的应用程序将更有效地运行。其次,您的 forwardEvent: 方法似乎忽略了传递给它的事件,而是创建了一个新事件。第三,您假设鼠标光标位于 iTunes 窗口内,这可能不太可能。
  • 这个问题的标题是怎么回事?

标签: objective-c cocoa events mouse itunes


【解决方案1】:

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

【讨论】:

  • 嗨尼克。我正在发送左下和上事件 ([self forwardEvent:NSLeftMouseDown];[NSThread sleepForTimeInterval:0.2];[self forwardEvent:NSLeftMouseUp];) 我在这里做错了吗?我曾尝试将modifierFlags 设置为0,但没有成功。
  • “右键单击”有两种方式:(1) 按下鼠标右键,或 (2) 在按住 control (⌃) 键的同时按下鼠标左键。您的代码不执行这些操作,您在按住 command (⌘) 键的同时按下左键。
  • NSCommandKeyMask 错误。同意。但我不想右键单击。我试图在 iTunes 中的一个按钮上左键单击然后向上。我想模拟左键单击。谢谢尼克
  • 好的,但你的开场白是“我正在尝试自动单击鼠标右键”
  • 哦,我的错。对不起。有什么建议为什么代码不起作用?
猜你喜欢
  • 1970-01-01
  • 2013-07-19
  • 2011-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多