【问题标题】:How to get current type of mouse cursor in Mac OS X?如何在 Mac OS X 中获取当前类型的鼠标光标?
【发布时间】:2012-01-02 03:49:06
【问题描述】:

如何在屏幕上获取当前类型的鼠标光标? (不仅在我的应用程序窗口上,全局。)或者至少可以检测到当前是否显示默认光标? Carbon 或 Cocoa 都可以——甚至是其他可用的 API,最好是官方的。

这是我尝试过的:

NSCursor *sysCursor = [NSCursor currentSystemCursor];

if (sysCursor == nil) {
    NSLog(@"nil");
}

if ([sysCursor isEqual: [NSCursor arrowCursor]] || 
    [sysCursor isEqual: [NSCursor contextualMenuCursor]] || 
    [sysCursor isEqual: [NSCursor closedHandCursor]] || 
    [sysCursor isEqual: [NSCursor crosshairCursor]] || 
    [sysCursor isEqual: [NSCursor disappearingItemCursor]] || 
    [sysCursor isEqual: [NSCursor dragCopyCursor]] || 
    [sysCursor isEqual: [NSCursor dragLinkCursor]] || 
    [sysCursor isEqual: [NSCursor IBeamCursor]] || 
    [sysCursor isEqual: [NSCursor openHandCursor]] || 
    [sysCursor isEqual: [NSCursor operationNotAllowedCursor]] || 
    [sysCursor isEqual: [NSCursor pointingHandCursor]] || 
    [sysCursor isEqual: [NSCursor resizeDownCursor]] || 
    [sysCursor isEqual: [NSCursor resizeLeftCursor]] || 
    [sysCursor isEqual: [NSCursor resizeLeftRightCursor]] || 
    [sysCursor isEqual: [NSCursor resizeRightCursor]] || 
    [sysCursor isEqual: [NSCursor resizeUpCursor]] || 
    [sysCursor isEqual: [NSCursor resizeUpDownCursor]] || 
    [sysCursor isEqual: [NSCursor IBeamCursorForVerticalLayout]]
    ) {
    NSLog(@"equal");
} else {
    NSLog(@"not");
}

光标不是nil,但同时也不等于其他任何一个。它甚至不等于它自己:

NSLog(@"%i", [[NSCursor currentSystemCursor]
    isEqual:[NSCursor currentSystemCursor]]); // 0

想法?这是一个LSUIElement 类型的应用程序,如果这很重要的话。

【问题讨论】:

  • 无论应用程序是否为 LSUIElement 代理应用程序,此代码都适用于我。

标签: macos cocoa macos-carbon mouse-cursor


【解决方案1】:

您可以使用类似于以下的代码检查当前设置的光标类型:

if ([[NSCursor currentSystemCursor] isEqual: [NSCursor pointingHandCursor]]) {
  // … 
}

Retrieving cursor instances 中列出了您可以使用的其他值,而不是 [NSCursor pointingHandCursor]

【讨论】:

  • 如果您只想捕获当前光标,而不将其与任何特定光标进行比较,那么您可以向当前系统光标询问其图像。
  • 谢谢,搜索了好几次,但谷歌从来没有告诉我有一个 NSCursor 类。
  • 但是我用NSCursor *sysCursor = [NSCursor currentSystemCursor] 获取系统光标并与每个可能的值进行比较,没有类型相等,添加了有问题的代码。
  • [[NSCursor currentSystemCursor] isEqual: [NSCursor currentSystemCursor]] 不是真的,知道吗?谢谢。
【解决方案2】:

这是一个 hack,但看起来可以使用 hotSpot 属性来区分至少一些游标:

NSLog(@"%@", NSStringFromPoint([[NSCursor currentSystemCursor] hotSpot]));

这将为默认指针光标返回{5, 5}。我不知道在某些情况下(如更高的 DPI 或其他),默认光标的此值是否会发生变化。我在NSCursor 上结束了这个类别:

- (BOOL) isDefaultCursor
{
    NSPoint defaultCursorHotspot = [[NSCursor arrowCursor] hotSpot];
    return NSEqualPoints(defaultCursorHotspot, [self hotSpot]);
}

除此之外,还有一个 _flags.cursorType 实例变量,但它是受保护的。而且,正如您已经提到的,当前系统光标本身不必是-isEqual:

【讨论】:

    【解决方案3】:

    您可以比较光标图像。 isEqual 不起作用,您必须获取位图图像数据并进行比较。

    【讨论】:

      【解决方案4】:

      您应该使用 currentCursor 而不是 currentSystemCursor,因此您的 sysCursor 声明应该是这样的:

      NSCursor *sysCursor = [NSCursor currentCursor];
      

      此外,您应该检查用户点击后的光标类型,而不是,例如在 applicationDidFinishLaunching 或类似中。

      【讨论】:

      • 实际上我在测试时在applicationDidFinishLaunching 中运行了这段代码。我的应用是无窗口的(状态栏中只有一个图标),所以currentCursor 返回 nil。
      • 您可以在 applicationDidFinishLaunching 之后检查光标:使用 NSTimer 并在例如一秒后调用特定方法(或者在更短的时间后,您可以尝试不同的解决方案)。 [NSTimer scheduleTimerWithTimeInterval:1 目标:self 选择器:@selector(checkCursor) userInfo:nil repeats:NO];方法类似于这个: - (void)checkCursor { /*检查光标*/ }
      • currentCursor 指的是您的应用程序的当前光标,而不是活动应用程序中的当前光标。
      • NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(checkCursor) userInfo:nil repeats:NO]; 仍然无法正常工作。 (总是“不”)它可以在你的机器上运行吗?
      • [[NSCursor currentSystemCursor] isEqual: [NSCursor currentSystemCursor]] 不是真的,知道吗?谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      相关资源
      最近更新 更多