基本上我想创建系统菜单栏中提供的效果。用户按下其中一个菜单标题,当他在不同的标题上移动时,菜单会自动打开。
问题是,如果我打开按钮的弹出菜单,用户必须再次单击才能关闭它。整个运行循环被搁置,因为我相信弹出菜单是模态的。当用户移动到下一个按钮时,如何才能发送 [somePopUpMenu cancelTracking]?
这是我目前正在 NSWindow 子类中尝试的代码。重点是,一旦鼠标退出一个按钮,鼠标会自动点击(leftdown/leftup)下一个按钮,定时器失效,弹出菜单取消。
假设弹出菜单打开并且鼠标存在,则 leftdown/leftup 事件被触发(我知道这是有效的,因为我将它们记录在 NSLog 中的 mouseDown 和 mouseUp 中),计时器无效,但弹出菜单仍然存在显示,而假事件“单击”的另一个按钮没有显示任何内容。此外,整个事情进入了一个循环,并且由于某种原因发送了疯狂的 mouseDown/mouseUp 。
值得注意的是,弹出菜单是在另一个对象中创建的,尽管 hookToMenu 有对其的正确引用(我通过调试/单步执行确认)。
不知道我是否在破坏事件跟踪计时器或以错误的方式进行。我也通过窗口 Controller 尝试过,但得到了相同的结果。
对此的任何帮助将不胜感激。
-(void)stopTimer
{
[timer invalidate];
[hookToMenu cancelTracking]; //hookToMenu is NSMenu*
}
-startFireDateTimer
{
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
timer = [[NSTimer alloc] initWithFireDate:nil interval:0 target:self selector:@selector(targetMethod) userInfo:nil repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSEventTrackingRunLoopMode];
[timer release];
}
-(void)targetMethod
{
NSEvent *newEvent;
newEvent=[NSApp nextEventMatchingMask:NSMouseExitedMask untilDate:[NSDate distantFuture] inMode:NSEventTrackingRunLoopMode dequeue:NO];
if ([newEvent type]==NSMouseExited)
{
NSPoint mouseLoc;
mouseLoc=[newEvent locationInWindow];
int type=NSLeftMouseDown;
int type2=NSLeftMouseUp;
int windowNumber=[self windowNumber];
id fakeMouseUpEvent=[NSEvent mouseEventWithType:type
location:mouseLoc
modifierFlags:nil
timestamp:[NSDate timeIntervalSinceReferenceDate]
windowNumber:windowNumber
context:nil
eventNumber:nil
clickCount:1
pressure:1];
id fakeMouseUpEvent2=[NSEvent mouseEventWithType:type2
location:mouseLoc
modifierFlags:nil
timestamp:[NSDate timeIntervalSinceReferenceDate]
windowNumber:windowNumber
context:nil
eventNumber:nil
clickCount:1
pressure:1];
[NSApp sendEvent:fakeMouseUpEvent];
[NSApp sendEvent:fakeMouseUpEvent2];
[self stopTimer];
}
}
-(void)mouseDown:(NSEvent *)theEvent
{
[self startFireDateTimer];
NSLog(@"WINDOW: mouse down in window!");
[super mouseDown:theEvent];
}
-(void)mouseUp:(NSEvent *)theEvent
{
NSLog(@"WINDOW: mouse up in window!");
[super mouseUp:theEvent];
}
最佳答案
How do I go about being able to send a [somePopUpMenu cancelTracking] when the user moves to the next button?
就这么做吧。 NSMenu responds to a cancelTracking
message自 Mac OS X 10.5 起。
关于objective-c - Cocoa AppKit - 关闭模式窗口(即弹出窗口或上下文菜单)并按下当前悬停在上方的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2495044/