有条件地处理透明窗口上的鼠标事件

spd*_*spd 9 macos conditional transparent mouseevent nswindow

我正在开发一个桌面应用程序,我可以在透明窗口上进行鼠标事件.但是,透明的NSWindow不接受鼠标事件.所以,我将setIgnoreMouseEvents设置为NO,允许透明窗口捕获鼠标事件.

我在以下场景中遇到问题:在此窗口上有动态创建的矩形形状.透明窗口不应该在此区域中捕获鼠标事件; 它应该委托给这个形状后面的窗口(某些其他应用程序).为此,如果mouseDown事件在形状内,我将setIgnoreMouseEvents设置为YES.现在,如果用户在形状外的区域中执行鼠标事件,透明窗口应该接受事件.由于setIgnoreMouseEvents设置为YES,因此窗口不会捕获鼠标事件.

无法识别mouseDown事件是否已发生,因此我可以将setIgnoreMouseEvents设置为NO.

有人可以建议我在透明窗口上处理鼠标事件的最佳方法吗?

迪帕

小智 3

我刚刚遇到了 Quartz Event Taps,它基本上可以让您捕获鼠标事件并执行您自己的回调。

我自己还没有尝试过,但似乎您应该能够检查鼠标单击的位置并根据值有条件地执行

这是一个例子

//---------------------------------------------------------------------------  
 CGEventRef MouseTapCallback( CGEventTapProxy aProxy, CGEventType aType, CGEventRef aEvent, void* aRefcon )   
 //---------------------------------------------------------------------------  
 {  
    if( aType == kCGEventRightMouseDown ) NSLog( @"down" );  
    else if( aType == kCGEventRightMouseUp ) NSLog( @"up" );  
    else NSLog( @"other" );  

   CGPoint theLocation = CGEventGetLocation(aEvent);  
   NSLog( @"location x: %d y:%d", theLocation.x, theLocation.y );  

   return aEvent;   
 }   

 //---------------------------------------------------------------------------  
 - (void)applicationDidFinishLaunching:(NSNotification *)aNotification   
 //---------------------------------------------------------------------------  
 {  
   CGEventMask theEventMask = CGEventMaskBit(kCGEventRightMouseDown) |  
                 CGEventMaskBit(kCGEventRightMouseUp);  

   CFMachPortRef theEventTap = CGEventTapCreate( kCGSessionEventTap,   
                          kCGHeadInsertEventTap,   
                          0,   
                          theEventMask,   
                          MouseTapCallback,   
                          NULL );   

   if( !theEventTap )   
   {  
     NSLog( @"Failed to create event tap!" );  
   }   

   CFRunLoopSourceRef theRunLoopSource =   
     CFMachPortCreateRunLoopSource( kCFAllocatorDefault, theEventTap, 0);   

   CFRunLoopAddSource( CFRunLoopGetCurrent(),  
                       theRunLoopSource,   
                       kCFRunLoopCommonModes);   
   CGEventTapEnable(theEventTap, true);  
 }  
Run Code Online (Sandbox Code Playgroud)