📄 toplevel.cpp
字号:
///////////////////////////////////////////////////////////////////////////////// Name: src/mac/carbon/toplevel.cpp// Purpose: implements wxTopLevelWindow for Mac// Author: Stefan Csomor// Modified by:// Created: 24.09.01// RCS-ID: $Id: toplevel.cpp,v 1.188 2006/10/19 00:22:11 KO Exp $// Copyright: (c) 2001-2004 Stefan Csomor// License: wxWindows licence///////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx.h".#include "wx/wxprec.h"#ifdef __BORLANDC__ #pragma hdrstop#endif#include "wx/toplevel.h"#ifndef WX_PRECOMP #include "wx/app.h" #include "wx/frame.h" #include "wx/string.h" #include "wx/log.h" #include "wx/intl.h" #include "wx/settings.h" #include "wx/strconv.h" #include "wx/control.h"#endif //WX_PRECOMP#include "wx/mac/uma.h"#include "wx/mac/aga.h"#include "wx/tooltip.h"#include "wx/dnd.h"#if wxUSE_SYSTEM_OPTIONS #include "wx/sysopt.h"#endif#ifndef __DARWIN__#include <ToolUtils.h>#endif// for targeting OSX#include "wx/mac/private.h"// ----------------------------------------------------------------------------// constants// ----------------------------------------------------------------------------// trace mask for activation tracing messagesstatic const wxChar *TRACE_ACTIVATE = _T("activation");// ----------------------------------------------------------------------------// globals// ----------------------------------------------------------------------------// list of all frames and modeless dialogswxWindowList wxModelessWindows;static pascal long wxShapedMacWindowDef(short varCode, WindowRef window, SInt16 message, SInt32 param);// ============================================================================// wxTopLevelWindowMac implementation// ============================================================================BEGIN_EVENT_TABLE(wxTopLevelWindowMac, wxTopLevelWindowBase)END_EVENT_TABLE()// ---------------------------------------------------------------------------// Carbon Events// ---------------------------------------------------------------------------static const EventTypeSpec eventList[] ={ // TODO: remove control related event like key and mouse (except for WindowLeave events) { kEventClassKeyboard, kEventRawKeyDown } , { kEventClassKeyboard, kEventRawKeyRepeat } , { kEventClassKeyboard, kEventRawKeyUp } , { kEventClassKeyboard, kEventRawKeyModifiersChanged } , { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } , { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } , { kEventClassWindow , kEventWindowShown } , { kEventClassWindow , kEventWindowActivated } , { kEventClassWindow , kEventWindowDeactivated } , { kEventClassWindow , kEventWindowBoundsChanging } , { kEventClassWindow , kEventWindowBoundsChanged } , { kEventClassWindow , kEventWindowClose } , // we have to catch these events on the toplevel window level, // as controls don't get the raw mouse events anymore { kEventClassMouse , kEventMouseDown } , { kEventClassMouse , kEventMouseUp } , { kEventClassMouse , kEventMouseWheelMoved } , { kEventClassMouse , kEventMouseMoved } , { kEventClassMouse , kEventMouseDragged } ,} ;static pascal OSStatus KeyboardEventHandler( EventHandlerCallRef handler , EventRef event , void *data ){ OSStatus result = eventNotHandledErr ; // call DoFindFocus instead of FindFocus, because for Composite Windows(like WxGenericListCtrl) // FindFocus does not return the actual focus window, but the enclosing window wxWindow* focus = wxWindow::DoFindFocus(); if ( focus == NULL ) focus = (wxTopLevelWindowMac*) data ; unsigned char charCode ; wxChar uniChar[2] ; uniChar[0] = 0; uniChar[1] = 0; UInt32 keyCode ; UInt32 modifiers ; Point point ; UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ;#if wxUSE_UNICODE ByteCount dataSize = 0 ; if ( GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr ) { UniChar buf[2] ; int numChars = dataSize / sizeof( UniChar) + 1; UniChar* charBuf = buf ; if ( numChars * 2 > 4 ) charBuf = new UniChar[ numChars ] ; GetEventParameter( event, kEventParamKeyUnicodes, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ; charBuf[ numChars - 1 ] = 0;#if SIZEOF_WCHAR_T == 2 uniChar = charBuf[0] ;#else wxMBConvUTF16 converter ; converter.MB2WC( uniChar , (const char*)charBuf , 2 ) ;#endif if ( numChars * 2 > 4 ) delete[] charBuf ; }#endif GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode ); GetEventParameter( event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode ); GetEventParameter( event, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers ); GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point ); UInt32 message = (keyCode << 8) + charCode; switch ( GetEventKind( event ) ) { case kEventRawKeyRepeat : case kEventRawKeyDown : { WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; wxTheApp->MacSetCurrentEvent( event , handler ) ; if ( /* focus && */ wxTheApp->MacSendKeyDownEvent( focus , message , modifiers , when , point.h , point.v , uniChar[0] ) ) { result = noErr ; } wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; } break ; case kEventRawKeyUp : if ( /* focus && */ wxTheApp->MacSendKeyUpEvent( focus , message , modifiers , when , point.h , point.v , uniChar[0] ) ) { result = noErr ; } break ; case kEventRawKeyModifiersChanged : { wxKeyEvent event(wxEVT_KEY_DOWN); event.m_shiftDown = modifiers & shiftKey; event.m_controlDown = modifiers & controlKey; event.m_altDown = modifiers & optionKey; event.m_metaDown = modifiers & cmdKey; event.m_x = point.h; event.m_y = point.v;#if wxUSE_UNICODE event.m_uniChar = uniChar[0] ;#endif event.SetTimestamp(when); event.SetEventObject(focus); if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & controlKey ) { event.m_keyCode = WXK_CONTROL ; event.SetEventType( ( modifiers & controlKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; focus->GetEventHandler()->ProcessEvent( event ) ; } if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & shiftKey ) { event.m_keyCode = WXK_SHIFT ; event.SetEventType( ( modifiers & shiftKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; focus->GetEventHandler()->ProcessEvent( event ) ; } if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & optionKey ) { event.m_keyCode = WXK_ALT ; event.SetEventType( ( modifiers & optionKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; focus->GetEventHandler()->ProcessEvent( event ) ; } if ( /* focus && */ (modifiers ^ wxApp::s_lastModifiers ) & cmdKey ) { event.m_keyCode = WXK_COMMAND ; event.SetEventType( ( modifiers & cmdKey ) ? wxEVT_KEY_DOWN : wxEVT_KEY_UP ) ; focus->GetEventHandler()->ProcessEvent( event ) ; } wxApp::s_lastModifiers = modifiers ; } break ; default: break; } return result ;}// we don't interfere with foreign controls on our toplevel windows, therefore we always give back eventNotHandledErr// for windows that we didn't create (like eg Scrollbars in a databrowser), or for controls where we did not handle the// mouse down at all//// This handler can also be called from app level where data (ie target window) may be null or a non wx windowwxWindow* g_MacLastWindow = NULL ;EventMouseButton g_lastButton = 0 ;void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent ){ UInt32 modifiers = cEvent.GetParameter<UInt32>(kEventParamKeyModifiers, typeUInt32) ; Point screenMouseLocation = cEvent.GetParameter<Point>(kEventParamMouseLocation) ; // this parameter are not given for all events EventMouseButton button = 0 ; UInt32 clickCount = 0 ; cEvent.GetParameter<EventMouseButton>( kEventParamMouseButton, typeMouseButton , &button ) ; cEvent.GetParameter<UInt32>( kEventParamClickCount, typeUInt32 , &clickCount ) ; wxevent.m_x = screenMouseLocation.h; wxevent.m_y = screenMouseLocation.v; wxevent.m_shiftDown = modifiers & shiftKey; wxevent.m_controlDown = modifiers & controlKey; wxevent.m_altDown = modifiers & optionKey; wxevent.m_metaDown = modifiers & cmdKey; wxevent.SetTimestamp( cEvent.GetTicks() ) ; // a control click is interpreted as a right click if ( button == kEventMouseButtonPrimary && (modifiers & controlKey) ) button = kEventMouseButtonSecondary ; // otherwise we report double clicks by connecting a left click with a ctrl-left click if ( clickCount > 1 && button != g_lastButton ) clickCount = 1 ; // we must make sure that our synthetic 'right' button corresponds in // mouse down, moved and mouse up, and does not deliver a right down and left up if ( cEvent.GetKind() == kEventMouseDown ) g_lastButton = button ; if ( button == 0 ) g_lastButton = 0 ; else if ( g_lastButton ) button = g_lastButton ; // determine the correct down state, wx does not want a 'down' for a mouseUp event, // while mac delivers this button if ( button != 0 && cEvent.GetKind() != kEventMouseUp ) { switch ( button ) { case kEventMouseButtonPrimary : wxevent.m_leftDown = true ; break ; case kEventMouseButtonSecondary : wxevent.m_rightDown = true ; break ; case kEventMouseButtonTertiary : wxevent.m_middleDown = true ; break ; default: break ; } } // translate into wx types switch ( cEvent.GetKind() ) { case kEventMouseDown : switch ( button ) { case kEventMouseButtonPrimary : wxevent.SetEventType( clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ; break ; case kEventMouseButtonSecondary : wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ; break ; case kEventMouseButtonTertiary : wxevent.SetEventType( clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ; break ; default: break ; } break ; case kEventMouseUp : switch ( button ) { case kEventMouseButtonPrimary : wxevent.SetEventType( wxEVT_LEFT_UP ) ; break ; case kEventMouseButtonSecondary : wxevent.SetEventType( wxEVT_RIGHT_UP ) ; break ; case kEventMouseButtonTertiary : wxevent.SetEventType( wxEVT_MIDDLE_UP ) ; break ; default: break ; } break ; case kEventMouseWheelMoved : { wxevent.SetEventType( wxEVT_MOUSEWHEEL ) ; // EventMouseWheelAxis axis = cEvent.GetParameter<EventMouseWheelAxis>(kEventParamMouseWheelAxis, typeMouseWheelAxis) ; SInt32 delta = cEvent.GetParameter<SInt32>(kEventParamMouseWheelDelta, typeSInt32) ; wxevent.m_wheelRotation = delta; wxevent.m_wheelDelta = 1; wxevent.m_linesPerAction = 1; } break ; default : wxevent.SetEventType( wxEVT_MOTION ) ; break ; }}ControlRef wxMacFindSubControl( wxTopLevelWindowMac* toplevelWindow, const Point& location , ControlRef superControl , ControlPartCode *outPart ){ if ( superControl ) { UInt16 childrenCount = 0 ; ControlHandle sibling ; Rect r ; OSStatus err = CountSubControls( superControl , &childrenCount ) ; if ( err == errControlIsNotEmbedder ) return NULL ; wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ; for ( UInt16 i = childrenCount ; i >=1 ; --i ) { err = GetIndexedSubControl( superControl , i , & sibling ) ; if ( err == errControlIsNotEmbedder ) return NULL ; wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ; if ( IsControlVisible( sibling ) ) { UMAGetControlBoundsInWindowCoords( sibling , &r ) ; if ( MacPtInRect( location , &r ) ) { ControlHandle child = wxMacFindSubControl( toplevelWindow , location , sibling , outPart ) ; if ( child ) { return child ; } else { Point testLocation = location ; if ( toplevelWindow ) { testLocation.h -= r.left ; testLocation.v -= r.top ; } *outPart = TestControl( sibling , testLocation ) ; return sibling ; } } } } } return NULL ;}ControlRef wxMacFindControlUnderMouse( wxTopLevelWindowMac* toplevelWindow , const Point& location , WindowRef window , ControlPartCode *outPart ){#if TARGET_API_MAC_OSX if ( UMAGetSystemVersion() >= 0x1030 ) return FindControlUnderMouse( location , window , outPart ) ;#endif ControlRef rootControl = NULL ; verify_noerr( GetRootControl( window , &rootControl ) ) ; return wxMacFindSubControl( toplevelWindow , location , rootControl , outPart ) ;}#define NEW_CAPTURE_HANDLING 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -