1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/app.cpp
4 // Author: Stefan Csomor
7 // Copyright: (c) Stefan Csomor
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #include "wx/wxprec.h"
19 #include "wx/window.h"
22 #include "wx/button.h"
26 #include "wx/palette.h"
28 #include "wx/cursor.h"
29 #include "wx/dialog.h"
30 #include "wx/msgdlg.h"
31 #include "wx/textctrl.h"
32 #include "wx/memory.h"
33 #include "wx/gdicmn.h"
34 #include "wx/module.h"
37 #include "wx/tooltip.h"
38 #include "wx/docview.h"
39 #include "wx/filename.h"
41 #include "wx/thread.h"
42 #include "wx/evtloop.h"
48 #include "wx/osx/uma.h"
50 #include "wx/osx/private.h"
53 #if defined(WXMAKINGDLL_CORE)
54 # include <mach-o/dyld.h>
57 // Keep linker from discarding wxStockGDIMac
58 wxFORCE_LINK_MODULE(gdiobj
)
60 IMPLEMENT_DYNAMIC_CLASS(wxApp
, wxEvtHandler
)
61 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
62 EVT_IDLE(wxApp::OnIdle
)
63 EVT_END_SESSION(wxApp::OnEndSession
)
64 EVT_QUERY_END_SESSION(wxApp::OnQueryEndSession
)
68 // platform specific static variables
69 static const short kwxMacAppleMenuId
= 1 ;
71 wxWindow
* wxApp::s_captureWindow
= NULL
;
72 long wxApp::s_lastModifiers
= 0 ;
74 long wxApp::s_macAboutMenuItemId
= wxID_ABOUT
;
75 long wxApp::s_macPreferencesMenuItemId
= wxID_PREFERENCES
;
76 long wxApp::s_macExitMenuItemId
= wxID_EXIT
;
77 wxString
wxApp::s_macHelpMenuTitleName
= wxT("&Help") ;
79 bool wxApp::sm_isEmbedded
= false; // Normally we're not a plugin
83 //----------------------------------------------------------------------
84 // Core Apple Event Support
85 //----------------------------------------------------------------------
87 AEEventHandlerUPP sODocHandler
= NULL
;
88 AEEventHandlerUPP sGURLHandler
= NULL
;
89 AEEventHandlerUPP sOAppHandler
= NULL
;
90 AEEventHandlerUPP sPDocHandler
= NULL
;
91 AEEventHandlerUPP sRAppHandler
= NULL
;
92 AEEventHandlerUPP sQuitHandler
= NULL
;
94 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
95 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
96 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
97 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
98 pascal OSErr
AEHandleRApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
99 pascal OSErr
AEHandleGURL( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon refcon
) ;
101 pascal OSErr
AEHandleODoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
103 return wxTheApp
->MacHandleAEODoc( (AppleEvent
*) event
, reply
) ;
106 pascal OSErr
AEHandleOApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
108 return wxTheApp
->MacHandleAEOApp( (AppleEvent
*) event
, reply
) ;
111 pascal OSErr
AEHandlePDoc( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
113 return wxTheApp
->MacHandleAEPDoc( (AppleEvent
*) event
, reply
) ;
116 pascal OSErr
AEHandleQuit( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
118 return wxTheApp
->MacHandleAEQuit( (AppleEvent
*) event
, reply
) ;
121 pascal OSErr
AEHandleRApp( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
123 return wxTheApp
->MacHandleAERApp( (AppleEvent
*) event
, reply
) ;
126 pascal OSErr
AEHandleGURL( const AppleEvent
*event
, AppleEvent
*reply
, SRefCon
WXUNUSED(refcon
) )
128 return wxTheApp
->MacHandleAEGURL((WXEVENTREF
*)event
, reply
) ;
132 // AEODoc Calls MacOpenFiles with all of the files passed
134 short wxApp::MacHandleAEODoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
138 DescType returnedType
;
144 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
148 err
= AECountItems(&docList
, &itemsInList
);
152 ProcessSerialNumber PSN
;
153 PSN
.highLongOfPSN
= 0 ;
154 PSN
.lowLongOfPSN
= kCurrentProcess
;
155 SetFrontProcess( &PSN
) ;
160 wxArrayString fileNames
;
161 for (i
= 1; i
<= itemsInList
; i
++)
164 &docList
, i
, typeFSRef
, &keywd
, &returnedType
,
165 (Ptr
)&theRef
, sizeof(theRef
), &actualSize
);
170 fName
= wxMacFSRefToPath( &theRef
) ;
172 fileNames
.Add(fName
);
175 MacOpenFiles(fileNames
);
180 // AEODoc Calls MacOpenURL on the url passed
182 short wxApp::MacHandleAEGURL(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
184 DescType returnedType
;
187 OSErr err
= AEGetParamPtr((AppleEvent
*)event
, keyDirectObject
, typeChar
,
188 &returnedType
, url
, sizeof(url
)-1,
193 url
[actualSize
] = '\0'; // Terminate the C string
195 ProcessSerialNumber PSN
;
196 PSN
.highLongOfPSN
= 0 ;
197 PSN
.lowLongOfPSN
= kCurrentProcess
;
198 SetFrontProcess( &PSN
) ;
200 MacOpenURL(wxString(url
, wxConvUTF8
));
205 // AEPDoc Calls MacPrintFile on each of the files passed
207 short wxApp::MacHandleAEPDoc(const WXEVENTREF event
, WXEVENTREF
WXUNUSED(reply
))
211 DescType returnedType
;
217 err
= AEGetParamDesc((AppleEvent
*)event
, keyDirectObject
, typeAEList
,&docList
);
221 err
= AECountItems(&docList
, &itemsInList
);
225 ProcessSerialNumber PSN
;
226 PSN
.highLongOfPSN
= 0 ;
227 PSN
.lowLongOfPSN
= kCurrentProcess
;
228 SetFrontProcess( &PSN
) ;
233 for (i
= 1; i
<= itemsInList
; i
++)
236 &docList
, i
, typeFSRef
, &keywd
, &returnedType
,
237 (Ptr
)&theRef
, sizeof(theRef
), &actualSize
);
242 fName
= wxMacFSRefToPath( &theRef
) ;
250 // AEOApp calls MacNewFile
252 short wxApp::MacHandleAEOApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
258 // AEQuit attempts to quit the application
260 short wxApp::MacHandleAEQuit(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
263 wxTheApp
->OnQueryEndSession(event
);
264 if ( !event
.GetVeto() )
267 wxTheApp
->OnEndSession(event
);
272 // AEROApp calls MacReopenApp
274 short wxApp::MacHandleAERApp(const WXEVENTREF
WXUNUSED(event
) , WXEVENTREF
WXUNUSED(reply
))
283 //----------------------------------------------------------------------
284 // Support Routines linking the Mac...File Calls to the Document Manager
285 //----------------------------------------------------------------------
287 void wxApp::MacOpenFiles(const wxArrayString
& fileNames
)
290 const size_t fileCount
= fileNames
.GetCount();
291 for (i
= 0; i
< fileCount
; i
++)
293 MacOpenFile(fileNames
[i
]);
297 void wxApp::MacOpenFile(const wxString
& fileName
)
299 #if wxUSE_DOC_VIEW_ARCHITECTURE
300 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
302 dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
306 void wxApp::MacOpenURL(const wxString
& WXUNUSED(url
) )
310 void wxApp::MacPrintFile(const wxString
& fileName
)
312 #if wxUSE_DOC_VIEW_ARCHITECTURE
314 #if wxUSE_PRINTING_ARCHITECTURE
315 wxDocManager
* dm
= wxDocManager::GetDocumentManager() ;
318 wxDocument
*doc
= dm
->CreateDocument(fileName
, wxDOC_SILENT
) ;
321 wxView
* view
= doc
->GetFirstView() ;
324 wxPrintout
*printout
= view
->OnCreatePrintout();
328 printer
.Print(view
->GetFrame(), printout
, true);
335 doc
->DeleteAllViews();
336 dm
->RemoveDocument(doc
) ;
347 void wxApp::MacNewFile()
351 void wxApp::MacReopenApp()
354 // if there is no open window -> create a new one
355 // if all windows are hidden -> show the first
356 // if some windows are not hidden -> do nothing
358 wxWindowList::compatibility_iterator node
= wxTopLevelWindows
.GetFirst();
365 wxTopLevelWindow
* firstIconized
= NULL
;
366 wxTopLevelWindow
* firstHidden
= NULL
;
369 wxTopLevelWindow
* win
= (wxTopLevelWindow
*) node
->GetData();
370 if ( !win
->IsShown() )
372 // make sure we don't show 'virtual toplevel windows' like wxTaskBarIconWindow
373 if ( firstHidden
== NULL
&& ( wxDynamicCast( win
, wxFrame
) || wxDynamicCast( win
, wxDialog
) ) )
376 else if ( win
->IsIconized() )
378 if ( firstIconized
== NULL
)
379 firstIconized
= win
;
383 // we do have a visible, non-iconized toplevelwindow -> do nothing
387 node
= node
->GetNext();
391 firstIconized
->Iconize( false ) ;
393 // showing hidden windows is not really always a good solution, also non-modal dialogs when closed end up
394 // as hidden tlws, we don't want to reshow those, so let's just reopen the minimized a.k.a. iconized tlws
395 // unless we find a regression ...
397 else if ( firstHidden
)
398 firstHidden
->Show( true );
403 #if wxOSX_USE_COCOA_OR_IPHONE
404 void wxApp::OSXOnWillFinishLaunching()
407 m_onInitResult
= OnInit();
411 void wxApp::OSXOnDidFinishLaunching()
415 void wxApp::OSXOnWillTerminate()
418 event
.SetCanVeto(false);
419 wxTheApp
->OnEndSession(event
);
422 bool wxApp::OSXOnShouldTerminate()
425 wxTheApp
->OnQueryEndSession(event
);
426 return !event
.GetVeto();
430 //----------------------------------------------------------------------
431 // Macintosh CommandID support - converting between native and wx IDs
432 //----------------------------------------------------------------------
434 // if no native match they just return the passed-in id
444 IdPair gCommandIds
[] =
446 { kHICommandCut
, wxID_CUT
} ,
447 { kHICommandCopy
, wxID_COPY
} ,
448 { kHICommandPaste
, wxID_PASTE
} ,
449 { kHICommandSelectAll
, wxID_SELECTALL
} ,
450 { kHICommandClear
, wxID_CLEAR
} ,
451 { kHICommandUndo
, wxID_UNDO
} ,
452 { kHICommandRedo
, wxID_REDO
} ,
455 int wxMacCommandToId( UInt32 macCommandId
)
459 switch ( macCommandId
)
461 case kHICommandPreferences
:
462 wxid
= wxApp::s_macPreferencesMenuItemId
;
465 case kHICommandQuit
:
466 wxid
= wxApp::s_macExitMenuItemId
;
469 case kHICommandAbout
:
470 wxid
= wxApp::s_macAboutMenuItemId
;
475 for ( size_t i
= 0 ; i
< WXSIZEOF(gCommandIds
) ; ++i
)
477 if ( gCommandIds
[i
].macId
== macCommandId
)
479 wxid
= gCommandIds
[i
].wxId
;
488 wxid
= (int) macCommandId
;
493 UInt32
wxIdToMacCommand( int wxId
)
497 if ( wxId
== wxApp::s_macPreferencesMenuItemId
)
498 macId
= kHICommandPreferences
;
499 else if (wxId
== wxApp::s_macExitMenuItemId
)
500 macId
= kHICommandQuit
;
501 else if (wxId
== wxApp::s_macAboutMenuItemId
)
502 macId
= kHICommandAbout
;
505 for ( size_t i
= 0 ; i
< WXSIZEOF(gCommandIds
) ; ++i
)
507 if ( gCommandIds
[i
].wxId
== wxId
)
509 macId
= gCommandIds
[i
].macId
;
521 wxMenu
* wxFindMenuFromMacCommand( const HICommand
&command
, wxMenuItem
* &item
)
523 wxMenu
* itemMenu
= NULL
;
524 #ifndef __WXUNIVERSAL__
527 // for 'standard' commands which don't have a wx-menu
528 if ( command
.commandID
== kHICommandPreferences
|| command
.commandID
== kHICommandQuit
|| command
.commandID
== kHICommandAbout
)
530 id
= wxMacCommandToId( command
.commandID
) ;
532 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
534 item
= mbar
->FindItem( id
, &itemMenu
) ;
536 else if ( command
.commandID
!= 0 && command
.menu
.menuRef
!= 0 && command
.menu
.menuItemIndex
!= 0 )
538 id
= wxMacCommandToId( command
.commandID
) ;
539 // make sure it is one of our own menus, or of the 'synthetic' apple and help menus , otherwise don't touch
540 MenuItemIndex firstUserHelpMenuItem
;
541 static MenuHandle helpMenuHandle
= NULL
;
542 if ( helpMenuHandle
== NULL
)
544 if ( UMAGetHelpMenuDontCreate( &helpMenuHandle
, &firstUserHelpMenuItem
) != noErr
)
545 helpMenuHandle
= NULL
;
548 // is it part of the application or the Help menu, then look for the id directly
549 if ( ( GetMenuHandle( kwxMacAppleMenuId
) != NULL
&& command
.menu
.menuRef
== GetMenuHandle( kwxMacAppleMenuId
) ) ||
550 ( helpMenuHandle
!= NULL
&& command
.menu
.menuRef
== helpMenuHandle
) ||
551 wxMenuBar::MacGetWindowMenuHMenu() != NULL
&& command
.menu
.menuRef
== wxMenuBar::MacGetWindowMenuHMenu() )
553 wxMenuBar
* mbar
= wxMenuBar::MacGetInstalledMenuBar() ;
555 item
= mbar
->FindItem( id
, &itemMenu
) ;
561 GetMenuItemRefCon( command
.menu
.menuRef
, command
.menu
.menuItemIndex
, &refCon
) ;
562 itemMenu
= wxFindMenuFromMacMenu( command
.menu
.menuRef
) ;
563 if ( itemMenu
!= NULL
&& refCon
!= 0)
564 item
= (wxMenuItem
*) refCon
;
573 //----------------------------------------------------------------------
574 // Carbon Event Handler
575 //----------------------------------------------------------------------
579 static const EventTypeSpec eventList
[] =
581 { kEventClassCommand
, kEventProcessCommand
} ,
582 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
584 { kEventClassMenu
, kEventMenuOpening
},
585 { kEventClassMenu
, kEventMenuClosed
},
586 { kEventClassMenu
, kEventMenuTargetItem
},
588 { kEventClassApplication
, kEventAppActivated
} ,
589 { kEventClassApplication
, kEventAppDeactivated
} ,
590 // handling the quit event is not recommended by apple
591 // rather using the quit apple event - which we do
593 { kEventClassAppleEvent
, kEventAppleEvent
} ,
595 { kEventClassMouse
, kEventMouseDown
} ,
596 { kEventClassMouse
, kEventMouseMoved
} ,
597 { kEventClassMouse
, kEventMouseUp
} ,
598 { kEventClassMouse
, kEventMouseDragged
} ,
602 static pascal OSStatus
603 wxMacAppMenuEventHandler( EventHandlerCallRef
WXUNUSED(handler
),
605 void *WXUNUSED(data
) )
607 wxMacCarbonEvent
cEvent( event
) ;
608 MenuRef menuRef
= cEvent
.GetParameter
<MenuRef
>(kEventParamDirectObject
) ;
609 #ifndef __WXUNIVERSAL__
610 wxMenu
* menu
= wxFindMenuFromMacMenu( menuRef
) ;
614 switch (GetEventKind(event
))
616 case kEventMenuOpening
:
617 menu
->HandleMenuOpened();
620 case kEventMenuClosed
:
621 menu
->HandleMenuClosed();
624 case kEventMenuTargetItem
:
628 command
.menu
.menuRef
= menuRef
;
629 command
.menu
.menuItemIndex
= cEvent
.GetParameter
<MenuItemIndex
>(kEventParamMenuItemIndex
,typeMenuItemIndex
) ;
630 command
.commandID
= cEvent
.GetParameter
<MenuCommand
>(kEventParamMenuCommand
,typeMenuCommand
) ;
631 if (command
.commandID
!= 0)
633 wxMenuItem
* item
= NULL
;
634 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
635 if ( itemMenu
&& item
)
636 itemMenu
->HandleMenuItemHighlighted( item
);
642 wxFAIL_MSG(wxT("Unexpected menu event kind"));
648 return eventNotHandledErr
;
651 static pascal OSStatus
652 wxMacAppCommandEventHandler( EventHandlerCallRef
WXUNUSED(handler
) ,
654 void *WXUNUSED(data
) )
656 OSStatus result
= eventNotHandledErr
;
660 wxMacCarbonEvent
cEvent( event
) ;
661 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
663 wxMenuItem
* item
= NULL
;
664 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
668 wxASSERT( itemMenu
!= NULL
) ;
670 switch ( cEvent
.GetKind() )
672 case kEventProcessCommand
:
673 if ( itemMenu
->HandleCommandProcess( item
) )
677 case kEventCommandUpdateStatus
:
678 if ( itemMenu
->HandleCommandUpdateStatus( item
) )
689 static pascal OSStatus
690 wxMacAppApplicationEventHandler( EventHandlerCallRef
WXUNUSED(handler
) ,
692 void *WXUNUSED(data
) )
694 OSStatus result
= eventNotHandledErr
;
695 switch ( GetEventKind( event
) )
697 case kEventAppActivated
:
699 wxTheApp
->SetActive( true , NULL
) ;
703 case kEventAppDeactivated
:
705 wxTheApp
->SetActive( false , NULL
) ;
716 pascal OSStatus
wxMacAppEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
718 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
719 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
720 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
722 OSStatus result
= eventNotHandledErr
;
723 switch ( GetEventClass( event
) )
726 case kEventClassCommand
:
727 result
= wxMacAppCommandEventHandler( handler
, event
, data
) ;
730 case kEventClassApplication
:
731 result
= wxMacAppApplicationEventHandler( handler
, event
, data
) ;
734 case kEventClassMenu
:
735 result
= wxMacAppMenuEventHandler( handler
, event
, data
) ;
738 case kEventClassMouse
:
740 wxMacCarbonEvent
cEvent( event
) ;
743 Point screenMouseLocation
= cEvent
.GetParameter
<Point
>(kEventParamMouseLocation
) ;
744 ::FindWindow(screenMouseLocation
, &window
);
745 // only send this event in case it had not already been sent to a tlw, as we get
746 // double events otherwise (in case event.skip) was called
747 if ( window
== NULL
)
748 result
= wxMacTopLevelMouseEventHandler( handler
, event
, NULL
) ;
752 case kEventClassAppleEvent
:
753 result
= AEProcessEvent(event
);
760 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
765 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacAppEventHandler
)
768 #if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
771 wxMacAssertOutputHandler(OSType
WXUNUSED(componentSignature
),
772 UInt32
WXUNUSED(options
),
773 const char *assertionString
,
774 const char *exceptionLabelString
,
775 const char *errorString
,
776 const char *fileName
,
779 ConstStr255Param
WXUNUSED(outputMsg
))
781 // flow into assert handling
782 wxString fileNameStr
;
783 wxString assertionStr
;
784 wxString exceptionStr
;
788 fileNameStr
= wxString(fileName
, wxConvLocal
);
789 assertionStr
= wxString(assertionString
, wxConvLocal
);
790 exceptionStr
= wxString((exceptionLabelString
!=0) ? exceptionLabelString
: "", wxConvLocal
) ;
791 errorStr
= wxString((errorString
!=0) ? errorString
: "", wxConvLocal
) ;
793 fileNameStr
= fileName
;
794 assertionStr
= assertionString
;
795 exceptionStr
= (exceptionLabelString
!=0) ? exceptionLabelString
: "" ;
796 errorStr
= (errorString
!=0) ? errorString
: "" ;
801 wxLogDebug( wxT("AssertMacros: %s %s %s file: %s, line: %ld (value %p)\n"),
802 assertionStr
.c_str() ,
803 exceptionStr
.c_str() ,
805 fileNameStr
.c_str(), lineNumber
,
809 wxOnAssert(fileNameStr
, lineNumber
, assertionStr
,
810 wxString::Format( wxT("%s %s value (%p)") , exceptionStr
, errorStr
, value
) ) ;
814 #endif // wxDEBUG_LEVEL
816 bool wxApp::Initialize(int& argc
, wxChar
**argv
)
820 #if wxDEBUG_LEVEL && wxOSX_USE_COCOA_OR_CARBON
821 InstallDebugAssertOutputHandler( NewDebugAssertOutputHandlerUPP( wxMacAssertOutputHandler
) );
824 // Mac OS X passes a process serial number command line argument when
825 // the application is launched from the Finder. This argument must be
826 // removed from the command line arguments before being handled by the
827 // application (otherwise applications would need to handle it)
830 static const wxChar
*ARG_PSN
= wxT("-psn_");
831 if ( wxStrncmp(argv
[1], ARG_PSN
, wxStrlen(ARG_PSN
)) == 0 )
833 // remove this argument
835 memmove(argv
+ 1, argv
+ 2, argc
* sizeof(wxChar
*));
840 Cocoa supports -Key value options which set the user defaults key "Key"
841 to the value "value" Some of them are very handy for debugging like
842 -NSShowAllViews YES. Cocoa picks these up from the real argv so
843 our removal of them from the wx copy of it does not affect Cocoa's
846 We basically just assume that any "-NS" option and its following
847 argument needs to be removed from argv. We hope that user code does
848 not expect to see -NS options and indeed it's probably a safe bet
849 since most user code accepting options is probably using the
850 double-dash GNU-style syntax.
852 for(int i
=1; i
< argc
; ++i
)
854 static const wxChar
*ARG_NS
= wxT("-NS");
855 if( wxStrncmp(argv
[i
], ARG_NS
, wxStrlen(ARG_NS
)) == 0 )
857 // Only eat this option if it has an argument
860 memmove(argv
+ i
, argv
+ i
+ 2, (argc
-i
-1)*sizeof(wxChar
*));
862 // drop back one position so the next run through the loop
863 // reprocesses the argument at our current index.
869 if ( !wxAppBase::Initialize(argc
, argv
) )
873 wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
876 // these might be the startup dirs, set them to the 'usual' dir containing the app bundle
877 wxString startupCwd
= wxGetCwd() ;
878 if ( startupCwd
== wxT("/") || startupCwd
.Right(15) == wxT("/Contents/MacOS") )
880 CFURLRef url
= CFBundleCopyBundleURL(CFBundleGetMainBundle() ) ;
881 CFURLRef urlParent
= CFURLCreateCopyDeletingLastPathComponent( kCFAllocatorDefault
, url
) ;
883 CFStringRef path
= CFURLCopyFileSystemPath ( urlParent
, kCFURLPOSIXPathStyle
) ;
884 CFRelease( urlParent
) ;
885 wxString cwd
= wxCFStringRef(path
).AsString(wxLocale::GetSystemEncoding());
886 wxSetWorkingDirectory( cwd
) ;
893 bool wxApp::CallOnInit()
895 wxMacAutoreleasePool autoreleasepool
;
900 bool wxApp::OnInitGui()
902 if ( !wxAppBase::OnInitGui() )
911 bool wxApp::ProcessIdle()
913 wxMacAutoreleasePool autoreleasepool
;
914 return wxAppBase::ProcessIdle();
919 wxMacAutoreleasePool pool
;
920 return wxAppBase::OnRun();
924 bool wxApp::DoInitGui()
926 InstallStandardEventHandler( GetApplicationEventTarget() ) ;
929 InstallApplicationEventHandler(
930 GetwxMacAppEventHandlerUPP(),
931 GetEventTypeCount(eventList
), eventList
, wxTheApp
, (EventHandlerRef
*)&(wxTheApp
->m_macEventHandler
));
936 sODocHandler
= NewAEEventHandlerUPP(AEHandleODoc
) ;
937 sGURLHandler
= NewAEEventHandlerUPP(AEHandleGURL
) ;
938 sOAppHandler
= NewAEEventHandlerUPP(AEHandleOApp
) ;
939 sPDocHandler
= NewAEEventHandlerUPP(AEHandlePDoc
) ;
940 sRAppHandler
= NewAEEventHandlerUPP(AEHandleRApp
) ;
941 sQuitHandler
= NewAEEventHandlerUPP(AEHandleQuit
) ;
943 AEInstallEventHandler( kCoreEventClass
, kAEOpenDocuments
,
944 sODocHandler
, 0 , FALSE
) ;
945 AEInstallEventHandler( kInternetEventClass
, kAEGetURL
,
946 sGURLHandler
, 0 , FALSE
) ;
947 AEInstallEventHandler( kCoreEventClass
, kAEOpenApplication
,
948 sOAppHandler
, 0 , FALSE
) ;
949 AEInstallEventHandler( kCoreEventClass
, kAEPrintDocuments
,
950 sPDocHandler
, 0 , FALSE
) ;
951 AEInstallEventHandler( kCoreEventClass
, kAEReopenApplication
,
952 sRAppHandler
, 0 , FALSE
) ;
953 AEInstallEventHandler( kCoreEventClass
, kAEQuitApplication
,
954 sQuitHandler
, 0 , FALSE
) ;
957 if ( !wxMacInitCocoa() )
963 void wxApp::DoCleanUp()
966 RemoveEventHandler( (EventHandlerRef
)(wxTheApp
->m_macEventHandler
) );
970 AERemoveEventHandler( kCoreEventClass
, kAEOpenDocuments
,
971 sODocHandler
, FALSE
) ;
972 AERemoveEventHandler( kInternetEventClass
, kAEGetURL
,
973 sGURLHandler
, FALSE
) ;
974 AERemoveEventHandler( kCoreEventClass
, kAEOpenApplication
,
975 sOAppHandler
, FALSE
) ;
976 AERemoveEventHandler( kCoreEventClass
, kAEPrintDocuments
,
977 sPDocHandler
, FALSE
) ;
978 AERemoveEventHandler( kCoreEventClass
, kAEReopenApplication
,
979 sRAppHandler
, FALSE
) ;
980 AERemoveEventHandler( kCoreEventClass
, kAEQuitApplication
,
981 sQuitHandler
, FALSE
) ;
983 DisposeAEEventHandlerUPP( sODocHandler
) ;
984 DisposeAEEventHandlerUPP( sGURLHandler
) ;
985 DisposeAEEventHandlerUPP( sOAppHandler
) ;
986 DisposeAEEventHandlerUPP( sPDocHandler
) ;
987 DisposeAEEventHandlerUPP( sRAppHandler
) ;
988 DisposeAEEventHandlerUPP( sQuitHandler
) ;
994 void wxApp::CleanUp()
996 wxMacAutoreleasePool autoreleasepool
;
998 wxToolTip::RemoveToolTips() ;
1003 wxAppBase::CleanUp();
1006 //----------------------------------------------------------------------
1007 // misc initialization stuff
1008 //----------------------------------------------------------------------
1012 m_printMode
= wxPRINT_WINDOWS
;
1014 m_macCurrentEvent
= NULL
;
1015 m_macCurrentEventHandlerCallRef
= NULL
;
1016 m_macPool
= new wxMacAutoreleasePool();
1025 CFMutableArrayRef
GetAutoReleaseArray()
1027 static CFMutableArrayRef array
= 0;
1029 array
= CFArrayCreateMutable(kCFAllocatorDefault
,0,&kCFTypeArrayCallBacks
);
1033 void wxApp::MacAddToAutorelease( void* cfrefobj
)
1035 CFArrayAppendValue( GetAutoReleaseArray(), cfrefobj
);
1038 void wxApp::MacReleaseAutoreleasePool()
1042 m_macPool
= new wxMacAutoreleasePool();
1045 void wxApp::OnIdle(wxIdleEvent
& WXUNUSED(event
))
1047 // If they are pending events, we must process them: pending events are
1048 // either events to the threads other than main or events posted with
1049 // wxPostEvent() functions
1050 #ifndef __WXUNIVERSAL__
1052 if (!wxMenuBar::MacGetInstalledMenuBar() && wxMenuBar::MacGetCommonMenuBar())
1053 wxMenuBar::MacGetCommonMenuBar()->MacInstallMenuBar();
1056 CFArrayRemoveAllValues( GetAutoReleaseArray() );
1059 void wxApp::WakeUpIdle()
1061 wxEventLoopBase
* const loop
= wxEventLoopBase::GetActive();
1067 void wxApp::OnEndSession(wxCloseEvent
& WXUNUSED(event
))
1070 GetTopWindow()->Close(true);
1073 // Default behaviour: close the application with prompts. The
1074 // user can veto the close, and therefore the end session.
1075 void wxApp::OnQueryEndSession(wxCloseEvent
& event
)
1077 if ( !wxDialog::OSXHasModalDialogsOpen() )
1081 if (!GetTopWindow()->Close(!event
.CanVeto()))
1091 extern "C" void wxCYield() ;
1098 void wxApp::MacHandleUnhandledEvent( WXEVENTREF
WXUNUSED(evr
) )
1100 // Override to process unhandled events as you please
1103 #if wxOSX_USE_COCOA_OR_CARBON
1105 CGKeyCode
wxCharCodeWXToOSX(wxKeyCode code
)
1111 // Clang warns about switch values not of the same type as (enumerated)
1112 // switch controlling expression. This is generally useful but here we
1113 // really want to be able to use letters and digits without making them
1114 // part of wxKeyCode enum.
1116 #pragma clang diagnostic push
1117 #pragma clang diagnostic ignored "-Wswitch"
1120 case 'a': case 'A': keycode
= kVK_ANSI_A
; break;
1121 case 'b': case 'B': keycode
= kVK_ANSI_B
; break;
1122 case 'c': case 'C': keycode
= kVK_ANSI_C
; break;
1123 case 'd': case 'D': keycode
= kVK_ANSI_D
; break;
1124 case 'e': case 'E': keycode
= kVK_ANSI_E
; break;
1125 case 'f': case 'F': keycode
= kVK_ANSI_F
; break;
1126 case 'g': case 'G': keycode
= kVK_ANSI_G
; break;
1127 case 'h': case 'H': keycode
= kVK_ANSI_H
; break;
1128 case 'i': case 'I': keycode
= kVK_ANSI_I
; break;
1129 case 'j': case 'J': keycode
= kVK_ANSI_J
; break;
1130 case 'k': case 'K': keycode
= kVK_ANSI_K
; break;
1131 case 'l': case 'L': keycode
= kVK_ANSI_L
; break;
1132 case 'm': case 'M': keycode
= kVK_ANSI_M
; break;
1133 case 'n': case 'N': keycode
= kVK_ANSI_N
; break;
1134 case 'o': case 'O': keycode
= kVK_ANSI_O
; break;
1135 case 'p': case 'P': keycode
= kVK_ANSI_P
; break;
1136 case 'q': case 'Q': keycode
= kVK_ANSI_Q
; break;
1137 case 'r': case 'R': keycode
= kVK_ANSI_R
; break;
1138 case 's': case 'S': keycode
= kVK_ANSI_S
; break;
1139 case 't': case 'T': keycode
= kVK_ANSI_T
; break;
1140 case 'u': case 'U': keycode
= kVK_ANSI_U
; break;
1141 case 'v': case 'V': keycode
= kVK_ANSI_V
; break;
1142 case 'w': case 'W': keycode
= kVK_ANSI_W
; break;
1143 case 'x': case 'X': keycode
= kVK_ANSI_X
; break;
1144 case 'y': case 'Y': keycode
= kVK_ANSI_Y
; break;
1145 case 'z': case 'Z': keycode
= kVK_ANSI_Z
; break;
1147 case '0': keycode
= kVK_ANSI_0
; break;
1148 case '1': keycode
= kVK_ANSI_1
; break;
1149 case '2': keycode
= kVK_ANSI_2
; break;
1150 case '3': keycode
= kVK_ANSI_3
; break;
1151 case '4': keycode
= kVK_ANSI_4
; break;
1152 case '5': keycode
= kVK_ANSI_5
; break;
1153 case '6': keycode
= kVK_ANSI_6
; break;
1154 case '7': keycode
= kVK_ANSI_7
; break;
1155 case '8': keycode
= kVK_ANSI_8
; break;
1156 case '9': keycode
= kVK_ANSI_9
; break;
1159 #pragma clang diagnostic pop
1162 case WXK_BACK
: keycode
= kVK_Delete
; break;
1163 case WXK_TAB
: keycode
= kVK_Tab
; break;
1164 case WXK_RETURN
: keycode
= kVK_Return
; break;
1165 case WXK_ESCAPE
: keycode
= kVK_Escape
; break;
1166 case WXK_SPACE
: keycode
= kVK_Space
; break;
1167 case WXK_DELETE
: keycode
= kVK_ForwardDelete
; break;
1169 case WXK_SHIFT
: keycode
= kVK_Shift
; break;
1170 case WXK_ALT
: keycode
= kVK_Option
; break;
1171 case WXK_RAW_CONTROL
: keycode
= kVK_Control
; break;
1172 case WXK_CONTROL
: keycode
= kVK_Command
; break;
1174 case WXK_CAPITAL
: keycode
= kVK_CapsLock
; break;
1175 case WXK_END
: keycode
= kVK_End
; break;
1176 case WXK_HOME
: keycode
= kVK_Home
; break;
1177 case WXK_LEFT
: keycode
= kVK_LeftArrow
; break;
1178 case WXK_UP
: keycode
= kVK_UpArrow
; break;
1179 case WXK_RIGHT
: keycode
= kVK_RightArrow
; break;
1180 case WXK_DOWN
: keycode
= kVK_DownArrow
; break;
1182 case WXK_HELP
: keycode
= kVK_Help
; break;
1185 case WXK_NUMPAD0
: keycode
= kVK_ANSI_Keypad0
; break;
1186 case WXK_NUMPAD1
: keycode
= kVK_ANSI_Keypad1
; break;
1187 case WXK_NUMPAD2
: keycode
= kVK_ANSI_Keypad2
; break;
1188 case WXK_NUMPAD3
: keycode
= kVK_ANSI_Keypad3
; break;
1189 case WXK_NUMPAD4
: keycode
= kVK_ANSI_Keypad4
; break;
1190 case WXK_NUMPAD5
: keycode
= kVK_ANSI_Keypad5
; break;
1191 case WXK_NUMPAD6
: keycode
= kVK_ANSI_Keypad6
; break;
1192 case WXK_NUMPAD7
: keycode
= kVK_ANSI_Keypad7
; break;
1193 case WXK_NUMPAD8
: keycode
= kVK_ANSI_Keypad8
; break;
1194 case WXK_NUMPAD9
: keycode
= kVK_ANSI_Keypad9
; break;
1195 case WXK_F1
: keycode
= kVK_F1
; break;
1196 case WXK_F2
: keycode
= kVK_F2
; break;
1197 case WXK_F3
: keycode
= kVK_F3
; break;
1198 case WXK_F4
: keycode
= kVK_F4
; break;
1199 case WXK_F5
: keycode
= kVK_F5
; break;
1200 case WXK_F6
: keycode
= kVK_F6
; break;
1201 case WXK_F7
: keycode
= kVK_F7
; break;
1202 case WXK_F8
: keycode
= kVK_F8
; break;
1203 case WXK_F9
: keycode
= kVK_F9
; break;
1204 case WXK_F10
: keycode
= kVK_F10
; break;
1205 case WXK_F11
: keycode
= kVK_F11
; break;
1206 case WXK_F12
: keycode
= kVK_F12
; break;
1207 case WXK_F13
: keycode
= kVK_F13
; break;
1208 case WXK_F14
: keycode
= kVK_F14
; break;
1209 case WXK_F15
: keycode
= kVK_F15
; break;
1210 case WXK_F16
: keycode
= kVK_F16
; break;
1211 case WXK_F17
: keycode
= kVK_F17
; break;
1212 case WXK_F18
: keycode
= kVK_F18
; break;
1213 case WXK_F19
: keycode
= kVK_F19
; break;
1214 case WXK_F20
: keycode
= kVK_F20
; break;
1216 case WXK_PAGEUP
: keycode
= kVK_PageUp
; break;
1217 case WXK_PAGEDOWN
: keycode
= kVK_PageDown
; break;
1219 case WXK_NUMPAD_DELETE
: keycode
= kVK_ANSI_KeypadClear
; break;
1220 case WXK_NUMPAD_EQUAL
: keycode
= kVK_ANSI_KeypadEquals
; break;
1221 case WXK_NUMPAD_MULTIPLY
: keycode
= kVK_ANSI_KeypadMultiply
; break;
1222 case WXK_NUMPAD_ADD
: keycode
= kVK_ANSI_KeypadPlus
; break;
1223 case WXK_NUMPAD_SUBTRACT
: keycode
= kVK_ANSI_KeypadMinus
; break;
1224 case WXK_NUMPAD_DECIMAL
: keycode
= kVK_ANSI_KeypadDecimal
; break;
1225 case WXK_NUMPAD_DIVIDE
: keycode
= kVK_ANSI_KeypadDivide
; break;
1228 wxLogDebug( "Unrecognised keycode %d", code
);
1229 keycode
= static_cast<CGKeyCode
>(-1);
1235 long wxMacTranslateKey(unsigned char key
, unsigned char code
)
1240 case kHomeCharCode
:
1244 case kEnterCharCode
:
1245 retval
= WXK_RETURN
;
1251 case kHelpCharCode
:
1255 case kBackspaceCharCode
:
1263 case kPageUpCharCode
:
1264 retval
= WXK_PAGEUP
;
1267 case kPageDownCharCode
:
1268 retval
= WXK_PAGEDOWN
;
1271 case kReturnCharCode
:
1272 retval
= WXK_RETURN
;
1275 case kFunctionKeyCharCode
:
1345 case kEscapeCharCode
:
1346 retval
= WXK_ESCAPE
;
1349 case kLeftArrowCharCode
:
1353 case kRightArrowCharCode
:
1354 retval
= WXK_RIGHT
;
1357 case kUpArrowCharCode
:
1361 case kDownArrowCharCode
:
1365 case kDeleteCharCode
:
1366 retval
= WXK_DELETE
;
1376 int wxMacKeyCodeToModifier(wxKeyCode key
)
1394 case WXK_RAW_CONTROL
:
1403 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
1405 // defined in utils.mm
1407 #elif wxOSX_USE_COCOA_OR_CARBON
1409 wxMouseState
wxGetMouseState()
1413 wxPoint pt
= wxGetMousePosition();
1417 UInt32 buttons
= GetCurrentButtonState();
1418 ms
.SetLeftDown( (buttons
& 0x01) != 0 );
1419 ms
.SetMiddleDown( (buttons
& 0x04) != 0 );
1420 ms
.SetRightDown( (buttons
& 0x02) != 0 );
1422 UInt32 modifiers
= GetCurrentKeyModifiers();
1423 ms
.SetRawControlDown(modifiers
& controlKey
);
1424 ms
.SetShiftDown(modifiers
& shiftKey
);
1425 ms
.SetAltDown(modifiers
& optionKey
);
1426 ms
.SetControlDown(modifiers
& cmdKey
);
1433 // TODO : once the new key/char handling is tested, move all the code to wxWindow
1435 bool wxApp::MacSendKeyDownEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1440 wxKeyEvent
event(wxEVT_KEY_DOWN
) ;
1441 MacCreateKeyEvent( event
, focus
, keymessage
, modifiers
, when
, uniChar
) ;
1443 return focus
->OSXHandleKeyEvent(event
);
1446 bool wxApp::MacSendKeyUpEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1451 wxKeyEvent
event( wxEVT_KEY_UP
) ;
1452 MacCreateKeyEvent( event
, focus
, keymessage
, modifiers
, when
, uniChar
) ;
1454 return focus
->OSXHandleKeyEvent(event
) ;
1457 bool wxApp::MacSendCharEvent( wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1461 wxKeyEvent
event(wxEVT_CHAR
) ;
1462 MacCreateKeyEvent( event
, focus
, keymessage
, modifiers
, when
, uniChar
) ;
1464 bool handled
= false ;
1466 #if wxOSX_USE_CARBON
1467 long keyval
= event
.m_keyCode
;
1470 wxKeyEvent
eventCharHook(wxEVT_CHAR_HOOK
, event
);
1471 handled
= focus
->HandleWindowEvent( eventCharHook
);
1472 if ( handled
&& eventCharHook
.IsNextEventAllowed() )
1478 handled
= focus
->HandleWindowEvent( event
) ;
1481 if ( !handled
&& (keyval
== WXK_TAB
) )
1483 wxWindow
* iter
= focus
->GetParent() ;
1484 while ( iter
&& !handled
)
1486 if ( iter
->HasFlag( wxTAB_TRAVERSAL
) )
1488 wxNavigationKeyEvent new_event
;
1489 new_event
.SetEventObject( focus
);
1490 new_event
.SetDirection( !event
.ShiftDown() );
1491 /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
1492 new_event
.SetWindowChange( event
.ControlDown() );
1493 new_event
.SetCurrentFocus( focus
);
1494 handled
= focus
->GetParent()->HandleWindowEvent( new_event
);
1495 if ( handled
&& new_event
.GetSkipped() )
1499 iter
= iter
->GetParent() ;
1503 // backdoor handler for default return and command escape
1504 if ( !handled
&& (!focus
->IsKindOf(CLASSINFO(wxControl
) ) || !focus
->AcceptsFocus() ) )
1506 // if window is not having a focus still testing for default enter or cancel
1507 // TODO: add the UMA version for ActiveNonFloatingWindow
1509 wxWindow
* focus
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) FrontWindow() ) ;
1512 if ( keyval
== WXK_RETURN
|| keyval
== WXK_NUMPAD_ENTER
)
1514 wxTopLevelWindow
*tlw
= wxDynamicCast(wxGetTopLevelParent(focus
), wxTopLevelWindow
);
1515 if ( tlw
&& tlw
->GetDefaultItem() )
1517 wxButton
*def
= wxDynamicCast(tlw
->GetDefaultItem(), wxButton
);
1518 if ( def
&& def
->IsEnabled() )
1520 wxCommandEvent
event(wxEVT_BUTTON
, def
->GetId() );
1521 event
.SetEventObject(def
);
1522 def
->Command(event
);
1528 else if (keyval
== WXK_ESCAPE
|| (keyval
== '.' && modifiers
& cmdKey
) )
1530 // generate wxID_CANCEL if command-. or <esc> has been pressed (typically in dialogs)
1531 wxCommandEvent
new_event(wxEVT_BUTTON
,wxID_CANCEL
);
1532 new_event
.SetEventObject( focus
);
1533 handled
= focus
->HandleWindowEvent( new_event
);
1542 // This method handles common code for SendKeyDown, SendKeyUp, and SendChar events.
1543 void wxApp::MacCreateKeyEvent( wxKeyEvent
& event
, wxWindow
* focus
, long keymessage
, long modifiers
, long when
, wxChar uniChar
)
1545 #if wxOSX_USE_COCOA_OR_CARBON
1547 short keycode
, keychar
;
1549 keychar
= short(keymessage
& charCodeMask
);
1550 keycode
= short(keymessage
& keyCodeMask
) >> 8 ;
1551 if ( !(event
.GetEventType() == wxEVT_CHAR
) && (modifiers
& (controlKey
| shiftKey
| optionKey
) ) )
1553 // control interferes with some built-in keys like pgdown, return etc. therefore we remove the controlKey modifier
1554 // and look at the character after
1556 // TODO new implementation using TextInputSources
1559 UInt32 keyInfo
= KeyTranslate((Ptr
)GetScriptManagerVariable(smKCHRCache
), ( modifiers
& (~(controlKey
| shiftKey
| optionKey
))) | keycode
, &state
);
1560 keychar
= short(keyInfo
& charCodeMask
);
1564 long keyval
= wxMacTranslateKey(keychar
, keycode
) ;
1565 if ( keyval
== keychar
&& ( event
.GetEventType() == wxEVT_KEY_UP
|| event
.GetEventType() == wxEVT_KEY_DOWN
) )
1566 keyval
= wxToupper( keyval
) ;
1568 // Check for NUMPAD keys. For KEY_UP/DOWN events we need to use the
1569 // WXK_NUMPAD constants, but for the CHAR event we want to use the
1570 // standard ascii values
1571 if ( event
.GetEventType() != wxEVT_CHAR
)
1573 if (keyval
>= '0' && keyval
<= '9' && keycode
>= 82 && keycode
<= 92)
1575 keyval
= (keyval
- '0') + WXK_NUMPAD0
;
1577 else if (keycode
>= 65 && keycode
<= 81)
1582 keyval
= WXK_NUMPAD_ENTER
;
1586 keyval
= WXK_NUMPAD_EQUAL
;
1590 keyval
= WXK_NUMPAD_MULTIPLY
;
1594 keyval
= WXK_NUMPAD_DIVIDE
;
1598 keyval
= WXK_NUMPAD_SUBTRACT
;
1602 keyval
= WXK_NUMPAD_ADD
;
1606 keyval
= WXK_NUMPAD_DECIMAL
;
1614 event
.m_shiftDown
= modifiers
& shiftKey
;
1615 event
.m_rawControlDown
= modifiers
& controlKey
;
1616 event
.m_altDown
= modifiers
& optionKey
;
1617 event
.m_controlDown
= modifiers
& cmdKey
;
1618 event
.m_keyCode
= keyval
;
1620 event
.m_uniChar
= uniChar
;
1623 event
.m_rawCode
= keymessage
;
1624 event
.m_rawFlags
= modifiers
;
1625 event
.SetTimestamp(when
);
1626 event
.SetEventObject(focus
);
1630 wxUnusedVar(keymessage
);
1631 wxUnusedVar(modifiers
);
1633 wxUnusedVar(uniChar
);
1638 void wxApp::MacHideApp()
1640 #if wxOSX_USE_CARBON
1641 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1643 memset( &command
, 0 , sizeof(command
) );
1644 command
.commandID
= kHICommandHide
;
1645 event
.SetParameter
<HICommand
>(kEventParamDirectObject
, command
);
1646 SendEventToApplication( event
);