我正在尝试制作一个简单的应用程序,其中有一个空的红色矩形,每当鼠标移动到矩形的上半边框时,光标就会变成闭合的手。
我从选择基础命令行项目开始。制作了一个透明的
NSWindow
,并用矩形在其中嵌入了NSView
,制作了窗口来接受鼠标移动事件(通过方法:-setAcceptsMouseMovedEvents
)。我已覆盖 -canBecomeKeyWindow
和 -canBecomeMainWindow
窗口以返回 YES。但不知何故,-mouseMoved
没有收到任何 NSView
事件。
当我通过制作可可应用程序项目并在
-applicationDidFinishLaunching
方法中创建窗口来放置相同的代码时,我的视图能够接收 -mouseMoved
事件。
为什么当我使用基础命令行实用项目时它没有接收到鼠标移动事件?
我还观察到,每当我通过基础命令行实用程序项目创建一个窗口(carbon 或 cocoa)时,即使单击标题栏,该窗口也不会成为关键。单击标题栏时,标题栏颜色保持浅灰色而不是变暗灰色的。为什么会发生这种情况?
我已覆盖
-canBecomeKeyWindow
和 -canBecomeMainWindow
的 NSwindow
以返回 YES。
我同意约书亚已经说过的话。任何要显示用户界面的应用程序,无论是不露面的后台进程还是显示在 Dock 中的进程,都应该采用应用程序包的形式,而不是像 Foundation 工具模板那样的普通旧式 Mach-O 可执行文件。创建。
此外,视图默认不响应
mouseMoved:
事件也是有原因的:
mouseMoved:
,因为跟踪区域
更加有效和高效。不久前,我编写了一个小测试应用程序来演示这两种方法之间的差异:
在上视图中移动鼠标大约 20 秒会产生 1000 个事件,而在使用跟踪区域的下视图中,会产生不到 50 个事件。
示例 GitHub 项目:https://github.com/NSGod/MouseMoved-vs-TrackingAreas
再次,正如约书亚提到的,如果您能够描述您想要完成的任务,将会很有帮助。如果您的应用程序需要成为后台应用程序(LSUIElement == 1),并呈现一个界面而不出现在 Dock 中,那么有一些方法可以做到这一点(正如 Josh 提到的,命令行、非捆绑应用程序不是方式)。
您没有事件循环来检测事件并将它们传递到您的窗口,因为您的程序没有启动 NSApplication。请参阅典型 Cocoa 应用程序的 main.m 文件。
描述您试图通过采用这种方法实现的目标可能会有所帮助。我的猜测是您正在构建一个守护进程,但想要一个 GUI 界面来管理“无头”守护进程。或者您正在构建一个新的登录管理系统。无论哪种情况,都有特定的方法可以同时完成这两者,但不是这样。 :-)
要使您的
NSView
检测 mouseMoved 事件,您必须执行以下操作:
acceptsFirstResponder
属性mouseMoved
事件acceptMouseMovedEvents = YES
@implementation YourNSView
- (BOOL) acceptsFirstResponder {
return YES;
}
- (void) mouseMoved:(NSEvent*) event {
// can't hear these events? did you override acceptsFirstResponder!
[super mouseMoved:event];
printf( "Mouse @ %f %f\n", event.locationInWindow.x, event.locationInWindow.y );
}
@end
@implementation YourAppDelegate
- (void) applicationDidFinishLaunching:(NSNotification *)aNotification {
self.window.acceptsMouseMovedEvents = YES;
}
@end
如果缺少其中任何一个,它将无法工作。以上对我有用,如果仍然不起作用,其他建议是尝试致电:
[window makeMainWindow];
[window makeKeyAndOrderFront:self.window];