1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/window.cpp
3 // Purpose: wxWindowMac
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
14 #include "wx/window.h"
23 #include "wx/dcclient.h"
24 #include "wx/button.h"
26 #include "wx/dialog.h"
27 #include "wx/settings.h"
28 #include "wx/msgdlg.h"
29 #include "wx/scrolbar.h"
30 #include "wx/statbox.h"
31 #include "wx/textctrl.h"
32 #include "wx/toolbar.h"
33 #include "wx/layout.h"
34 #include "wx/statusbr.h"
35 #include "wx/menuitem.h"
36 #include "wx/treectrl.h"
37 #include "wx/listctrl.h"
40 #include "wx/tooltip.h"
41 #include "wx/spinctrl.h"
42 #include "wx/geometry.h"
45 #include "wx/listctrl.h"
49 #include "wx/treectrl.h"
57 #include "wx/popupwin.h"
60 #if wxUSE_DRAG_AND_DROP
65 #include "wx/osx/uma.h"
67 #include "wx/osx/private.h"
69 #include <Carbon/Carbon.h>
72 #define MAC_SCROLLBAR_SIZE 15
73 #define MAC_SMALL_SCROLLBAR_SIZE 11
77 #define wxMAC_DEBUG_REDRAW 0
78 #ifndef wxMAC_DEBUG_REDRAW
79 #define wxMAC_DEBUG_REDRAW 0
82 // ---------------------------------------------------------------------------
84 // ---------------------------------------------------------------------------
86 static const EventTypeSpec eventList
[] =
88 { kEventClassCommand
, kEventProcessCommand
} ,
89 { kEventClassCommand
, kEventCommandUpdateStatus
} ,
91 { kEventClassControl
, kEventControlGetClickActivation
} ,
92 { kEventClassControl
, kEventControlHit
} ,
94 { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent
} ,
95 { kEventClassTextInput
, kEventTextInputUpdateActiveInputArea
} ,
97 { kEventClassControl
, kEventControlDraw
} ,
99 { kEventClassControl
, kEventControlVisibilityChanged
} ,
100 { kEventClassControl
, kEventControlEnabledStateChanged
} ,
101 { kEventClassControl
, kEventControlHiliteChanged
} ,
103 { kEventClassControl
, kEventControlActivate
} ,
104 { kEventClassControl
, kEventControlDeactivate
} ,
106 { kEventClassControl
, kEventControlSetFocusPart
} ,
107 { kEventClassControl
, kEventControlFocusPartChanged
} ,
109 { kEventClassService
, kEventServiceGetTypes
},
110 { kEventClassService
, kEventServiceCopy
},
111 { kEventClassService
, kEventServicePaste
},
113 // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only
114 // { kEventClassControl , kEventControlBoundsChanged } ,
117 static pascal OSStatus
wxMacWindowControlEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
119 OSStatus result
= eventNotHandledErr
;
120 static wxWindowMac
* targetFocusWindow
= NULL
;
121 static wxWindowMac
* formerFocusWindow
= NULL
;
123 wxMacCarbonEvent
cEvent( event
) ;
125 ControlRef controlRef
;
126 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
128 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
130 switch ( GetEventKind( event
) )
132 case kEventControlDraw
:
134 RgnHandle updateRgn
= NULL
;
135 RgnHandle allocatedRgn
= NULL
;
136 wxRegion visRegion
= thisWindow
->MacGetVisibleRegion() ;
138 if ( cEvent
.GetParameter
<RgnHandle
>(kEventParamRgnHandle
, &updateRgn
) != noErr
)
140 HIShapeGetAsQDRgn( visRegion
.GetWXHRGN(), updateRgn
);
144 if ( thisWindow
->MacGetLeftBorderSize() != 0 || thisWindow
->MacGetTopBorderSize() != 0 )
146 // as this update region is in native window locals we must adapt it to wx window local
147 allocatedRgn
= NewRgn() ;
148 CopyRgn( updateRgn
, allocatedRgn
) ;
150 // hide the given region by the new region that must be shifted
151 OffsetRgn( allocatedRgn
, thisWindow
->MacGetLeftBorderSize() , thisWindow
->MacGetTopBorderSize() ) ;
152 updateRgn
= allocatedRgn
;
156 #if wxMAC_DEBUG_REDRAW
157 if ( thisWindow
->MacIsUserPane() )
159 static float color
= 0.5 ;
160 static int channel
= 0 ;
162 CGContextRef cgContext
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
) ;
164 HIViewGetBounds( controlRef
, &bounds
);
165 CGContextSetRGBFillColor( cgContext
, channel
== 0 ? color
: 0.5 ,
166 channel
== 1 ? color
: 0.5 , channel
== 2 ? color
: 0.5 , 1 );
167 CGContextFillRect( cgContext
, bounds
);
180 bool created
= false ;
181 CGContextRef cgContext
= NULL
;
182 OSStatus err
= cEvent
.GetParameter
<CGContextRef
>(kEventParamCGContextRef
, &cgContext
) ;
185 wxFAIL_MSG("Unable to retrieve CGContextRef");
188 thisWindow
->MacSetCGContextRef( cgContext
) ;
191 wxMacCGContextStateSaver
sg( cgContext
) ;
192 CGFloat alpha
= (CGFloat
)1.0 ;
194 wxWindow
* iter
= thisWindow
;
197 alpha
*= (CGFloat
)( iter
->GetTransparent()/255.0 ) ;
198 if ( iter
->IsTopLevel() )
201 iter
= iter
->GetParent() ;
204 CGContextSetAlpha( cgContext
, alpha
) ;
206 if ( thisWindow
->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT
)
209 HIViewGetBounds( controlRef
, &bounds
);
210 CGContextClearRect( cgContext
, bounds
);
215 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
218 thisWindow
->MacSetCGContextRef( NULL
) ;
222 CGContextRelease( cgContext
) ;
226 DisposeRgn( allocatedRgn
) ;
230 case kEventControlVisibilityChanged
:
231 // we might have two native controls attributed to the same wxWindow instance
232 // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
233 // control, as otherwise native and wx visibility are different
234 if ( thisWindow
->GetPeer() != NULL
&& thisWindow
->GetPeer()->GetControlRef() == controlRef
)
236 thisWindow
->MacVisibilityChanged() ;
240 case kEventControlEnabledStateChanged
:
241 thisWindow
->MacEnabledStateChanged();
244 case kEventControlHiliteChanged
:
245 thisWindow
->MacHiliteChanged() ;
248 case kEventControlActivate
:
249 case kEventControlDeactivate
:
250 // FIXME: we should have a virtual function for this!
252 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
253 thisWindow
->Refresh();
256 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
257 thisWindow
->Refresh();
263 // different handling on OS X
266 case kEventControlFocusPartChanged
:
267 // the event is emulated by wxmac for systems lower than 10.5
269 if ( UMAGetSystemVersion() < 0x1050 )
271 // as it is synthesized here, we have to manually avoid propagation
274 ControlPartCode previousControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPreviousPart
, typeControlPartCode
);
275 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlCurrentPart
, typeControlPartCode
);
277 if ( thisWindow
->MacGetTopLevelWindow() && thisWindow
->GetPeer()->NeedsFocusRect() )
279 thisWindow
->MacInvalidateBorders();
282 if ( currentControlPart
== 0 )
286 if ( thisWindow
->GetCaret() )
287 thisWindow
->GetCaret()->OnKillFocus();
290 wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast<void*>(thisWindow
));
292 // remove this as soon as posting the synthesized event works properly
293 static bool inKillFocusEvent
= false ;
295 if ( !inKillFocusEvent
)
297 inKillFocusEvent
= true ;
298 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
299 event
.SetEventObject(thisWindow
);
300 event
.SetWindow(targetFocusWindow
);
301 thisWindow
->HandleWindowEvent(event
) ;
302 inKillFocusEvent
= false ;
303 targetFocusWindow
= NULL
;
306 else if ( previousControlPart
== 0 )
309 // panel wants to track the window which was the last to have focus in it
310 wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast<void*>(thisWindow
));
311 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
312 thisWindow
->HandleWindowEvent(eventFocus
);
315 if ( thisWindow
->GetCaret() )
316 thisWindow
->GetCaret()->OnSetFocus();
319 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
320 event
.SetEventObject(thisWindow
);
321 event
.SetWindow(formerFocusWindow
);
322 thisWindow
->HandleWindowEvent(event
) ;
323 formerFocusWindow
= NULL
;
327 case kEventControlSetFocusPart
:
329 Boolean focusEverything
= false ;
330 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
332 // put a breakpoint here to catch focus everything events
334 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
335 if ( controlPart
!= kControlFocusNoPart
)
337 targetFocusWindow
= thisWindow
;
338 wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), static_cast<void*>(thisWindow
));
342 formerFocusWindow
= thisWindow
;
343 wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), static_cast<void*>(thisWindow
));
346 ControlPartCode previousControlPart
= 0;
347 verify_noerr( HIViewGetFocusPart(controlRef
, &previousControlPart
));
349 if ( thisWindow
->MacIsUserPane() )
351 if ( controlPart
!= kControlFocusNoPart
)
352 cEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPart
, typeControlPartCode
, 1 ) ;
356 result
= CallNextEventHandler(handler
, event
);
358 if ( UMAGetSystemVersion() < 0x1050 )
360 // set back to 0 if problems arise
362 if ( result
== noErr
)
364 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
365 // synthesize the event focus changed event
366 EventRef evRef
= NULL
;
368 OSStatus err
= MacCreateEvent(
369 NULL
, kEventClassControl
, kEventControlFocusPartChanged
, TicksToEventTime( TickCount() ) ,
370 kEventAttributeUserEvent
, &evRef
);
373 wxMacCarbonEvent
iEvent( evRef
) ;
374 iEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, controlRef
);
375 iEvent
.SetParameter
<EventTargetRef
>( kEventParamPostTarget
, typeEventTargetRef
, GetControlEventTarget( controlRef
) );
376 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPreviousPart
, typeControlPartCode
, previousControlPart
);
377 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlCurrentPart
, typeControlPartCode
, currentControlPart
);
380 // TODO test this first, avoid double posts etc...
381 PostEventToQueue( GetMainEventQueue(), evRef
, kEventPriorityHigh
);
383 wxMacWindowControlEventHandler( NULL
, evRef
, data
) ;
385 ReleaseEvent( evRef
) ;
388 // old implementation, to be removed if the new one works
389 if ( controlPart
== kControlFocusNoPart
)
392 if ( thisWindow
->GetCaret() )
393 thisWindow
->GetCaret()->OnKillFocus();
396 wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast<void*>(thisWindow
));
398 static bool inKillFocusEvent
= false ;
400 if ( !inKillFocusEvent
)
402 inKillFocusEvent
= true ;
403 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
404 event
.SetEventObject(thisWindow
);
405 thisWindow
->HandleWindowEvent(event
) ;
406 inKillFocusEvent
= false ;
411 // panel wants to track the window which was the last to have focus in it
412 wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast<void*>(thisWindow
));
413 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
414 thisWindow
->HandleWindowEvent(eventFocus
);
417 if ( thisWindow
->GetCaret() )
418 thisWindow
->GetCaret()->OnSetFocus();
421 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
422 event
.SetEventObject(thisWindow
);
423 thisWindow
->HandleWindowEvent(event
) ;
430 case kEventControlHit
:
431 result
= thisWindow
->MacControlHit( handler
, event
) ;
434 case kEventControlGetClickActivation
:
436 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
437 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
438 if ( !IsWindowActive(owner
) )
440 cEvent
.SetParameter(kEventParamClickActivation
,typeClickActivationResult
, (UInt32
) kActivateAndIgnoreClick
) ;
453 static pascal OSStatus
454 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
458 OSStatus result
= eventNotHandledErr
;
460 wxMacCarbonEvent
cEvent( event
) ;
462 ControlRef controlRef
;
463 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
464 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
465 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
467 switch ( GetEventKind( event
) )
469 case kEventServiceGetTypes
:
473 textCtrl
->GetSelection( &from
, &to
) ;
475 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
477 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
478 if ( textCtrl
->IsEditable() )
479 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
481 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
482 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
484 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
488 CFArrayAppendValue(copyTypes
, typestring
) ;
490 CFArrayAppendValue(pasteTypes
, typestring
) ;
492 CFRelease( typestring
) ;
500 case kEventServiceCopy
:
505 textCtrl
->GetSelection( &from
, &to
) ;
506 wxString val
= textCtrl
->GetValue() ;
507 val
= val
.Mid( from
, to
- from
) ;
508 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
509 verify_noerr( PasteboardClear( pasteboard
) ) ;
510 PasteboardSynchronize( pasteboard
);
511 // TODO add proper conversion
512 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
513 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
519 case kEventServicePaste
:
522 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
523 PasteboardSynchronize( pasteboard
);
525 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
526 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
528 PasteboardItemID itemID
;
529 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
531 CFDataRef flavorData
= NULL
;
532 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
534 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
535 char *content
= new char[flavorDataSize
+1] ;
536 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
537 content
[flavorDataSize
]=0;
538 CFRelease( flavorData
);
540 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
542 textCtrl
->WriteText( wxString( content
) ) ;
560 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
562 OSStatus result
= eventNotHandledErr
;
563 wxWindowMac
* focus
= (wxWindowMac
*) data
;
565 wchar_t* uniChars
= NULL
;
566 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
568 UniChar
* charBuf
= NULL
;
569 ByteCount dataSize
= 0 ;
572 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
574 numChars
= dataSize
/ sizeof( UniChar
) + 1;
577 if ( (size_t) numChars
* 2 > sizeof(buf
) )
578 charBuf
= new UniChar
[ numChars
] ;
582 uniChars
= new wchar_t[ numChars
] ;
583 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
584 charBuf
[ numChars
- 1 ] = 0;
585 #if SIZEOF_WCHAR_T == 2
586 uniChars
= (wchar_t*) charBuf
;
587 /* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...)
589 // the resulting string will never have more chars than the utf16 version, so this is safe
590 wxMBConvUTF16 converter
;
591 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
595 switch ( GetEventKind( event
) )
597 case kEventTextInputUpdateActiveInputArea
:
599 // An IME input event may return several characters, but we need to send one char at a time to
601 for (int pos
=0 ; pos
< numChars
; pos
++)
603 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
604 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
605 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
607 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
609 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
610 multiple times to update the active range during inline input, so this handler will often receive
611 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
612 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
613 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
614 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
615 should add new event types to support advanced text input. For now, I would keep things as they are.
617 However, the code that was being used caused additional problems:
618 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
619 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
620 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
621 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
622 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
623 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
624 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
625 overlap with Unicode within the (7-bit) ASCII range.
626 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
627 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
628 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
629 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
630 I don't have time to look into that right now.
633 if ( wxTheApp
->MacSendCharEvent(
634 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
639 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
643 case kEventTextInputUnicodeForKeyEvent
:
645 UInt32 keyCode
, modifiers
;
648 unsigned char charCode
;
650 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
651 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
652 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
653 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
654 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
656 UInt32 message
= (keyCode
<< 8) + charCode
;
658 // An IME input event may return several characters, but we need to send one char at a time to
660 for (int pos
=0 ; pos
< numChars
; pos
++)
662 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
663 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
664 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
666 if ( wxTheApp
->MacSendCharEvent(
667 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
672 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
681 if ( charBuf
!= buf
)
687 static pascal OSStatus
688 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
692 OSStatus result
= eventNotHandledErr
;
693 wxWindowMac
* focus
= (wxWindowMac
*) data
;
697 wxMacCarbonEvent
cEvent( event
) ;
698 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
700 wxMenuItem
* item
= NULL
;
701 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
705 wxASSERT( itemMenu
!= NULL
) ;
707 switch ( cEvent
.GetKind() )
709 case kEventProcessCommand
:
710 if ( itemMenu
->HandleCommandProcess( item
, focus
) )
714 case kEventCommandUpdateStatus
:
715 if ( itemMenu
->HandleCommandUpdateStatus( item
, focus
) )
726 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
728 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
729 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
730 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
731 OSStatus result
= eventNotHandledErr
;
733 switch ( GetEventClass( event
) )
735 case kEventClassCommand
:
736 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
739 case kEventClassControl
:
740 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
743 case kEventClassService
:
744 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
747 case kEventClassTextInput
:
748 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
755 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
760 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
762 // ---------------------------------------------------------------------------
763 // Scrollbar Tracking for all
764 // ---------------------------------------------------------------------------
766 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
767 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
771 wxWindow
* wx
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
774 wxEventType scrollEvent
= wxEVT_NULL
;
777 case kControlUpButtonPart
:
778 scrollEvent
= wxEVT_SCROLL_LINEUP
;
781 case kControlDownButtonPart
:
782 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
785 case kControlPageUpPart
:
786 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
789 case kControlPageDownPart
:
790 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
793 case kControlIndicatorPart
:
794 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
795 // when this is called as a live proc, mouse is always still down
796 // so no need for thumbrelease
797 // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
800 wx
->TriggerScrollEvent(scrollEvent
) ;
804 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
806 wxWidgetImplType
* wxWidgetImpl::CreateUserPane( wxWindowMac
* wxpeer
, wxWindowMac
* parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
,
807 long style
, long extraStyle
)
809 OSStatus err
= noErr
;
810 Rect bounds
= wxMacGetBoundsForControl( wxpeer
, pos
, size
) ;
811 wxMacControl
* c
= new wxMacControl(wxpeer
) ;
813 | kControlSupportsEmbedding
814 | kControlSupportsLiveFeedback
815 | kControlGetsFocusOnClick
816 // | kControlHasSpecialBackground
817 // | kControlSupportsCalcBestRect
818 | kControlHandlesTracking
819 | kControlSupportsFocus
820 | kControlWantsActivate
821 | kControlWantsIdle
;
823 err
=::CreateUserPaneControl( MAC_WXHWND(wxpeer
->GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, c
->GetControlRefAddr() );
829 void wxMacControl::InstallEventHandler( WXWidget control
)
831 wxWidgetImpl::Associate( control
? control
: (WXWidget
) m_controlRef
, this ) ;
832 ::InstallControlEventHandler( control
? (ControlRef
) control
: m_controlRef
, GetwxMacWindowEventHandlerUPP(),
833 GetEventTypeCount(eventList
), eventList
, GetWXPeer(), NULL
);
836 IMPLEMENT_DYNAMIC_CLASS( wxMacControl
, wxWidgetImpl
)
838 wxMacControl::wxMacControl()
843 wxMacControl::wxMacControl(wxWindowMac
* peer
, bool isRootControl
) :
844 wxWidgetImpl( peer
, isRootControl
)
849 wxMacControl::~wxMacControl()
851 if ( m_controlRef
&& !IsRootControl() )
853 wxASSERT_MSG( m_controlRef
!= NULL
, wxT("Control Handle already NULL, Dispose called twice ?") );
854 wxASSERT_MSG( IsValidControlHandle(m_controlRef
) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
856 wxWidgetImpl::RemoveAssociations( this ) ;
857 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
858 // we can have situations when being embedded, where the control gets deleted behind our back, so only
859 // CFRelease if we are safe
860 if ( IsValidControlHandle(m_controlRef
) )
861 CFRelease(m_controlRef
);
866 void wxMacControl::Init()
869 m_macControlEventHandler
= NULL
;
872 void wxMacControl::RemoveFromParent()
874 // nothing to do here for carbon
875 HIViewRemoveFromSuperview(m_controlRef
);
878 void wxMacControl::Embed( wxWidgetImpl
*parent
)
880 HIViewAddSubview((ControlRef
)parent
->GetWXWidget(), m_controlRef
);
883 void wxMacControl::SetNeedsDisplay( const wxRect
* rect
)
890 HIRect updatearea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
891 HIViewSetNeedsDisplayInRect( m_controlRef
, &updatearea
, true );
894 HIViewSetNeedsDisplay( m_controlRef
, true );
897 void wxMacControl::Raise()
899 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderAbove
, NULL
) );
902 void wxMacControl::Lower()
904 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderBelow
, NULL
) );
907 void wxMacControl::GetContentArea(int &left
, int &top
, int &width
, int &height
) const
909 RgnHandle rgn
= NewRgn() ;
911 if ( GetControlRegion( m_controlRef
, kControlContentMetaPart
, rgn
) == noErr
)
912 GetRegionBounds( rgn
, &content
) ;
915 GetControlBounds( m_controlRef
, &content
);
916 content
.right
-= content
.left
;
918 content
.bottom
-= content
.top
;
926 width
= content
.right
- content
.left
;
927 height
= content
.bottom
- content
.top
;
930 void wxMacControl::Move(int x
, int y
, int width
, int height
)
932 HIRect hir
= CGRectMake(x
,y
,width
,height
);
933 HIViewSetFrame ( m_controlRef
, &hir
);
936 void wxMacControl::GetPosition( int &x
, int &y
) const
939 GetControlBounds( m_controlRef
, &r
);
944 void wxMacControl::GetSize( int &width
, int &height
) const
947 GetControlBounds( m_controlRef
, &r
);
948 width
= r
.right
- r
.left
;
949 height
= r
.bottom
- r
.top
;
952 void wxMacControl::SetControlSize( wxWindowVariant variant
)
957 case wxWINDOW_VARIANT_NORMAL
:
958 size
= kControlSizeNormal
;
961 case wxWINDOW_VARIANT_SMALL
:
962 size
= kControlSizeSmall
;
965 case wxWINDOW_VARIANT_MINI
:
966 // not always defined in the headers
970 case wxWINDOW_VARIANT_LARGE
:
971 size
= kControlSizeLarge
;
975 wxFAIL_MSG(_T("unexpected window variant"));
979 SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
982 void wxMacControl::ScrollRect( const wxRect
*rect
, int dx
, int dy
)
984 if (GetNeedsDisplay() )
986 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
987 // in case there is already a pending redraw on that area
988 // either immediate redraw or full invalidate
990 // is the better overall solution, as it does not slow down scrolling
993 // this would be the preferred version for fast drawing controls
994 HIViewRender(GetControlRef()) ;
998 // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control
999 // area is scrolled, this does not occur if width and height are 2 pixels less,
1000 // TODO: write optimal workaround
1002 HIRect scrollarea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1003 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
);
1006 // this would be the preferred version for fast drawing controls
1007 HIViewRender(GetControlRef()) ;
1011 bool wxMacControl::CanFocus() const
1013 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1014 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1015 // but the value range is nowhere documented
1016 Boolean keyExistsAndHasValidFormat
;
1017 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1018 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1020 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1026 UInt32 features
= 0 ;
1027 GetControlFeatures( m_controlRef
, &features
) ;
1029 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1033 bool wxMacControl::GetNeedsDisplay() const
1035 return HIViewGetNeedsDisplay( m_controlRef
);
1038 void wxWidgetImpl::Convert( wxPoint
*pt
, wxWidgetImpl
*from
, wxWidgetImpl
*to
)
1044 HIViewConvertPoint( &hiPoint
, (ControlRef
) from
->GetWXWidget() , (ControlRef
) to
->GetWXWidget() );
1045 pt
->x
= (int)hiPoint
.x
;
1046 pt
->y
= (int)hiPoint
.y
;
1049 bool wxMacControl::SetFocus()
1051 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1052 // we can only leave in case of an error
1054 OSStatus err
= SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, kControlFocusNextPart
);
1055 if ( err
== errCouldntSetFocus
)
1057 SetUserFocusWindow(GetControlOwner( m_controlRef
) );
1062 bool wxMacControl::HasFocus() const
1065 GetKeyboardFocus( GetUserFocusWindow() , &control
);
1066 return control
== m_controlRef
;
1069 void wxMacControl::SetCursor(const wxCursor
& cursor
)
1071 wxWindowMac
*mouseWin
= 0 ;
1072 WindowRef window
= GetControlOwner( m_controlRef
) ;
1074 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) window
) ;
1075 if ( tlwwx
!= NULL
)
1077 ControlPartCode part
;
1078 ControlRef control
;
1080 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1082 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1086 GetGlobalMouse( &pt
);
1089 tlwwx
->ScreenToClient(&x
, &y
);
1093 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1095 mouseWin
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
1098 if ( mouseWin
== tlwwx
&& !wxIsBusy() )
1099 cursor
.MacInstall() ;
1102 void wxMacControl::CaptureMouse()
1106 void wxMacControl::ReleaseMouse()
1111 // subclass specifics
1114 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
1116 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
);
1119 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
1121 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
);
1124 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
1126 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
);
1129 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
1131 return SendEventToEventTargetWithOptions( event
,
1132 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
1135 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
1137 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1139 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
);
1141 return SendEvent( event
, inOptions
);
1144 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
1148 memset( &command
, 0 , sizeof(command
) );
1149 command
.commandID
= commandID
;
1150 return SendHICommand( command
, inOptions
);
1153 void wxMacControl::PerformClick()
1155 HIViewSimulateClick (m_controlRef
, kControlButtonPart
, 0, NULL
);
1158 wxInt32
wxMacControl::GetValue() const
1160 return ::GetControl32BitValue( m_controlRef
);
1163 wxInt32
wxMacControl::GetMaximum() const
1165 return ::GetControl32BitMaximum( m_controlRef
);
1168 wxInt32
wxMacControl::GetMinimum() const
1170 return ::GetControl32BitMinimum( m_controlRef
);
1173 void wxMacControl::SetValue( wxInt32 v
)
1175 ::SetControl32BitValue( m_controlRef
, v
);
1178 void wxMacControl::SetMinimum( wxInt32 v
)
1180 ::SetControl32BitMinimum( m_controlRef
, v
);
1183 void wxMacControl::SetMaximum( wxInt32 v
)
1185 ::SetControl32BitMaximum( m_controlRef
, v
);
1188 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
1190 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1191 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1192 ::SetControl32BitValue( m_controlRef
, value
);
1195 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown
))
1199 void wxMacControl::SuperChangedPosition()
1203 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
, bool ignoreBlack
)
1206 #if wxOSX_USE_CORE_TEXT
1207 if ( UMAGetSystemVersion() >= 0x1050 )
1209 HIViewPartCode part
= 0;
1210 HIThemeTextHorizontalFlush flush
= kHIThemeTextHorizontalFlushDefault
;
1211 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1212 flush
= kHIThemeTextHorizontalFlushCenter
;
1213 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1214 flush
= kHIThemeTextHorizontalFlushRight
;
1215 HIViewSetTextFont( m_controlRef
, part
, (CTFontRef
) font
.MacGetCTFont() );
1216 HIViewSetTextHorizontalFlush( m_controlRef
, part
, flush
);
1218 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1220 ControlFontStyleRec fontStyle
;
1221 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1222 fontStyle
.flags
= kControlUseForeColorMask
;
1223 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1227 #if wxOSX_USE_ATSU_TEXT
1228 ControlFontStyleRec fontStyle
;
1229 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
1231 switch ( font
.MacGetThemeFontID() )
1233 case kThemeSmallSystemFont
:
1234 fontStyle
.font
= kControlFontSmallSystemFont
;
1237 case 109 : // mini font
1238 fontStyle
.font
= -5;
1241 case kThemeSystemFont
:
1242 fontStyle
.font
= kControlFontBigSystemFont
;
1246 fontStyle
.font
= kControlFontBigSystemFont
;
1250 fontStyle
.flags
= kControlUseFontMask
;
1254 fontStyle
.font
= font
.MacGetFontNum();
1255 fontStyle
.style
= font
.MacGetFontStyle();
1256 fontStyle
.size
= font
.MacGetFontSize();
1257 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1260 fontStyle
.just
= teJustLeft
;
1261 fontStyle
.flags
|= kControlUseJustMask
;
1262 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1263 fontStyle
.just
= teJustCenter
;
1264 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1265 fontStyle
.just
= teJustRight
;
1268 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1269 // won't get grayed out by the system anymore
1271 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1273 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1274 fontStyle
.flags
|= kControlUseForeColorMask
;
1277 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1281 void wxMacControl::SetBackgroundColour( const wxColour
&WXUNUSED(col
) )
1283 // HITextViewSetBackgroundColor( m_textView , color );
1286 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1288 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1289 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1292 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1294 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
);
1297 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1299 SetControlAction( m_controlRef
, actionProc
);
1302 SInt32
wxMacControl::GetViewSize() const
1304 return GetControlViewSize( m_controlRef
);
1307 bool wxMacControl::IsVisible() const
1309 return IsControlVisible( m_controlRef
);
1312 void wxMacControl::SetVisibility( bool visible
)
1314 SetControlVisibility( m_controlRef
, visible
, true );
1317 bool wxMacControl::IsEnabled() const
1319 return IsControlEnabled( m_controlRef
);
1322 bool wxMacControl::IsActive() const
1324 return IsControlActive( m_controlRef
);
1327 void wxMacControl::Enable( bool enable
)
1330 EnableControl( m_controlRef
);
1332 DisableControl( m_controlRef
);
1335 void wxMacControl::SetDrawingEnabled( bool enable
)
1337 HIViewSetDrawingEnabled( m_controlRef
, enable
);
1340 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1342 GetControlBounds( m_controlRef
, r
) ;
1344 WindowRef tlwref
= GetControlOwner( m_controlRef
) ;
1346 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) tlwref
) ;
1347 if ( tlwwx
!= NULL
)
1349 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
1350 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
1351 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(m_controlRef
) , rootControl
) ;
1352 OffsetRect( r
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
1356 void wxMacControl::GetBestRect( wxRect
*rect
) const
1358 short baselineoffset
;
1361 GetBestControlRect( m_controlRef
, &r
, &baselineoffset
);
1362 *rect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
-r
.top
);
1365 void wxMacControl::GetBestRect( Rect
*r
) const
1367 short baselineoffset
;
1368 GetBestControlRect( m_controlRef
, r
, &baselineoffset
);
1371 void wxMacControl::SetLabel( const wxString
&title
, wxFontEncoding encoding
)
1373 SetControlTitleWithCFString( m_controlRef
, wxCFStringRef( title
, encoding
) );
1376 void wxMacControl::GetFeatures( UInt32
* features
)
1378 GetControlFeatures( m_controlRef
, features
);
1381 OSStatus
wxMacControl::GetRegion( ControlPartCode partCode
, RgnHandle region
)
1383 OSStatus err
= GetControlRegion( m_controlRef
, partCode
, region
);
1387 void wxMacControl::PulseGauge()
1391 // SetNeedsDisplay would not invalidate the children
1392 static void InvalidateControlAndChildren( HIViewRef control
)
1394 HIViewSetNeedsDisplay( control
, true );
1395 UInt16 childrenCount
= 0;
1396 OSStatus err
= CountSubControls( control
, &childrenCount
);
1397 if ( err
== errControlIsNotEmbedder
)
1400 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") );
1402 for ( UInt16 i
= childrenCount
; i
>=1; --i
)
1406 err
= GetIndexedSubControl( control
, i
, & child
);
1407 if ( err
== errControlIsNotEmbedder
)
1410 InvalidateControlAndChildren( child
);
1414 void wxMacControl::InvalidateWithChildren()
1416 InvalidateControlAndChildren( m_controlRef
);
1419 OSType wxMacCreator
= 'WXMC';
1420 OSType wxMacControlProperty
= 'MCCT';
1422 void wxMacControl::SetReferenceInNativeControl()
1425 verify_noerr( SetControlProperty ( m_controlRef
,
1426 wxMacCreator
,wxMacControlProperty
, sizeof(data
), &data
) );
1429 wxMacControl
* wxMacControl::GetReferenceFromNativeControl(ControlRef control
)
1431 wxMacControl
* ctl
= NULL
;
1432 ByteCount actualSize
;
1433 if ( GetControlProperty( control
,wxMacCreator
,wxMacControlProperty
, sizeof(ctl
) ,
1434 &actualSize
, &ctl
) == noErr
)
1441 void wxMacControl::SetBitmap( const wxBitmap
& WXUNUSED(bmp
) )
1443 // implemented in the respective subclasses
1446 void wxMacControl::SetScrollThumb( wxInt32
WXUNUSED(pos
), wxInt32
WXUNUSED(viewsize
) )
1448 // implemented in respective subclass
1455 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1457 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
);
1464 wxWidgetImplType
* wxWidgetImpl::CreateContentView( wxNonOwnedWindow
* now
)
1466 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1467 // the content view, so we have to retrieve it explicitly
1469 wxMacControl
* contentview
= new wxMacControl(now
, true /*isRootControl*/);
1470 HIViewFindByID( HIViewGetRoot( (WindowRef
) now
->GetWXWindow() ) , kHIViewWindowContentID
,
1471 contentview
->GetControlRefAddr() ) ;
1472 if ( !contentview
->IsOk() )
1474 // compatibility mode fallback
1475 GetRootControl( (WindowRef
) now
->GetWXWindow() , contentview
->GetControlRefAddr() ) ;
1478 // the root control level handler
1479 contentview
->InstallEventHandler() ;