J'ai créé une boucle d'événement local et montré une fenêtre sans bordure (dérivée de NSPanel), J'ai trouvé dans la boucle d'événement aucun événement NSMouseMoved reçu, bien que je puisse recevoir des événements de bouton bas/haut de souris . Que dois-je faire pour obtenir les événements NSMouseMoved?Cocoa nextEventMatchingMask ne recevant pas l'événement NSMouseMoved
J'ai trouvé que faire la fenêtre flottante comme fenêtre clé peut recevoir les événements NSMouseMoved, mais je ne veux pas changer la fenêtre clé. Et il semble que cela soit possible, parce que j'ai trouvé après avoir cliqué sur l'icône de l'application de test dans la barre de Dock système, je peux recevoir les événements mousemoved, et la fenêtre clé/mainwindow sont inchangées.
Voici le code de mon test: (Créez un projet Cocoa App FloatWindowTest, et mettez un bouton à lier avec onClick: IBAction). Merci d'avance!
-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