📄 app.cpp
字号:
const char *theLibPath;
gSharedLibraryBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.wxwindows.wxWidgets"));
if (gSharedLibraryBundle != NULL) {
// wxWidgets has been bundled into a framework
// load the framework resources
gSharedLibraryResource = CFBundleOpenBundleResourceMap(gSharedLibraryBundle);
}
else {
// wxWidgets is a simple dynamic shared library
// load the resources from the data fork of a separate resource file
wxString theResPath;
wxString theName;
FSRef theResRef;
OSErr theErr = noErr;
// get the library path
theSymbol = NSLookupAndBindSymbol("_gSharedLibraryResource");
theModule = NSModuleForSymbol(theSymbol);
theLibPath = NSLibraryNameForModule(theModule);
// if we call wxLogDebug from here then, as wxTheApp hasn't been
// created yet when we're called from wxApp::Initialize(), wxLog
// is going to create a default stderr-based log target instead of
// the expected normal GUI one -- don't do it, if we really want
// to see this message just use fprintf() here
#if 0
wxLogDebug( wxT("wxMac library installation name is '%s'"),
theLibPath );
#endif
// allocate copy to replace .dylib.* extension with .rsrc
if (theLibPath != NULL) {
#if wxUSE_UNICODE
theResPath = wxString(theLibPath, wxConvLocal);
#else
theResPath = wxString(theLibPath);
#endif
// replace '_core' with '' in case of multi-lib build
theResPath.Replace(wxT("_core"), wxEmptyString);
// replace ".dylib" shared library extension with ".rsrc"
theResPath.Replace(wxT(".dylib"), wxT(".rsrc"));
// Find the begining of the filename
theName = theResPath.AfterLast('/');
#if 0
wxLogDebug( wxT("wxMac resources file name is '%s'"),
theResPath.mb_str() );
#endif
theErr = FSPathMakeRef((UInt8 *) theResPath.mb_str(), &theResRef, false);
if (theErr != noErr) {
// try in current directory (using name only)
theErr = FSPathMakeRef((UInt8 *) theName.mb_str(), &theResRef, false);
}
// open the resource file
if (theErr == noErr) {
theErr = FSOpenResourceFile( &theResRef, 0, NULL, fsRdPerm,
&gSharedLibraryResource);
}
if (theErr != noErr) {
#ifdef __WXDEBUG__
wxLogDebug( wxT("unable to open wxMac resource file '%s'\n"),
theResPath.mb_str() );
#endif // __WXDEBUG__
}
}
}
#endif /* __DARWIN__ */
}
#endif /* WXMAKINGDLL_CORE */
}
void wxStAppResource::CloseSharedLibraryResource()
{
#ifdef WXMAKINGDLL_CORE
// Close the shared library resource file
if (gSharedLibraryResource != kResFileNotOpened) {
#ifdef __DARWIN__
if (gSharedLibraryBundle != NULL) {
CFBundleCloseBundleResourceMap(gSharedLibraryBundle,
gSharedLibraryResource);
gSharedLibraryBundle = NULL;
}
else
#endif /* __DARWIN__ */
{
CloseResFile(gSharedLibraryResource);
}
gSharedLibraryResource = kResFileNotOpened;
}
#endif /* WXMAKINGDLL_CORE */
}
#if defined(WXMAKINGDLL_CORE) && !defined(__DARWIN__)
// for shared libraries we have to manually get the correct resource
// ref num upon initializing and releasing when terminating, therefore
// the __wxinitialize and __wxterminate must be used
extern "C" {
void __sinit(void); /* (generated by linker) */
pascal OSErr __initialize(const CFragInitBlock *theInitBlock);
pascal void __terminate(void);
}
pascal OSErr __wxinitialize(const CFragInitBlock *theInitBlock)
{
wxStAppResource::OpenSharedLibraryResource( theInitBlock ) ;
return __initialize( theInitBlock ) ;
}
pascal void __wxterminate(void)
{
wxStAppResource::CloseSharedLibraryResource() ;
__terminate() ;
}
#endif /* WXMAKINGDLL_CORE && !__DARWIN__ */
#if TARGET_CARBON
bool wxMacConvertEventToRecord( EventRef event , EventRecord *rec)
{
bool converted = ConvertEventRefToEventRecord( event,rec) ;
OSStatus err = noErr ;
if ( !converted )
{
switch( GetEventClass( event ) )
{
case kEventClassKeyboard :
{
converted = true ;
switch( GetEventKind(event) )
{
case kEventRawKeyDown :
rec->what = keyDown ;
break ;
case kEventRawKeyRepeat :
rec->what = autoKey ;
break ;
case kEventRawKeyUp :
rec->what = keyUp ;
break ;
case kEventRawKeyModifiersChanged :
rec->what = nullEvent ;
break ;
default :
converted = false ;
break ;
}
if ( converted )
{
UInt32 keyCode ;
unsigned char charCode ;
UInt32 modifiers ;
GetMouse( &rec->where) ;
err = GetEventParameter(event, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
err = GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
err = GetEventParameter(event, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
rec->modifiers = modifiers ;
rec->message = (keyCode << 8 ) + charCode ;
}
}
break ;
case kEventClassTextInput :
{
switch( GetEventKind( event ) )
{
case kEventTextInputUnicodeForKeyEvent :
{
EventRef rawEvent ;
err = GetEventParameter( event , kEventParamTextInputSendKeyboardEvent ,typeEventRef,NULL,sizeof(rawEvent),NULL,&rawEvent ) ;
converted = true ;
{
UInt32 keyCode ;
unsigned char charCode ;
UInt32 modifiers ;
GetMouse( &rec->where) ;
rec->what = keyDown ;
err = GetEventParameter(rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, 4, NULL, &modifiers);
err = GetEventParameter(rawEvent, kEventParamKeyCode, typeUInt32, NULL, 4, NULL, &keyCode);
err = GetEventParameter(rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, 1, NULL, &charCode);
rec->modifiers = modifiers ;
rec->message = (keyCode << 8 ) + charCode ;
}
}
break ;
default :
break ;
}
}
break ;
}
}
return converted ;
}
/*
pascal OSStatus wxMacApplicationEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
{
OSStatus result = eventNotHandledErr ;
EventRecord rec ;
switch ( GetEventClass( event ) )
{
case kEventClassKeyboard :
if ( wxMacConvertEventToRecord( event , &rec ) )
{
wxTheApp->MacHandleModifierEvents( &rec ) ;
wxTheApp->MacHandleOneEvent( &rec ) ;
result = noErr ;
}
break ;
case kEventClassTextInput :
if ( wxMacConvertEventToRecord( event , &rec ) )
{
wxTheApp->MacHandleModifierEvents( &rec ) ;
wxTheApp->MacHandleOneEvent( &rec ) ;
result = noErr ;
}
break ;
default :
break ;
}
return result ;
}
*/
#endif
wxApp::wxApp()
{
m_printMode = wxPRINT_WINDOWS;
m_auto3D = true;
m_macCurrentEvent = NULL ;
#if TARGET_CARBON
m_macCurrentEventHandlerCallRef = NULL ;
#endif
}
int wxApp::MainLoop()
{
m_keepGoing = true;
while (m_keepGoing)
{
MacDoOneEvent() ;
}
return 0;
}
void wxApp::ExitMainLoop()
{
m_keepGoing = false;
}
// Is a message/event pending?
bool wxApp::Pending()
{
#if TARGET_CARBON
// without the receive event (with pull param = false ) nothing is ever reported
EventRef theEvent;
ReceiveNextEvent (0, NULL, kEventDurationNoWait, false, &theEvent);
return GetNumEventsInQueue( GetMainEventQueue() ) > 0 ;
#else
EventRecord event ;
return EventAvail( everyEvent , &event ) ;
#endif
}
// Dispatch a message.
bool wxApp::Dispatch()
{
MacDoOneEvent() ;
return true;
}
void wxApp::OnIdle(wxIdleEvent& event)
{
wxAppBase::OnIdle(event);
// If they are pending events, we must process them: pending events are
// either events to the threads other than main or events posted with
// wxPostEvent() functions
wxMacProcessNotifierAndPendingEvents();
if(!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
}
void wxApp::WakeUpIdle()
{
wxMacWakeUp() ;
}
void wxApp::Exit()
{
wxApp::CleanUp();
::ExitToShell() ;
}
void wxApp::OnEndSession(wxCloseEvent& WXUNUSED(event))
{
if (GetTopWindow())
GetTopWindow()->Close(true);
}
// Default behaviour: close the application with prompts. The
// user can veto the close, and therefore the end session.
void wxApp::OnQueryEndSession(wxCloseEvent& event)
{
if (GetTopWindow())
{
if (!GetTopWindow()->Close(!event.CanVeto()))
event.Veto(true);
}
}
extern "C" void wxCYield() ;
void wxCYield()
{
wxYield() ;
}
// Yield to other processes
bool wxApp::Yield(bool onlyIfNeeded)
{
if (s_inYield)
{
if ( !onlyIfNeeded )
{
wxFAIL_MSG( wxT("wxYield called recursively" ) );
}
return false;
}
s_inYield = true;
#if wxUSE_THREADS
YieldToAnyThread() ;
#endif
// by definition yield should handle all non-processed events
#if TARGET_CARBON
EventRef theEvent;
OSStatus status = noErr ;
do
{
s_inReceiveEvent = true ;
status = ReceiveNextEvent(0, NULL,kEventDurationNoWait,true,&theEvent) ;
s_inReceiveEvent = false ;
if ( status == eventLoopTimedOutErr )
{
// make sure next time the event loop will trigger idle events
sleepTime = kEventDurationNoWait ;
}
else if ( status == eventLoopQuitErr )
{
// according to QA1061 this may also occur when a WakeUp Process
// is executed
}
else
{
MacHandleOneEvent( theEvent ) ;
ReleaseEvent(theEvent);
}
} while( status == noErr ) ;
#else
EventRecord event ;
// having a larger value here leads to large performance slowdowns
// so we cannot give background apps more processor time here
// we do so however having a large sleep value in the main event loop
sleepTime = 0 ;
while ( !IsExiting() && WaitNextEvent(everyEvent, &event,sleepTime, (RgnHandle) wxApp::s_macCursorRgn))
{
MacHandleModifierEvents( &event ) ;
MacHandleOneEvent( &event );
if ( event.what != kHighLevelEvent )
SetRectRgn( (RgnHandle) wxApp::s_macCursorRgn , event.where.h , event.where.v , event.where.h + 1 , event.where.v + 1 ) ;
}
MacHandleModifierEvents( &event ) ;
#endif
wxMacProcessNotifierAndPendingEvents() ;
s_inYield = false;
return true;
}
// platform specifics
void wxApp::MacSuspend( bool convertClipboard )
{
#if !TARGET_CARBON
// we have to deactive the top level windows manually
wxWindowListNode* node = wxTopLevelWindows.GetFirst();
while (node)
{
wxTopLevelWindow* win = (wxTopLevelWindow*) node->Data();
#if TARGET_CARBON
#if 0 // having problems right now with that
if (!win->HasFlag(wxSTAY_ON_TOP))
#endif
#endif
win->MacActivate( ((EventRecord*) MacGetCurrentEvent())->when , false ) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -