📄 toplevel.cpp
字号:
WindowRef window = NULL;
short windowPart = ::FindWindow(screenMouseLocation, &window);
wxWindow* currentMouseWindow = NULL ;
ControlRef control = NULL ;
#if NEW_CAPTURE_HANDLING
if ( wxApp::s_captureWindow )
{
window = (WindowRef) wxApp::s_captureWindow->MacGetTopLevelWindowRef() ;
windowPart = inContent ;
}
#endif
if ( window )
{
QDGlobalToLocalPoint( UMAGetWindowPort(window ) , &windowMouseLocation ) ;
if ( wxApp::s_captureWindow
#if !NEW_CAPTURE_HANDLING
&& wxApp::s_captureWindow->MacGetTopLevelWindowRef() == (WXWindow) window && windowPart == inContent
#endif
)
{
currentMouseWindow = wxApp::s_captureWindow ;
}
else if ( (IsWindowActive(window) && windowPart == inContent) )
{
ControlPartCode part ;
control = wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &part ) ;
// if there is no control below the mouse position, send the event to the toplevel window itself
if ( control == 0 )
{
currentMouseWindow = (wxWindow*) data ;
}
else
{
currentMouseWindow = wxFindControlFromMacControl( control ) ;
if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved )
{
#if wxUSE_TOOLBAR
// for wxToolBar to function we have to send certaint events to it
// instead of its children (wxToolBarTools)
ControlRef parent ;
GetSuperControl(control, &parent );
wxWindow *wxParent = wxFindControlFromMacControl( parent ) ;
if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) )
currentMouseWindow = wxParent ;
#endif
}
}
// disabled windows must not get any input messages
if ( currentMouseWindow && !currentMouseWindow->MacIsReallyEnabled() )
currentMouseWindow = NULL;
}
}
wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
SetupMouseEvent( wxevent , cEvent ) ;
// handle all enter / leave events
if ( currentMouseWindow != g_MacLastWindow )
{
if ( g_MacLastWindow )
{
wxMouseEvent eventleave(wxevent);
eventleave.SetEventType( wxEVT_LEAVE_WINDOW );
g_MacLastWindow->ScreenToClient( &eventleave.m_x, &eventleave.m_y );
eventleave.SetEventObject( g_MacLastWindow ) ;
wxevent.SetId( g_MacLastWindow->GetId() ) ;
#if wxUSE_TOOLTIPS
wxToolTip::RelayEvent( g_MacLastWindow , eventleave);
#endif
g_MacLastWindow->GetEventHandler()->ProcessEvent(eventleave);
}
if ( currentMouseWindow )
{
wxMouseEvent evententer(wxevent);
evententer.SetEventType( wxEVT_ENTER_WINDOW );
currentMouseWindow->ScreenToClient( &evententer.m_x, &evententer.m_y );
evententer.SetEventObject( currentMouseWindow ) ;
wxevent.SetId( currentMouseWindow->GetId() ) ;
#if wxUSE_TOOLTIPS
wxToolTip::RelayEvent( currentMouseWindow , evententer );
#endif
currentMouseWindow->GetEventHandler()->ProcessEvent(evententer);
}
g_MacLastWindow = currentMouseWindow ;
}
if ( windowPart == inMenuBar )
{
// special case menu bar, as we are having a low-level runloop we must do it ourselves
if ( cEvent.GetKind() == kEventMouseDown )
{
::MenuSelect( screenMouseLocation ) ;
result = noErr ;
}
}
else if ( currentMouseWindow )
{
wxWindow *currentMouseWindowParent = currentMouseWindow->GetParent();
currentMouseWindow->ScreenToClient( &wxevent.m_x , &wxevent.m_y ) ;
wxevent.SetEventObject( currentMouseWindow ) ;
wxevent.SetId( currentMouseWindow->GetId() ) ;
// make tooltips current
#if wxUSE_TOOLTIPS
if ( wxevent.GetEventType() == wxEVT_MOTION )
wxToolTip::RelayEvent( currentMouseWindow , wxevent );
#endif
if ( currentMouseWindow->GetEventHandler()->ProcessEvent(wxevent) )
{
if ((currentMouseWindowParent != NULL) &&
(currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
currentMouseWindow = NULL;
result = noErr;
}
else
{
// if the user code did _not_ handle the event, then perform the
// default processing
if ( wxevent.GetEventType() == wxEVT_LEFT_DOWN )
{
// ... that is set focus to this window
if (currentMouseWindow->AcceptsFocus() && wxWindow::FindFocus()!=currentMouseWindow)
currentMouseWindow->SetFocus();
}
ControlPartCode dummyPart ;
// if built-in find control is finding the wrong control (ie static box instead of overlaid
// button, we cannot let the standard handler do its job, but must handle manually
if ( ( cEvent.GetKind() == kEventMouseDown )
#ifdef __WXMAC_OSX__
&&
(FindControlUnderMouse(windowMouseLocation , window , &dummyPart) !=
wxMacFindControlUnderMouse( toplevelWindow , windowMouseLocation , window , &dummyPart ) )
#endif
)
{
if ( currentMouseWindow->MacIsReallyEnabled() )
{
EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
Point clickLocation = windowMouseLocation ;
if ( toplevelWindow->MacUsesCompositing() )
currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
modifiers , (ControlActionUPP ) -1 ) ;
if ((currentMouseWindowParent != NULL) &&
(currentMouseWindowParent->GetChildren().Find(currentMouseWindow) == NULL))
{
currentMouseWindow = NULL;
}
}
result = noErr ;
}
}
if ( cEvent.GetKind() == kEventMouseUp && wxApp::s_captureWindow )
{
wxApp::s_captureWindow = NULL ;
// update cursor ?
}
// update cursor
wxWindow* cursorTarget = currentMouseWindow ;
wxPoint cursorPoint( wxevent.m_x , wxevent.m_y ) ;
while ( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) )
{
cursorTarget = cursorTarget->GetParent() ;
if ( cursorTarget )
cursorPoint += cursorTarget->GetPosition();
}
}
else // currentMouseWindow == NULL
{
// don't mess with controls we don't know about
// for some reason returning eventNotHandledErr does not lead to the correct behaviour
// so we try sending them the correct control directly
if ( cEvent.GetKind() == kEventMouseDown && toplevelWindow && control )
{
EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
Point clickLocation = windowMouseLocation ;
#if TARGET_API_MAC_OSX
if ( toplevelWindow->MacUsesCompositing() )
{
HIPoint hiPoint ;
hiPoint.x = clickLocation.h ;
hiPoint.y = clickLocation.v ;
HIViewConvertPoint( &hiPoint , (ControlRef) toplevelWindow->GetHandle() , control ) ;
clickLocation.h = (int)hiPoint.x ;
clickLocation.v = (int)hiPoint.y ;
}
#endif // TARGET_API_MAC_OSX
HandleControlClick( control , clickLocation , modifiers , (ControlActionUPP ) -1 ) ;
result = noErr ;
}
}
return result ;
}
static pascal OSStatus wxMacTopLevelWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
wxMacCarbonEvent cEvent( event ) ;
// WindowRef windowRef = cEvent.GetParameter<WindowRef>(kEventParamDirectObject) ;
wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
switch ( GetEventKind( event ) )
{
case kEventWindowActivated :
{
toplevelWindow->MacActivate( cEvent.GetTicks() , true) ;
wxActivateEvent wxevent(wxEVT_ACTIVATE, true , toplevelWindow->GetId());
wxevent.SetTimestamp( cEvent.GetTicks() ) ;
wxevent.SetEventObject(toplevelWindow);
toplevelWindow->GetEventHandler()->ProcessEvent(wxevent);
// we still sending an eventNotHandledErr in order to allow for default processing
}
break ;
case kEventWindowDeactivated :
{
toplevelWindow->MacActivate(cEvent.GetTicks() , false) ;
wxActivateEvent wxevent(wxEVT_ACTIVATE, false , toplevelWindow->GetId());
wxevent.SetTimestamp( cEvent.GetTicks() ) ;
wxevent.SetEventObject(toplevelWindow);
toplevelWindow->GetEventHandler()->ProcessEvent(wxevent);
// we still sending an eventNotHandledErr in order to allow for default processing
}
break ;
case kEventWindowShown :
toplevelWindow->Refresh() ;
result = noErr ;
break ;
case kEventWindowClose :
toplevelWindow->Close() ;
result = noErr ;
break ;
case kEventWindowBoundsChanged :
{
UInt32 attributes = cEvent.GetParameter<UInt32>(kEventParamAttributes, typeUInt32) ;
Rect newRect = cEvent.GetParameter<Rect>(kEventParamCurrentBounds) ;
wxRect r( newRect.left , newRect.top , newRect.right - newRect.left , newRect.bottom - newRect.top ) ;
if ( attributes & kWindowBoundsChangeSizeChanged )
{
// according to the other ports we handle this within the OS level
// resize event, not within a wxSizeEvent
wxFrame *frame = wxDynamicCast( toplevelWindow , wxFrame ) ;
if ( frame )
{
frame->PositionBars();
}
wxSizeEvent event( r.GetSize() , toplevelWindow->GetId() ) ;
event.SetEventObject( toplevelWindow ) ;
toplevelWindow->GetEventHandler()->ProcessEvent(event) ;
toplevelWindow->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
}
if ( attributes & kWindowBoundsChangeOriginChanged )
{
wxMoveEvent event( r.GetLeftTop() , toplevelWindow->GetId() ) ;
event.SetEventObject( toplevelWindow ) ;
toplevelWindow->GetEventHandler()->ProcessEvent(event) ;
}
result = noErr ;
}
break ;
case kEventWindowBoundsChanging :
{
UInt32 attributes = cEvent.GetParameter<UInt32>(kEventParamAttributes,typeUInt32) ;
Rect newRect = cEvent.GetParameter<Rect>(kEventParamCurrentBounds) ;
if ( (attributes & kWindowBoundsChangeSizeChanged) || (attributes & kWindowBoundsChangeOriginChanged) )
{
// all (Mac) rects are in content area coordinates, all wxRects in structure coordinates
int left , top , right , bottom ;
toplevelWindow->MacGetContentAreaInset( left , top , right , bottom ) ;
wxRect r(
newRect.left - left,
newRect.top - top,
newRect.right - newRect.left + left + right,
newRect.bottom - newRect.top + top + bottom ) ;
// this is a EVT_SIZING not a EVT_SIZE type !
wxSizeEvent wxevent( r , toplevelWindow->GetId() ) ;
wxevent.SetEventObject( toplevelWindow ) ;
wxRect adjustR = r ;
if ( toplevelWindow->GetEventHandler()->ProcessEvent(wxevent) )
adjustR = wxevent.GetRect() ;
if ( toplevelWindow->GetMaxWidth() != -1 && adjustR.GetWidth() > toplevelWindow->GetMaxWidth() )
adjustR.SetWidth( toplevelWindow->GetMaxWidth() ) ;
if ( toplevelWindow->GetMaxHeight() != -1 && adjustR.GetHeight() > toplevelWindow->GetMaxHeight() )
adjustR.SetHeight( toplevelWindow->GetMaxHeight() ) ;
if ( toplevelWindow->GetMinWidth() != -1 && adjustR.GetWidth() < toplevelWindow->GetMinWidth() )
adjustR.SetWidth( toplevelWindow->GetMinWidth() ) ;
if ( toplevelWindow->GetMinHeight() != -1 && adjustR.GetHeight() < toplevelWindow->GetMinHeight() )
adjustR.SetHeight( toplevelWindow->GetMinHeight() ) ;
const Rect adjustedRect = { adjustR.y + top , adjustR.x + left , adjustR.y + adjustR.height - bottom , adjustR.x + adjustR.width - right } ;
if ( !EqualRect( &newRect , &adjustedRect ) )
cEvent.SetParameter<Rect>( kEventParamCurrentBounds , &adjustedRect ) ;
toplevelWindow->wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
}
result = noErr ;
}
break ;
default :
break ;
}
return result ;
}
// mix this in from window.cpp
pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) ;
pascal OSStatus wxMacTopLevelEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
switch ( GetEventClass( event ) )
{
case kEventClassTextInput :
result = wxMacUnicodeTextEventHandler( handler, event , data ) ;
break ;
case kEventClassKeyboard :
result = KeyboardEventHandler( handler, event , data ) ;
break ;
case kEventClassWindow :
result = wxMacTopLevelWindowEventHandler( handler, event , data ) ;
break ;
case kEventClassMouse :
result = wxMacTopLevelMouseEventHandler( handler, event , data ) ;
break ;
default :
break ;
}
return result ;
}
DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTopLevelEventHandler )
// ---------------------------------------------------------------------------
// wxWindowMac utility functions
// ---------------------------------------------------------------------------
// Find an item given the Macintosh Window Reference
WX_DECLARE_HASH_MAP(WindowRef, wxTopLevelWindowMac*, wxPointerHash, wxPointerEqual, MacWindowMap);
static MacWindowMap wxWinMacWindowList;
wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
{
MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef);
return (node == wxWinMacWindowList.end()) ? NULL : node->second;
}
void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win) ;
void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win)
{
// adding NULL WindowRef is (first) surely a result of an error and
// nothing else :-)
wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
wxWinMacWindowList[inWindowRef] = win;
}
void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win) ;
void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
{
MacWindowMap::iterator it;
for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it )
{
if ( it->second == win )
{
wxWinMacWindowList.erase(it);
break;
}
}
}
// ----------------------------------------------------------------------------
// wxTopLevelWindowMac creation
// ----------------------------------------------------------------------------
wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL;
typedef struct
{
wxPoint m_position ;
wxSize m_size ;
bool m_wasResizable ;
}
FullScreenData ;
void wxTopLevelWindowMac::Init()
{
m_iconized =
m_maximizeOnShow = false;
m_macWindow = NULL ;
#if TARGET_API_MAC_OSX
m_macUsesCompositing = ( UMAGetSystemVersion() >= 0x1030 );
#else
m_macUsesCompositing = false;
#endif
m_macEventHandler = NULL ;
m_macFullScreenData = NULL ;
}
class wxMacDeferredWindowDeleter : public wxObject
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -