如何在Mac OS X中获取当前鼠标指针的类型?

7

我该如何获取屏幕上当前鼠标光标的类型?(不仅限于我的应用窗口,全局范围内都需要获取)或者至少能够检测到默认光标是否正在显示?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”代理应用程序,此代码对我都有效。 - Rob Keniger
4个回答

2

这是一种非常巧妙的方法,但看起来至少可以使用hotSpot属性区分某些光标:

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

默认指针光标返回{5, 5}。我不知道在某些情况下(如更高的DPI或其他任何情况下)默认光标的值是否会改变。我已经在NSCursor类别中找到了这个值:

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

除此之外,还有一个名为_flags.cursorType的实例变量,但是它是受保护的。而且,正如你已经提到的那样,当前系统光标甚至不必与自己相等。

1
您可以使用类似以下代码的代码检查当前设置的光标类型:
if ([[NSCursor currentSystemCursor] isEqual: [NSCursor pointingHandCursor]]) {
  // … 
}

除了[NSCursor pointingHandCursor]之外,您可以使用的其他值列在检索光标实例中。


如果您只想捕获当前光标,而不与任何特定光标进行比较,那么可以请求当前系统光标的图像。 - Peter Hosey
谢谢,我搜索了好几次,但 Google 从未告诉我有一个 NSCursor 类。 - Cloudream
1
但是我使用 NSCursor *sysCursor = [NSCursor currentSystemCursor] 获取系统光标,并与每个可能的值进行比较,没有任何类型相等,问题中添加了代码。 - Cloudream

0
你可以比较光标图像。isEqual 对此无效,你必须获取位图图像数据并进行比较。

-2

你应该使用currentCursor而不是currentSystemCursor,所以你的sysCursor声明应该像这样:

NSCursor *sysCursor = [NSCursor currentCursor];

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

实际上,我在测试时在applicationDidFinishLaunching中运行此代码。我的应用程序没有窗口(只有状态栏中的图标),因此currentCursor返回nil。 - Cloudream
你可以使用NSTimer在applicationDidFinishLaunching:方法后检查光标,并在一秒钟后调用特定的方法(或在更短的时间内调用不同的解决方案)。 [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(checkCursor) userInfo:nil repeats:NO]; 该方法类似于以下内容:
  • (void)checkCursor { /检查光标/ }
- Sylter
1
currentCursor 指的是您应用程序中的当前光标,而不是活动应用程序中的当前光标。 - Peter Hosey
1
NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(checkCursor) userInfo:nil repeats:NO]; 仍然无法工作。(总是“不”)它在你的机器上工作吗? - Cloudream

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接