问题描述
我有一个程序可以接受NSWindow的本机窗口句柄(已经创建但尚不可见)。我这样做是为了更改某些本机窗口样式和行为。除了无法使mouseEnter / mouseExit正常工作以外,我可以做所有需要做的事情,因为它似乎需要在实例化之前进行子类化。有没有解决的办法?我真的不想仅仅为了检测窗口的一部分的mouseEnter和mouseExit而连续轮询鼠标位置。
注意:我必须这样做,因为我想在窗口未聚焦时检测到悬停。
我可以附加跟踪区域,但是如果不对它进行子类化,我不确定如何挂入事件:
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:CGRectMake(0,120,300) options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveAlways owner:window userInfo:nil];
[window.contentView addTrackingArea:area];
P.S。如果有帮助,我愿意使用C或Swift。
解决方法
您无需创建视图即可执行此操作,您可以使用任何自定义对象(例如您的 controller )作为跟踪方法的一种委托:
NSView * theView = window.contentView;
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect: theView.bounds
options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingActiveAlways)
owner:myController //<-- your controller
userInfo:nil];
[theView addTrackingArea:area];
从那里,跟踪方法将发送到'myController'
,感谢@Willeke建议对新的子类进行子类化,而不必担心对窗口进行子类化。
#include <Cocoa/Cocoa.h>
@interface TrackerView : NSView
-(void)mouseEntered:(NSEvent *)theEvent;
-(void)mouseExited:(NSEvent *)theEvent;
@end
@implementation TrackerView
-(void)mouseEntered:(NSEvent *)theEvent {
NSLog(@"Mouse entered");
}
-(void)mouseExited:(NSEvent *)theEvent {
NSLog(@"Mouse exited");
}
@end
void AddTrackingToWindow(void* windowPointer) {
NSWindow* window = windowPointer;
TrackerView *trackerView = [[TrackerView alloc] initWithFrame:CGRectMake(0,50,50)];
[trackerView setWantsLayer:YES];
trackerView.layer.backgroundColor = [[NSColor yellowColor] CGColor];
[window.contentView addSubview:trackerView];
NSTrackingArea *area = [[NSTrackingArea alloc] initWithRect:CGRectMake(0,50) options:NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingActiveAlways owner:trackerView userInfo:nil];
[trackerView addTrackingArea:area];
}