2010-04-02 101 views
0

我创建了一个本地事件循环,并且出现了一个无边框窗口(派生自NSPanel), 我发现事件循环中没有收到NSMouseMoved事件,尽管我可以接收鼠标按钮向下/向上事件。可可nextEventMatchingMask没有收到NSMouseMoved事件

我应该怎么做才能获得NSMouseMoved事件?我发现将浮动窗口作为关键窗口可以接收NSMouseMoved事件,但我不想更改关键窗口。看起来这是可能的,因为我在单击System Dock Bar中的测试应用程序图标后发现,我可以接收mousemoved事件,并且关键窗口/主窗口未更改。

这里是我的测试代码:(创建一个可可应用程序项目名称FloatWindowTest,并把一个按钮,用的onClick链接:IBAction为)。 在此先感谢!

-Jonny

#import "FloatWindowTestAppDelegate.h" 

@interface FloatWindow : NSPanel 
@end 

@interface FloatWindowContentView : NSView 
@end 

@implementation FloatWindowTestAppDelegate 

@synthesize window; 

- (void)delayedAction:(id)sender 
{ 
    // What does this function do? 
    // 1. create a float window 
    // 2. create a local event loop 
    // 3. print out the events got from nextEventMatchingMask. 
    // 4. send it to float window. 

    // What is the problem? 
    // In local event loop, althrough the event mask has set NSMouseMovedMask 
    // there's no mouse moved messages received. 
    // 

    FloatWindow* floatWindow = [[FloatWindow alloc] init]; 

    NSEvent* event = [NSApp currentEvent]; 
    NSPoint screenOrigin = [[self window] convertBaseToScreen:[event locationInWindow]];  
    [floatWindow setFrameTopLeftPoint:screenOrigin]; 
    [floatWindow orderFront:nil]; 


    //Making the float window as Key window will work, however 
    //change active window is not anticipated. 
    //[floatWindow makeKeyAndOrderFront:nil]; 

    BOOL done = NO; 
    while (!done) 
    { 
     NSAutoreleasePool* pool = [NSAutoreleasePool new]; 
     NSUInteger eventMask = NSLeftMouseDownMask| 
     NSLeftMouseUpMask| 
     NSMouseMovedMask| 
     NSMouseEnteredMask| 
     NSMouseExitedMask| 
     NSLeftMouseDraggedMask; 

     NSEvent* event = [NSApp nextEventMatchingMask:eventMask 
              untilDate:[NSDate distantFuture] 
               inMode:NSDefaultRunLoopMode 
               dequeue:YES]; 

     //why I cannot get NSMouseMoved event?? 
     NSLog(@"new event %@", [event description]); 
     [floatWindow sendEvent:event]; 
     [pool drain]; 
    } 

    [floatWindow release]; 
    return; 
} 

-(IBAction)onClick:(id)sender 
{ 
    //Tried to postpone the local event loop 
    //after return from button's mouse tracking loop. 
    //but not fixes this problem. 
    [[NSRunLoop currentRunLoop] 
      performSelector:@selector(delayedAction:) 
        target:self 
        argument:nil 
        order:0 
        modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; 
} 
@end 



@implementation FloatWindow 

- (id)init 
{ 
    NSRect contentRect = NSMakeRect(200,300,200,300); 
    self = [super initWithContentRect:contentRect 
          styleMask:NSTitledWindowMask 
           backing:NSBackingStoreBuffered 
           defer:YES]; 

    if (self) { 
     [self setLevel:NSFloatingWindowLevel]; 

     NSRect frameRect = [self frameRectForContentRect:contentRect]; 
     NSView* view = [[[FloatWindowContentView alloc] 
         initWithFrame:frameRect] autorelease]; 
     [self setContentView:view]; 

     [self setAcceptsMouseMovedEvents:YES]; 
     [self setIgnoresMouseEvents:NO]; 
    }  
    return self;       
} 

- (BOOL)becomesKeyOnlyIfNeeded 
{ 
    return YES; 
} 

- (void)becomeMainWindow 
{ 
    NSLog(@"becomeMainWindow"); 
    [super becomeMainWindow]; 
} 

- (void)becomeKeyWindow 
{ 
    NSLog(@"becomeKeyWindow"); 
    [super becomeKeyWindow]; 
} 

@end 

@implementation FloatWindowContentView 

- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent 
{ 
    return YES; 
} 

- (BOOL)acceptsFirstResponder 
{ 
    return YES; 
} 

- (id)initWithFrame:(NSRect)frameRect 
{ 
    self = [super initWithFrame:frameRect]; 
    if (self) { 
     NSTrackingArea* area; 
     area = [[NSTrackingArea alloc] initWithRect:frameRect 
              options:NSTrackingActiveAlways| 
                NSTrackingMouseMoved| 
                NSTrackingMouseEnteredAndExited 
               owner:self 
              userInfo:nil]; 
     [self addTrackingArea:area]; 
     [area release]; 
    } 
    return self; 
} 

- (void)drawRect:(NSRect)rect 
{ 
    [[NSColor redColor] set]; 
    NSRectFill([self bounds]); 
} 

- (BOOL)becomeFirstResponder 
{ 
    NSLog(@"becomeFirstResponder"); 
    return [super becomeFirstResponder]; 
} 

@end 

回答

1

我想我找到正确的答案。这在某种程度上与告诉NSWindow接受MouseMoved事件有关。但什么让我吃惊的是,该窗口应该接受的mouseMoved事件不是浮动窗口,但目前的主要窗口。所以解决方案很简单,只需在开始跟踪之前启用关键窗口接受鼠标移动的事件,并在结束跟踪后恢复开关。