1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/app.cpp
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
20 #include "wx/window.h"
23 #include "wx/button.h"
27 #include "wx/palette.h"
29 #include "wx/cursor.h"
30 #include "wx/dialog.h"
31 #include "wx/msgdlg.h"
32 #include "wx/textctrl.h"
33 #include "wx/memory.h"
34 #include "wx/gdicmn.h"
35 #include "wx/module.h"
38 #include "wx/tooltip.h"
39 #include "wx/docview.h"
40 #include "wx/filename.h"
42 #include "wx/thread.h"
43 #include "wx/evtloop.h"
49 #include "wx/osx/uma.h"
51 #include "wx/osx/private.h"
54 #if defined(WXMAKINGDLL_CORE)
55 # include <mach-o/dyld.h>
58 // Keep linker from discarding wxStockGDIMac
59 wxFORCE_LINK_MODULE(gdiobj
)
61 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
62 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
63 EVT_IDLE(wxApp::OnIdle
)
64 EVT_END_SESSION(wxApp::OnEndSession
)
65 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
69 // platform specific static variables
70 static const short kwxMacAppleMenuId
= 1 ;
72 wxWindow
* wxApp::s_captureWindow
= NULL
;
73 long wxApp::s_lastModifiers
= 0 ;
75 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
76 long wxApp::s_macPreferencesMenuItemId
= wxID_PREFERENCES
;
77 long wxApp::s_macExitMenuItemId
= wxID_EXIT
;
78 wxString
wxApp::s_macHelpMenuTitleName
= wxT("&Help") ;
80 bool wxApp::sm_isEmbedded
= false; // Normally we're not a plugin
84 //----------------------------------------------------------------------
85 // Core Apple Event Support
86 //----------------------------------------------------------------------
88 AEEventHandlerUPP sODocHandler
= NULL
;
89 AEEventHandlerUPP sGURLHandler
= NULL
;
90 AEEventHandlerUPP sOAppHandler
= NULL
;
91 AEEventHandlerUPP sPDocHandler
= NULL
;
92 AEEventHandlerUPP sRAppHandler
= NULL
;
93 AEEventHandlerUPP sQuitHandler
= NULL
;
95 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
96 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
97 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
98 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
99 pascal OSErr
AEHandleRApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
100 pascal OSErr
AEHandleGURL( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
102 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
104 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
107 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
109 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
112 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
114 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
117 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
119 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
122 pascal OSErr
AEHandleRApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
124 return wxTheApp
->MacHandleAERApp( (AppleEvent
*) event
, reply
) ;
127 pascal OSErr
AEHandleGURL( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
129 return wxTheApp
->MacHandleAEGURL((WXEVENTREF
*)event
, reply
) ;
133 // AEODoc Calls MacOpenFiles with all of the files passed
135 short wxApp::MacHandleAEODoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
139 DescType returnedType
;
145 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
149 err
= AECountItems(&docList
, &itemsInList
);
153 ProcessSerialNumber PSN
;
154 PSN
.highLongOfPSN
= 0 ;
155 PSN
.lowLongOfPSN
= kCurrentProcess
;
156 SetFrontProcess( &PSN
) ;
161 wxArrayString fileNames
;
162 for (i
= 1; i
<= itemsInList
; i
++)
165 &docList
, i
, typeFSRef
, &keywd
, &returnedType
,
166 (Ptr
)&theRef
, sizeof(theRef
), &actualSize
);
171 fName
= wxMacFSRefToPath( &theRef
) ;
173 fileNames
.Add(fName
);
176 MacOpenFiles(fileNames
);
181 // AEODoc Calls MacOpenURL on the url passed
183 short wxApp::MacHandleAEGURL(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
185 DescType returnedType
;
188 OSErr err
= AEGetParamPtr((AppleEvent
*)event
, keyDirectObject
, typeChar
,
189 &returnedType
, url
, sizeof(url
)-1,
194 url
[actualSize
] = '\0'; // Terminate the C string
196 ProcessSerialNumber PSN
;
197 PSN
.highLongOfPSN
= 0 ;
198 PSN
.lowLongOfPSN
= kCurrentProcess
;
199 SetFrontProcess( &PSN
) ;
201 MacOpenURL(wxString(url
, wxConvUTF8
));
206 // AEPDoc Calls MacPrintFile on each of the files passed
208 short wxApp::MacHandleAEPDoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
212 DescType returnedType
;
218 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
222 err
= AECountItems(&docList
, &itemsInList
);
226 ProcessSerialNumber PSN
;
227 PSN
.highLongOfPSN
= 0 ;
228 PSN
.lowLongOfPSN
= kCurrentProcess
;
229 SetFrontProcess( &PSN
) ;
234 for (i
= 1; i
<= itemsInList
; i
++)
237 &docList
, i
, typeFSRef
, &keywd
, &returnedType
,
238 (Ptr
)&theRef
, sizeof(theRef
), &actualSize
);
243 fName
= wxMacFSRefToPath( &theRef
) ;
251 // AEOApp calls MacNewFile
253 short wxApp::MacHandleAEOApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
259 // AEQuit attempts to quit the application
261 short wxApp::MacHandleAEQuit(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
264 wxTheApp
->OnQueryEndSession(event
);
265 if ( !event
.GetVeto() )
268 wxTheApp
->OnEndSession(event
);
273 // AEROApp calls MacReopenApp
275 short wxApp::MacHandleAERApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
284 //----------------------------------------------------------------------
285 // Support Routines linking the Mac...File Calls to the Document Manager
286 //----------------------------------------------------------------------
288 void wxApp::MacOpenFiles(const wxArrayString
& fileNames
)
291 const size_t fileCount
= fileNames
.GetCount();
292 for (i
= 0; i
< fileCount
; i
++)
294 MacOpenFile(fileNames
[i
]);
298 void wxApp::MacOpenFile(const wxString
& fileName
)
300 #if wxUSE_DOC_VIEW_ARCHITECTURE
301 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
303 dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
307 void wxApp::MacOpenURL(const wxString
& WXUNUSED(url
) )
311 void wxApp::MacPrintFile(const wxString
& fileName
)
313 #if wxUSE_DOC_VIEW_ARCHITECTURE
315 #if wxUSE_PRINTING_ARCHITECTURE
316 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
319 wxDocument
*doc
= dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
322 wxView
* view
= doc
->GetFirstView() ;
325 wxPrintout
*printout
= view
->OnCreatePrintout();
329 printer
.Print(view
->GetFrame(), printout
, true);
336 doc
->DeleteAllViews();
337 dm
->RemoveDocument(doc
) ;
348 void wxApp::MacNewFile()
352 void wxApp::MacReopenApp()
355 // if there is no open window -> create a new one
356 // if all windows are hidden -> show the first
357 // if some windows are not hidden -> do nothing
359 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetFirst();
366 wxTopLevelWindow
* firstIconized
= NULL
;
367 wxTopLevelWindow
* firstHidden
= NULL
;
370 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->GetData();
371 if ( !win
->IsShown() )
373 // make sure we don't show 'virtual toplevel windows' like wxTaskBarIconWindow
374 if ( firstHidden
== NULL
&& ( wxDynamicCast( win
, wxFrame
) || wxDynamicCast( win
, wxDialog
) ) )
377 else if ( win
->IsIconized() )
379 if ( firstIconized
== NULL
)
380 firstIconized
= win
;
384 // we do have a visible, non-iconized toplevelwindow -> do nothing
388 node
= node
->GetNext();
392 firstIconized
->Iconize( false ) ;
394 // showing hidden windows is not really always a good solution, also non-modal dialogs when closed end up
395 // as hidden tlws, we don't want to reshow those, so let's just reopen the minimized a.k.a. iconized tlws
396 // unless we find a regression ...
398 else if ( firstHidden
)
399 firstHidden
->Show( true );
404 #if wxOSX_USE_COCOA_OR_IPHONE
405 void wxApp::OSXOnWillFinishLaunching()
410 void wxApp::OSXOnDidFinishLaunching()
412 wxTheApp
->OnLaunched();
415 void wxApp::OSXOnWillTerminate()
418 event
.SetCanVeto(false);
419 wxTheApp
->OnEndSession(event
);
424 bool wxApp::OSXOnShouldTerminate()
427 wxTheApp
->OnQueryEndSession(event
);
428 return !event
.GetVeto();
432 //----------------------------------------------------------------------
433 // Macintosh CommandID support - converting between native and wx IDs
434 //----------------------------------------------------------------------
436 // if no native match they just return the passed-in id
446 IdPair gCommandIds
[] =
448 { kHICommandCut
, wxID_CUT
} ,
449 { kHICommandCopy
, wxID_COPY
} ,
450 { kHICommandPaste
, wxID_PASTE
} ,
451 { kHICommandSelectAll
, wxID_SELECTALL
} ,
452 { kHICommandClear
, wxID_CLEAR
} ,
453 { kHICommandUndo
, wxID_UNDO
} ,
454 { kHICommandRedo
, wxID_REDO
} ,
457 int wxMacCommandToId( UInt32 macCommandId
)
461 switch ( macCommandId
)
463 case kHICommandPreferences
:
464 wxid
= wxApp::s_macPreferencesMenuItemId
;
467 case kHICommandQuit
:
468 wxid
= wxApp::s_macExitMenuItemId
;
471 case kHICommandAbout
:
472 wxid
= wxApp::s_macAboutMenuItemId
;
477 for ( size_t i
= 0 ; i
< WXSIZEOF(gCommandIds
) ; ++i
)
479 if ( gCommandIds
[i
].macId
== macCommandId
)
481 wxid
= gCommandIds
[i
].wxId
;
490 wxid
= (int) macCommandId
;
495 UInt32
wxIdToMacCommand( int wxId
)
499 if ( wxId
== wxApp::s_macPreferencesMenuItemId
)
500 macId
= kHICommandPreferences
;
501 else if (wxId
== wxApp::s_macExitMenuItemId
)
502 macId
= kHICommandQuit
;
503 else if (wxId
== wxApp::s_macAboutMenuItemId
)
504 macId
= kHICommandAbout
;
507 for ( size_t i
= 0 ; i
< WXSIZEOF(gCommandIds
) ; ++i
)
509 if ( gCommandIds
[i
].wxId
== wxId
)
511 macId
= gCommandIds
[i
].macId
;
523 wxMenu
* wxFindMenuFromMacCommand( const HICommand
&command
, wxMenuItem
* &item
)
525 wxMenu
* itemMenu
= NULL
;
526 #ifndef __WXUNIVERSAL__
529 // for 'standard' commands which don't have a wx-menu
530 if ( command
.commandID
== kHICommandPreferences
|| command
.commandID
== kHICommandQuit
|| command
.commandID
== kHICommandAbout
)
532 id
= wxMacCommandToId( command
.commandID
) ;
534 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
536 item
= mbar
->FindItem( id
, &itemMenu
) ;
538 else if ( command
.commandID
!= 0 && command
.menu
.menuRef
!= 0 && command
.menu
.menuItemIndex
!= 0 )
540 id
= wxMacCommandToId( command
.commandID
) ;
541 // make sure it is one of our own menus, or of the 'synthetic' apple and help menus , otherwise don't touch
542 MenuItemIndex firstUserHelpMenuItem
;
543 static MenuHandle helpMenuHandle
= NULL
;
544 if ( helpMenuHandle
== NULL
)
546 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle
, &firstUserHelpMenuItem
) != noErr
)
547 helpMenuHandle
= NULL
;
550 // is it part of the application or the Help menu, then look for the id directly
551 if ( ( GetMenuHandle( kwxMacAppleMenuId
) != NULL
&& command
.menu
.menuRef
== GetMenuHandle( kwxMacAppleMenuId
) ) ||
552 ( helpMenuHandle
!= NULL
&& command
.menu
.menuRef
== helpMenuHandle
) ||
553 wxMenuBar::MacGetWindowMenuHMenu() != NULL
&& command
.menu
.menuRef
== wxMenuBar::MacGetWindowMenuHMenu() )
555 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
557 item
= mbar
->FindItem( id
, &itemMenu
) ;
563 GetMenuItemRefCon( command
.menu
.menuRef
, command
.menu
.menuItemIndex
, &refCon
) ;
564 itemMenu
= wxFindMenuFromMacMenu( command
.menu
.menuRef
) ;
565 if ( itemMenu
!= NULL
&& refCon
!= 0)
566 item
= (wxMenuItem
*) refCon
;
575 //----------------------------------------------------------------------
576 // Carbon Event Handler
577 //----------------------------------------------------------------------
581 static const EventTypeSpec eventList
[] =
583 { kEventClassCommand
, kEventProcessCommand
} ,
584 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
586 { kEventClassMenu
, kEventMenuOpening
},
587 { kEventClassMenu
, kEventMenuClosed
},
588 { kEventClassMenu
, kEventMenuTargetItem
},
590 { kEventClassApplication
, kEventAppActivated
} ,
591 { kEventClassApplication
, kEventAppDeactivated
} ,
592 // handling the quit event is not recommended by apple
593 // rather using the quit apple event - which we do
595 { kEventClassAppleEvent
, kEventAppleEvent
} ,
597 { kEventClassMouse
, kEventMouseDown
} ,
598 { kEventClassMouse
, kEventMouseMoved
} ,
599 { kEventClassMouse
, kEventMouseUp
} ,
600 { kEventClassMouse
, kEventMouseDragged
} ,
604 static pascal OSStatus
605 wxMacAppMenuEventHandler( EventHandlerCallRef
WXUNUSED(handler
),
607 void *WXUNUSED(data
) )
609 wxMacCarbonEvent
cEvent( event
) ;
610 MenuRef menuRef
= cEvent
.GetParameter
<MenuRef
>(kEventParamDirectObject
) ;
611 #ifndef __WXUNIVERSAL__
612 wxMenu
* menu
= wxFindMenuFromMacMenu( menuRef
) ;
616 switch (GetEventKind(event
))
618 case kEventMenuOpening
:
619 menu
->HandleMenuOpened();
622 case kEventMenuClosed
:
623 menu
->HandleMenuClosed();
626 case kEventMenuTargetItem
:
630 command
.menu
.menuRef
= menuRef
;
631 command
.menu
.menuItemIndex
= cEvent
.GetParameter
<MenuItemIndex
>(kEventParamMenuItemIndex
,typeMenuItemIndex
) ;
632 command
.commandID
= cEvent
.GetParameter
<MenuCommand
>(kEventParamMenuCommand
,typeMenuCommand
) ;
633 if (command
.commandID
!= 0)
635 wxMenuItem
* item
= NULL
;
636 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
637 if ( itemMenu
&& item
)
638 itemMenu
->HandleMenuItemHighlighted( item
);
644 wxFAIL_MSG(wxT("Unexpected menu event kind"));
650 return eventNotHandledErr
;
653 static pascal OSStatus
654 wxMacAppCommandEventHandler( EventHandlerCallRef
WXUNUSED(handler
) ,
656 void *WXUNUSED(data
) )
658 OSStatus result
= eventNotHandledErr
;
662 wxMacCarbonEvent
cEvent( event
) ;
663 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
665 wxMenuItem
* item
= NULL
;
666 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
670 wxASSERT( itemMenu
!= NULL
) ;
672 switch ( cEvent
.GetKind() )
674 case kEventProcessCommand
:
675 if ( itemMenu
->HandleCommandProcess( item
) )
679 case kEventCommandUpdateStatus
:
680 if ( itemMenu
->HandleCommandUpdateStatus( item
) )
691 static pascal OSStatus
692 wxMacAppApplicationEventHandler( EventHandlerCallRef
WXUNUSED(handler
) ,
694 void *WXUNUSED(data
) )
696 OSStatus result
= eventNotHandledErr
;
697 switch ( GetEventKind( event
) )
699 case kEventAppActivated
:
701 wxTheApp
->SetActive( true , NULL
) ;
705 case kEventAppDeactivated
:
707 wxTheApp
->SetActive( false , NULL
) ;
718 pascal OSStatus
wxMacAppEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
720 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
721 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
722 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
724 OSStatus result
= eventNotHandledErr
;
725 switch ( GetEventClass( event
) )
728 case kEventClassCommand
:
729 result
= wxMacAppCommandEventHandler( handler
, event
, data
) ;
732 case kEventClassApplication
:
733 result
= wxMacAppApplicationEventHandler( handler
, event
, data
) ;
736 case kEventClassMenu
:
737 result
= wxMacAppMenuEventHandler( handler
, event
, data
) ;
740 case kEventClassMouse
:
742 wxMacCarbonEvent
cEvent( event
) ;
745 Point screenMouseLocation
= cEvent
.GetParameter
<Point
>(kEventParamMouseLocation
) ;
746 ::FindWindow(screenMouseLocation
, &window
);
747 // only send this event in case it had not already been sent to a tlw, as we get
748 // double events otherwise (in case event.skip) was called
749 if ( window
== NULL
)
750 result
= wxMacTopLevelMouseEventHandler( handler
, event
, NULL
) ;
754 case kEventClassAppleEvent
:
755 result
= AEProcessEvent(event
);
762 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
767 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler
)
770 #if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
773 wxMacAssertOutputHandler(OSType
WXUNUSED(componentSignature
),
774 UInt32
WXUNUSED(options
),
775 const char *assertionString
,
776 const char *exceptionLabelString
,
777 const char *errorString
,
778 const char *fileName
,
781 ConstStr255Param
WXUNUSED(outputMsg
))
783 // flow into assert handling
784 wxString fileNameStr
;
785 wxString assertionStr
;
786 wxString exceptionStr
;
790 fileNameStr
= wxString(fileName
, wxConvLocal
);
791 assertionStr
= wxString(assertionString
, wxConvLocal
);
792 exceptionStr
= wxString((exceptionLabelString
!=0) ? exceptionLabelString
: "", wxConvLocal
) ;
793 errorStr
= wxString((errorString
!=0) ? errorString
: "", wxConvLocal
) ;
795 fileNameStr
= fileName
;
796 assertionStr
= assertionString
;
797 exceptionStr
= (exceptionLabelString
!=0) ? exceptionLabelString
: "" ;
798 errorStr
= (errorString
!=0) ? errorString
: "" ;
803 wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"),
804 assertionStr
.c_str() ,
805 exceptionStr
.c_str() ,
807 fileNameStr
.c_str(), lineNumber
,
811 wxOnAssert(fileNameStr
, lineNumber
, assertionStr
,
812 wxString::Format( wxT("%s %s value (%p)") , exceptionStr
, errorStr
, value
) ) ;
816 #endif // wxDEBUG_LEVEL
818 bool wxApp::Initialize(int& argc
, wxChar
**argv
)
822 #if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
823 InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler
) );
826 // Mac OS X passes a process serial number command line argument when
827 // the application is launched from the Finder. This argument must be
828 // removed from the command line arguments before being handled by the
829 // application (otherwise applications would need to handle it)
832 static const wxChar
*ARG_PSN
= wxT("-psn_");
833 if ( wxStrncmp(argv
[1], ARG_PSN
, wxStrlen(ARG_PSN
)) == 0 )
835 // remove this argument
837 memmove(argv
+ 1, argv
+ 2, argc
* sizeof(wxChar
*));
842 Cocoa supports -Key value options which set the user defaults key "Key"
843 to the value "value" Some of them are very handy for debugging like
844 -NSShowAllViews YES. Cocoa picks these up from the real argv so
845 our removal of them from the wx copy of it does not affect Cocoa's
848 We basically just assume that any "-NS" option and its following
849 argument needs to be removed from argv. We hope that user code does
850 not expect to see -NS options and indeed it's probably a safe bet
851 since most user code accepting options is probably using the
852 double-dash GNU-style syntax.
854 for(int i
=1; i
< argc
; ++i
)
856 static const wxChar
*ARG_NS
= wxT("-NS");
857 if( wxStrncmp(argv
[i
], ARG_NS
, wxStrlen(ARG_NS
)) == 0 )
859 // Only eat this option if it has an argument
862 memmove(argv
+ i
, argv
+ i
+ 2, (argc
-i
-1)*sizeof(wxChar
*));
864 // drop back one position so the next run through the loop
865 // reprocesses the argument at our current index.
871 if ( !wxAppBase::Initialize(argc
, argv
) )
875 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
878 // these might be the startup dirs, set them to the 'usual' dir containing the app bundle
879 wxString startupCwd
= wxGetCwd() ;
880 if ( startupCwd
== wxT("/") || startupCwd
.Right(15) == wxT("/Contents/MacOS") )
882 CFURLRef url
= CFBundleCopyBundleURL(CFBundleGetMainBundle() ) ;
883 CFURLRef urlParent
= CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault
, url
) ;
885 CFStringRef path
= CFURLCopyFileSystemPath ( urlParent
, kCFURLPOSIXPathStyle
) ;
886 CFRelease( urlParent
) ;
887 wxString cwd
= wxCFStringRef(path
).AsString(wxLocale::GetSystemEncoding());
888 wxSetWorkingDirectory( cwd
) ;
894 #if wxOSX_USE_COCOA_OR_CARBON
895 bool wxApp::CallOnInit()
897 wxMacAutoreleasePool autoreleasepool
;
902 bool wxApp::OnInitGui()
904 if ( !wxAppBase::OnInitGui() )
913 bool wxApp::ProcessIdle()
915 wxMacAutoreleasePool autoreleasepool
;
916 return wxAppBase::ProcessIdle();
921 wxMacAutoreleasePool pool
;
922 return wxAppBase::OnRun();
926 bool wxApp::DoInitGui()
928 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
931 InstallApplicationEventHandler(
932 GetwxMacAppEventHandlerUPP(),
933 GetEventTypeCount(eventList
), eventList
, wxTheApp
, (EventHandlerRef
*)&(wxTheApp
->m_macEventHandler
));
938 sODocHandler
= NewAEEventHandlerUPP(AEHandleODoc
) ;
939 sGURLHandler
= NewAEEventHandlerUPP(AEHandleGURL
) ;
940 sOAppHandler
= NewAEEventHandlerUPP(AEHandleOApp
) ;
941 sPDocHandler
= NewAEEventHandlerUPP(AEHandlePDoc
) ;
942 sRAppHandler
= NewAEEventHandlerUPP(AEHandleRApp
) ;
943 sQuitHandler
= NewAEEventHandlerUPP(AEHandleQuit
) ;
945 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
946 sODocHandler
, 0 , FALSE
) ;
947 AEInstallEventHandler( kInternetEventClass
, kAEGetURL
,
948 sGURLHandler
, 0 , FALSE
) ;
949 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
950 sOAppHandler
, 0 , FALSE
) ;
951 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
952 sPDocHandler
, 0 , FALSE
) ;
953 AEInstallEventHandler( kCoreEventClass
, kAEReopenApplication
,
954 sRAppHandler
, 0 , FALSE
) ;
955 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
956 sQuitHandler
, 0 , FALSE
) ;
959 if ( !wxMacInitCocoa() )
965 void wxApp::DoCleanUp()
968 RemoveEventHandler( (EventHandlerRef
)(wxTheApp
->m_macEventHandler
) );
972 AERemoveEventHandler( kCoreEventClass
, kAEOpenDocuments
,
973 sODocHandler
, FALSE
) ;
974 AERemoveEventHandler( kInternetEventClass
, kAEGetURL
,
975 sGURLHandler
, FALSE
) ;
976 AERemoveEventHandler( kCoreEventClass
, kAEOpenApplication
,
977 sOAppHandler
, FALSE
) ;
978 AERemoveEventHandler( kCoreEventClass
, kAEPrintDocuments
,
979 sPDocHandler
, FALSE
) ;
980 AERemoveEventHandler( kCoreEventClass
, kAEReopenApplication
,
981 sRAppHandler
, FALSE
) ;
982 AERemoveEventHandler( kCoreEventClass
, kAEQuitApplication
,
983 sQuitHandler
, FALSE
) ;
985 DisposeAEEventHandlerUPP( sODocHandler
) ;
986 DisposeAEEventHandlerUPP( sGURLHandler
) ;
987 DisposeAEEventHandlerUPP( sOAppHandler
) ;
988 DisposeAEEventHandlerUPP( sPDocHandler
) ;
989 DisposeAEEventHandlerUPP( sRAppHandler
) ;
990 DisposeAEEventHandlerUPP( sQuitHandler
) ;
996 void wxApp::CleanUp()
998 wxMacAutoreleasePool autoreleasepool
;
1000 wxToolTip::RemoveToolTips() ;
1005 wxAppBase::CleanUp();
1008 //----------------------------------------------------------------------
1009 // misc initialization stuff
1010 //----------------------------------------------------------------------
1014 m_printMode
= wxPRINT_WINDOWS
;
1016 m_macCurrentEvent
= NULL
;
1017 m_macCurrentEventHandlerCallRef
= NULL
;
1018 m_macPool
= new wxMacAutoreleasePool();
1027 CFMutableArrayRef
GetAutoReleaseArray()
1029 static CFMutableArrayRef array
= 0;
1031 array
= CFArrayCreateMutable(kCFAllocatorDefault
,0,&kCFTypeArrayCallBacks
);
1035 void wxApp::MacAddToAutorelease( void* cfrefobj
)
1037 CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj
);
1040 void wxApp::MacReleaseAutoreleasePool()
1044 m_macPool
= new wxMacAutoreleasePool();
1047 void wxApp::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1049 // If they are pending events, we must process them: pending events are
1050 // either events to the threads other than main or events posted with
1051 // wxPostEvent() functions
1052 #ifndef __WXUNIVERSAL__
1054 if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
1055 wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
1058 CFArrayRemoveAllValues( GetAutoReleaseArray() );
1061 void wxApp::WakeUpIdle()
1063 wxEventLoopBase
* const loop
= wxEventLoopBase::GetActive();
1069 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
1072 GetTopWindow()->Close(true);
1075 // Default behaviour: close the application with prompts. The
1076 // user can veto the close, and therefore the end session.
1077 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
1079 if ( !wxDialog::OSXHasModalDialogsOpen() )
1083 if (!GetTopWindow()->Close(!event
.CanVeto()))
1093 extern "C" void wxCYield() ;
1100 void wxApp::MacHandleUnhandledEvent( WXEVENTREF
WXUNUSED(evr
) )
1102 // Override to process unhandled events as you please
1105 #if wxOSX_USE_COCOA_OR_CARBON
1107 CGKeyCode
wxCharCodeWXToOSX(wxKeyCode code
)
1113 // Clang warns about switch values not of the same type as (enumerated)
1114 // switch controlling expression. This is generally useful but here we
1115 // really want to be able to use letters and digits without making them
1116 // part of wxKeyCode enum.
1118 #pragma clang diagnostic push
1119 #pragma clang diagnostic ignored "-Wswitch"
1122 case 'a': case 'A': keycode
= kVK_ANSI_A
; break;
1123 case 'b': case 'B': keycode
= kVK_ANSI_B
; break;
1124 case 'c': case 'C': keycode
= kVK_ANSI_C
; break;
1125 case 'd': case 'D': keycode
= kVK_ANSI_D
; break;
1126 case 'e': case 'E': keycode
= kVK_ANSI_E
; break;
1127 case 'f': case 'F': keycode
= kVK_ANSI_F
; break;
1128 case 'g': case 'G': keycode
= kVK_ANSI_G
; break;
1129 case 'h': case 'H': keycode
= kVK_ANSI_H
; break;
1130 case 'i': case 'I': keycode
= kVK_ANSI_I
; break;
1131 case 'j': case 'J': keycode
= kVK_ANSI_J
; break;
1132 case 'k': case 'K': keycode
= kVK_ANSI_K
; break;
1133 case 'l': case 'L': keycode
= kVK_ANSI_L
; break;
1134 case 'm': case 'M': keycode
= kVK_ANSI_M
; break;
1135 case 'n': case 'N': keycode
= kVK_ANSI_N
; break;
1136 case 'o': case 'O': keycode
= kVK_ANSI_O
; break;
1137 case 'p': case 'P': keycode
= kVK_ANSI_P
; break;
1138 case 'q': case 'Q': keycode
= kVK_ANSI_Q
; break;
1139 case 'r': case 'R': keycode
= kVK_ANSI_R
; break;
1140 case 's': case 'S': keycode
= kVK_ANSI_S
; break;
1141 case 't': case 'T': keycode
= kVK_ANSI_T
; break;
1142 case 'u': case 'U': keycode
= kVK_ANSI_U
; break;
1143 case 'v': case 'V': keycode
= kVK_ANSI_V
; break;
1144 case 'w': case 'W': keycode
= kVK_ANSI_W
; break;
1145 case 'x': case 'X': keycode
= kVK_ANSI_X
; break;
1146 case 'y': case 'Y': keycode
= kVK_ANSI_Y
; break;
1147 case 'z': case 'Z': keycode
= kVK_ANSI_Z
; break;
1149 case '0': keycode
= kVK_ANSI_0
; break;
1150 case '1': keycode
= kVK_ANSI_1
; break;
1151 case '2': keycode
= kVK_ANSI_2
; break;
1152 case '3': keycode
= kVK_ANSI_3
; break;
1153 case '4': keycode
= kVK_ANSI_4
; break;
1154 case '5': keycode
= kVK_ANSI_5
; break;
1155 case '6': keycode
= kVK_ANSI_6
; break;
1156 case '7': keycode
= kVK_ANSI_7
; break;
1157 case '8': keycode
= kVK_ANSI_8
; break;
1158 case '9': keycode
= kVK_ANSI_9
; break;
1161 #pragma clang diagnostic pop
1164 case WXK_BACK
: keycode
= kVK_Delete
; break;
1165 case WXK_TAB
: keycode
= kVK_Tab
; break;
1166 case WXK_RETURN
: keycode
= kVK_Return
; break;
1167 case WXK_ESCAPE
: keycode
= kVK_Escape
; break;
1168 case WXK_SPACE
: keycode
= kVK_Space
; break;
1169 case WXK_DELETE
: keycode
= kVK_ForwardDelete
; break;
1171 case WXK_SHIFT
: keycode
= kVK_Shift
; break;
1172 case WXK_ALT
: keycode
= kVK_Option
; break;
1173 case WXK_RAW_CONTROL
: keycode
= kVK_Control
; break;
1174 case WXK_CONTROL
: keycode
= kVK_Command
; break;
1176 case WXK_CAPITAL
: keycode
= kVK_CapsLock
; break;
1177 case WXK_END
: keycode
= kVK_End
; break;
1178 case WXK_HOME
: keycode
= kVK_Home
; break;
1179 case WXK_LEFT
: keycode
= kVK_LeftArrow
; break;
1180 case WXK_UP
: keycode
= kVK_UpArrow
; break;
1181 case WXK_RIGHT
: keycode
= kVK_RightArrow
; break;
1182 case WXK_DOWN
: keycode
= kVK_DownArrow
; break;
1184 case WXK_HELP
: keycode
= kVK_Help
; break;
1187 case WXK_NUMPAD0
: keycode
= kVK_ANSI_Keypad0
; break;
1188 case WXK_NUMPAD1
: keycode
= kVK_ANSI_Keypad1
; break;
1189 case WXK_NUMPAD2
: keycode
= kVK_ANSI_Keypad2
; break;
1190 case WXK_NUMPAD3
: keycode
= kVK_ANSI_Keypad3
; break;
1191 case WXK_NUMPAD4
: keycode
= kVK_ANSI_Keypad4
; break;
1192 case WXK_NUMPAD5
: keycode
= kVK_ANSI_Keypad5
; break;
1193 case WXK_NUMPAD6
: keycode
= kVK_ANSI_Keypad6
; break;
1194 case WXK_NUMPAD7
: keycode
= kVK_ANSI_Keypad7
; break;
1195 case WXK_NUMPAD8
: keycode
= kVK_ANSI_Keypad8
; break;
1196 case WXK_NUMPAD9
: keycode
= kVK_ANSI_Keypad9
; break;
1197 case WXK_F1
: keycode
= kVK_F1
; break;
1198 case WXK_F2
: keycode
= kVK_F2
; break;
1199 case WXK_F3
: keycode
= kVK_F3
; break;
1200 case WXK_F4
: keycode
= kVK_F4
; break;
1201 case WXK_F5
: keycode
= kVK_F5
; break;
1202 case WXK_F6
: keycode
= kVK_F6
; break;
1203 case WXK_F7
: keycode
= kVK_F7
; break;
1204 case WXK_F8
: keycode
= kVK_F8
; break;
1205 case WXK_F9
: keycode
= kVK_F9
; break;
1206 case WXK_F10
: keycode
= kVK_F10
; break;
1207 case WXK_F11
: keycode
= kVK_F11
; break;
1208 case WXK_F12
: keycode
= kVK_F12
; break;
1209 case WXK_F13
: keycode
= kVK_F13
; break;
1210 case WXK_F14
: keycode
= kVK_F14
; break;
1211 case WXK_F15
: keycode
= kVK_F15
; break;
1212 case WXK_F16
: keycode
= kVK_F16
; break;
1213 case WXK_F17
: keycode
= kVK_F17
; break;
1214 case WXK_F18
: keycode
= kVK_F18
; break;
1215 case WXK_F19
: keycode
= kVK_F19
; break;
1216 case WXK_F20
: keycode
= kVK_F20
; break;
1218 case WXK_PAGEUP
: keycode
= kVK_PageUp
; break;
1219 case WXK_PAGEDOWN
: keycode
= kVK_PageDown
; break;
1221 case WXK_NUMPAD_DELETE
: keycode
= kVK_ANSI_KeypadClear
; break;
1222 case WXK_NUMPAD_EQUAL
: keycode
= kVK_ANSI_KeypadEquals
; break;
1223 case WXK_NUMPAD_MULTIPLY
: keycode
= kVK_ANSI_KeypadMultiply
; break;
1224 case WXK_NUMPAD_ADD
: keycode
= kVK_ANSI_KeypadPlus
; break;
1225 case WXK_NUMPAD_SUBTRACT
: keycode
= kVK_ANSI_KeypadMinus
; break;
1226 case WXK_NUMPAD_DECIMAL
: keycode
= kVK_ANSI_KeypadDecimal
; break;
1227 case WXK_NUMPAD_DIVIDE
: keycode
= kVK_ANSI_KeypadDivide
; break;
1230 wxLogDebug( "Unrecognised keycode %d", code
);
1231 keycode
= static_cast<CGKeyCode
>(-1);
1237 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1242 case kHomeCharCode
:
1246 case kEnterCharCode
:
1247 retval
= WXK_RETURN
;
1253 case kHelpCharCode
:
1257 case kBackspaceCharCode
:
1265 case kPageUpCharCode
:
1266 retval
= WXK_PAGEUP
;
1269 case kPageDownCharCode
:
1270 retval
= WXK_PAGEDOWN
;
1273 case kReturnCharCode
:
1274 retval
= WXK_RETURN
;
1277 case kFunctionKeyCharCode
:
1347 case kEscapeCharCode
:
1348 retval
= WXK_ESCAPE
;
1351 case kLeftArrowCharCode
:
1355 case kRightArrowCharCode
:
1356 retval
= WXK_RIGHT
;
1359 case kUpArrowCharCode
:
1363 case kDownArrowCharCode
:
1367 case kDeleteCharCode
:
1368 retval
= WXK_DELETE
;
1378 int wxMacKeyCodeToModifier(wxKeyCode key
)
1396 case WXK_RAW_CONTROL
:
1405 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
1407 // defined in utils.mm
1409 #elif wxOSX_USE_COCOA_OR_CARBON
1411 wxMouseState
wxGetMouseState()
1415 wxPoint pt
= wxGetMousePosition();
1419 UInt32 buttons
= GetCurrentButtonState();
1420 ms
.SetLeftDown( (buttons
& 0x01) != 0 );
1421 ms
.SetMiddleDown( (buttons
& 0x04) != 0 );
1422 ms
.SetRightDown( (buttons
& 0x02) != 0 );
1424 UInt32 modifiers
= GetCurrentKeyModifiers();
1425 ms
.SetRawControlDown(modifiers
& controlKey
);
1426 ms
.SetShiftDown(modifiers
& shiftKey
);
1427 ms
.SetAltDown(modifiers
& optionKey
);
1428 ms
.SetControlDown(modifiers
& cmdKey
);
1435 // TODO : once the new key/char handling is tested, move all the code to wxWindow
1437 bool wxApp::MacSendKeyDownEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1442 wxKeyEvent
event(wxEVT_KEY_DOWN
) ;
1443 MacCreateKeyEvent( event
, focus
, keymessage
, modifiers
, when
, uniChar
) ;
1445 return focus
->OSXHandleKeyEvent(event
);
1448 bool wxApp::MacSendKeyUpEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1453 wxKeyEvent
event( wxEVT_KEY_UP
) ;
1454 MacCreateKeyEvent( event
, focus
, keymessage
, modifiers
, when
, uniChar
) ;
1456 return focus
->OSXHandleKeyEvent(event
) ;
1459 bool wxApp::MacSendCharEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1463 wxKeyEvent
event(wxEVT_CHAR
) ;
1464 MacCreateKeyEvent( event
, focus
, keymessage
, modifiers
, when
, uniChar
) ;
1466 bool handled
= false ;
1468 #if wxOSX_USE_CARBON
1469 long keyval
= event
.m_keyCode
;
1472 wxKeyEvent
eventCharHook(wxEVT_CHAR_HOOK
, event
);
1473 handled
= focus
->HandleWindowEvent( eventCharHook
);
1474 if ( handled
&& eventCharHook
.IsNextEventAllowed() )
1480 handled
= focus
->HandleWindowEvent( event
) ;
1483 if ( !handled
&& (keyval
== WXK_TAB
) )
1485 wxWindow
* iter
= focus
->GetParent() ;
1486 while ( iter
&& !handled
)
1488 if ( iter
->HasFlag( wxTAB_TRAVERSAL
) )
1490 wxNavigationKeyEvent new_event
;
1491 new_event
.SetEventObject( focus
);
1492 new_event
.SetDirection( !event
.ShiftDown() );
1493 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1494 new_event
.SetWindowChange( event
.ControlDown() );
1495 new_event
.SetCurrentFocus( focus
);
1496 handled
= focus
->GetParent()->HandleWindowEvent( new_event
);
1497 if ( handled
&& new_event
.GetSkipped() )
1501 iter
= iter
->GetParent() ;
1505 // backdoor handler for default return and command escape
1506 if ( !handled
&& (!focus
->IsKindOf(CLASSINFO(wxControl
) ) || !focus
->AcceptsFocus() ) )
1508 // if window is not having a focus still testing for default enter or cancel
1509 // TODO: add the UMA version for ActiveNonFloatingWindow
1511 wxWindow
* focus
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) FrontWindow() ) ;
1514 if ( keyval
== WXK_RETURN
|| keyval
== WXK_NUMPAD_ENTER
)
1516 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(focus
), wxTopLevelWindow
);
1517 if ( tlw
&& tlw
->GetDefaultItem() )
1519 wxButton
*def
= wxDynamicCast(tlw
->GetDefaultItem(), wxButton
);
1520 if ( def
&& def
->IsEnabled() )
1522 wxCommandEvent
event(wxEVT_BUTTON
, def
->GetId() );
1523 event
.SetEventObject(def
);
1524 def
->Command(event
);
1530 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && modifiers
& cmdKey
) )
1532 // generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs)
1533 wxCommandEvent
new_event(wxEVT_BUTTON
,wxID_CANCEL
);
1534 new_event
.SetEventObject( focus
);
1535 handled
= focus
->HandleWindowEvent( new_event
);
1544 // This method handles common code for SendKeyDown, SendKeyUp, and SendChar events.
1545 void wxApp::MacCreateKeyEvent( wxKeyEvent
& event
, wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1547 #if wxOSX_USE_COCOA_OR_CARBON
1549 short keycode
, keychar
;
1551 keychar
= short(keymessage
& charCodeMask
);
1552 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1553 if ( !(event
.GetEventType() == wxEVT_CHAR
) && (modifiers
& (controlKey
| shiftKey
| optionKey
) ) )
1555 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1556 // and look at the character after
1558 // TODO new implementation using TextInputSources
1561 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
| shiftKey
| optionKey
))) | keycode
, &state
);
1562 keychar
= short(keyInfo
& charCodeMask
);
1566 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1567 if ( keyval
== keychar
&& ( event
.GetEventType() == wxEVT_KEY_UP
|| event
.GetEventType() == wxEVT_KEY_DOWN
) )
1568 keyval
= wxToupper( keyval
) ;
1570 // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the
1571 // WXK_NUMPAD constants, but for the CHAR event we want to use the
1572 // standard ascii values
1573 if ( event
.GetEventType() != wxEVT_CHAR
)
1575 if (keyval
>= '0' && keyval
<= '9' && keycode
>= 82 && keycode
<= 92)
1577 keyval
= (keyval
- '0') + WXK_NUMPAD0
;
1579 else if (keycode
>= 65 && keycode
<= 81)
1584 keyval
= WXK_NUMPAD_ENTER
;
1588 keyval
= WXK_NUMPAD_EQUAL
;
1592 keyval
= WXK_NUMPAD_MULTIPLY
;
1596 keyval
= WXK_NUMPAD_DIVIDE
;
1600 keyval
= WXK_NUMPAD_SUBTRACT
;
1604 keyval
= WXK_NUMPAD_ADD
;
1608 keyval
= WXK_NUMPAD_DECIMAL
;
1616 event
.m_shiftDown
= modifiers
& shiftKey
;
1617 event
.m_rawControlDown
= modifiers
& controlKey
;
1618 event
.m_altDown
= modifiers
& optionKey
;
1619 event
.m_controlDown
= modifiers
& cmdKey
;
1620 event
.m_keyCode
= keyval
;
1622 event
.m_uniChar
= uniChar
;
1625 event
.m_rawCode
= keymessage
;
1626 event
.m_rawFlags
= modifiers
;
1627 event
.SetTimestamp(when
);
1628 event
.SetEventObject(focus
);
1632 wxUnusedVar(keymessage
);
1633 wxUnusedVar(modifiers
);
1635 wxUnusedVar(uniChar
);
1640 void wxApp::MacHideApp()
1642 #if wxOSX_USE_CARBON
1643 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1645 memset( &command
, 0 , sizeof(command
) );
1646 command
.commandID
= kHICommandHide
;
1647 event
.SetParameter
<HICommand
>(kEventParamDirectObject
, command
);
1648 SendEventToApplication( event
);