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
);
213 if ( thisWindow
->MacDoRedraw( updateRgn
, cEvent
.GetTicks() ) )
216 thisWindow
->MacSetCGContextRef( NULL
) ;
220 CGContextRelease( cgContext
) ;
224 DisposeRgn( allocatedRgn
) ;
228 case kEventControlVisibilityChanged
:
229 // we might have two native controls attributed to the same wxWindow instance
230 // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
231 // control, as otherwise native and wx visibility are different
232 if ( thisWindow
->GetPeer() != NULL
&& thisWindow
->GetPeer()->GetControlRef() == controlRef
)
234 thisWindow
->MacVisibilityChanged() ;
238 case kEventControlEnabledStateChanged
:
239 thisWindow
->MacEnabledStateChanged();
242 case kEventControlHiliteChanged
:
243 thisWindow
->MacHiliteChanged() ;
246 case kEventControlActivate
:
247 case kEventControlDeactivate
:
248 // FIXME: we should have a virtual function for this!
250 if ( thisWindow
->IsKindOf( CLASSINFO( wxTreeCtrl
) ) )
251 thisWindow
->Refresh();
254 if ( thisWindow
->IsKindOf( CLASSINFO( wxListCtrl
) ) )
255 thisWindow
->Refresh();
261 // different handling on OS X
264 case kEventControlFocusPartChanged
:
265 // the event is emulated by wxmac for systems lower than 10.5
267 if ( UMAGetSystemVersion() < 0x1050 )
269 // as it is synthesized here, we have to manually avoid propagation
272 ControlPartCode previousControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPreviousPart
, typeControlPartCode
);
273 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlCurrentPart
, typeControlPartCode
);
275 if ( thisWindow
->MacGetTopLevelWindow() && thisWindow
->GetPeer()->NeedsFocusRect() )
277 thisWindow
->MacInvalidateBorders();
280 if ( currentControlPart
== 0 )
284 if ( thisWindow
->GetCaret() )
285 thisWindow
->GetCaret()->OnKillFocus();
288 wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast<void*>(thisWindow
));
290 // remove this as soon as posting the synthesized event works properly
291 static bool inKillFocusEvent
= false ;
293 if ( !inKillFocusEvent
)
295 inKillFocusEvent
= true ;
296 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
297 event
.SetEventObject(thisWindow
);
298 event
.SetWindow(targetFocusWindow
);
299 thisWindow
->HandleWindowEvent(event
) ;
300 inKillFocusEvent
= false ;
301 targetFocusWindow
= NULL
;
304 else if ( previousControlPart
== 0 )
307 // panel wants to track the window which was the last to have focus in it
308 wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast<void*>(thisWindow
));
309 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
310 thisWindow
->HandleWindowEvent(eventFocus
);
313 if ( thisWindow
->GetCaret() )
314 thisWindow
->GetCaret()->OnSetFocus();
317 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
318 event
.SetEventObject(thisWindow
);
319 event
.SetWindow(formerFocusWindow
);
320 thisWindow
->HandleWindowEvent(event
) ;
321 formerFocusWindow
= NULL
;
325 case kEventControlSetFocusPart
:
327 Boolean focusEverything
= false ;
328 if ( cEvent
.GetParameter
<Boolean
>(kEventParamControlFocusEverything
, &focusEverything
) == noErr
)
330 // put a breakpoint here to catch focus everything events
332 ControlPartCode controlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
333 if ( controlPart
!= kControlFocusNoPart
)
335 targetFocusWindow
= thisWindow
;
336 wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), static_cast<void*>(thisWindow
));
340 formerFocusWindow
= thisWindow
;
341 wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), static_cast<void*>(thisWindow
));
344 ControlPartCode previousControlPart
= 0;
345 verify_noerr( HIViewGetFocusPart(controlRef
, &previousControlPart
));
347 if ( thisWindow
->MacIsUserPane() )
349 if ( controlPart
!= kControlFocusNoPart
)
350 cEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPart
, typeControlPartCode
, 1 ) ;
354 result
= CallNextEventHandler(handler
, event
);
356 if ( UMAGetSystemVersion() < 0x1050 )
358 // set back to 0 if problems arise
360 if ( result
== noErr
)
362 ControlPartCode currentControlPart
= cEvent
.GetParameter
<ControlPartCode
>(kEventParamControlPart
, typeControlPartCode
);
363 // synthesize the event focus changed event
364 EventRef evRef
= NULL
;
366 OSStatus err
= MacCreateEvent(
367 NULL
, kEventClassControl
, kEventControlFocusPartChanged
, TicksToEventTime( TickCount() ) ,
368 kEventAttributeUserEvent
, &evRef
);
371 wxMacCarbonEvent
iEvent( evRef
) ;
372 iEvent
.SetParameter
<ControlRef
>( kEventParamDirectObject
, controlRef
);
373 iEvent
.SetParameter
<EventTargetRef
>( kEventParamPostTarget
, typeEventTargetRef
, GetControlEventTarget( controlRef
) );
374 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlPreviousPart
, typeControlPartCode
, previousControlPart
);
375 iEvent
.SetParameter
<ControlPartCode
>( kEventParamControlCurrentPart
, typeControlPartCode
, currentControlPart
);
378 // TODO test this first, avoid double posts etc...
379 PostEventToQueue( GetMainEventQueue(), evRef
, kEventPriorityHigh
);
381 wxMacWindowControlEventHandler( NULL
, evRef
, data
) ;
383 ReleaseEvent( evRef
) ;
386 // old implementation, to be removed if the new one works
387 if ( controlPart
== kControlFocusNoPart
)
390 if ( thisWindow
->GetCaret() )
391 thisWindow
->GetCaret()->OnKillFocus();
394 wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast<void*>(thisWindow
));
396 static bool inKillFocusEvent
= false ;
398 if ( !inKillFocusEvent
)
400 inKillFocusEvent
= true ;
401 wxFocusEvent
event( wxEVT_KILL_FOCUS
, thisWindow
->GetId());
402 event
.SetEventObject(thisWindow
);
403 thisWindow
->HandleWindowEvent(event
) ;
404 inKillFocusEvent
= false ;
409 // panel wants to track the window which was the last to have focus in it
410 wxLogTrace(_T("Focus"), _T("focus set(%p)"), static_cast<void*>(thisWindow
));
411 wxChildFocusEvent
eventFocus((wxWindow
*)thisWindow
);
412 thisWindow
->HandleWindowEvent(eventFocus
);
415 if ( thisWindow
->GetCaret() )
416 thisWindow
->GetCaret()->OnSetFocus();
419 wxFocusEvent
event(wxEVT_SET_FOCUS
, thisWindow
->GetId());
420 event
.SetEventObject(thisWindow
);
421 thisWindow
->HandleWindowEvent(event
) ;
428 case kEventControlHit
:
429 result
= thisWindow
->MacControlHit( handler
, event
) ;
432 case kEventControlGetClickActivation
:
434 // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise)
435 WindowRef owner
= cEvent
.GetParameter
<WindowRef
>(kEventParamWindowRef
);
436 if ( !IsWindowActive(owner
) )
438 cEvent
.SetParameter(kEventParamClickActivation
,typeClickActivationResult
, (UInt32
) kActivateAndIgnoreClick
) ;
451 static pascal OSStatus
452 wxMacWindowServiceEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
456 OSStatus result
= eventNotHandledErr
;
458 wxMacCarbonEvent
cEvent( event
) ;
460 ControlRef controlRef
;
461 wxWindowMac
* thisWindow
= (wxWindowMac
*) data
;
462 wxTextCtrl
* textCtrl
= wxDynamicCast( thisWindow
, wxTextCtrl
) ;
463 cEvent
.GetParameter( kEventParamDirectObject
, &controlRef
) ;
465 switch ( GetEventKind( event
) )
467 case kEventServiceGetTypes
:
471 textCtrl
->GetSelection( &from
, &to
) ;
473 CFMutableArrayRef copyTypes
= 0 , pasteTypes
= 0;
475 copyTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServiceCopyTypes
, typeCFMutableArrayRef
) ;
476 if ( textCtrl
->IsEditable() )
477 pasteTypes
= cEvent
.GetParameter
< CFMutableArrayRef
>( kEventParamServicePasteTypes
, typeCFMutableArrayRef
) ;
479 static const OSType textDataTypes
[] = { kTXNTextData
/* , 'utxt', 'PICT', 'MooV', 'AIFF' */ };
480 for ( size_t i
= 0 ; i
< WXSIZEOF(textDataTypes
) ; ++i
)
482 CFStringRef typestring
= CreateTypeStringWithOSType(textDataTypes
[i
]);
486 CFArrayAppendValue(copyTypes
, typestring
) ;
488 CFArrayAppendValue(pasteTypes
, typestring
) ;
490 CFRelease( typestring
) ;
498 case kEventServiceCopy
:
503 textCtrl
->GetSelection( &from
, &to
) ;
504 wxString val
= textCtrl
->GetValue() ;
505 val
= val
.Mid( from
, to
- from
) ;
506 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
507 verify_noerr( PasteboardClear( pasteboard
) ) ;
508 PasteboardSynchronize( pasteboard
);
509 // TODO add proper conversion
510 CFDataRef data
= CFDataCreate( kCFAllocatorDefault
, (const UInt8
*)val
.c_str(), val
.length() );
511 PasteboardPutItemFlavor( pasteboard
, (PasteboardItemID
) 1, CFSTR("com.apple.traditional-mac-plain-text"), data
, 0);
517 case kEventServicePaste
:
520 PasteboardRef pasteboard
= cEvent
.GetParameter
<PasteboardRef
>( kEventParamPasteboardRef
, typePasteboardRef
);
521 PasteboardSynchronize( pasteboard
);
523 verify_noerr( PasteboardGetItemCount( pasteboard
, &itemCount
) );
524 for( UInt32 itemIndex
= 1; itemIndex
<= itemCount
; itemIndex
++ )
526 PasteboardItemID itemID
;
527 if ( PasteboardGetItemIdentifier( pasteboard
, itemIndex
, &itemID
) == noErr
)
529 CFDataRef flavorData
= NULL
;
530 if ( PasteboardCopyItemFlavorData( pasteboard
, itemID
, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData
) == noErr
)
532 CFIndex flavorDataSize
= CFDataGetLength( flavorData
);
533 char *content
= new char[flavorDataSize
+1] ;
534 memcpy( content
, CFDataGetBytePtr( flavorData
), flavorDataSize
);
535 content
[flavorDataSize
]=0;
536 CFRelease( flavorData
);
538 textCtrl
->WriteText( wxString( content
, wxConvLocal
) );
540 textCtrl
->WriteText( wxString( content
) ) ;
558 pascal OSStatus
wxMacUnicodeTextEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
560 OSStatus result
= eventNotHandledErr
;
561 wxWindowMac
* focus
= (wxWindowMac
*) data
;
563 wchar_t* uniChars
= NULL
;
564 UInt32 when
= EventTimeToTicks( GetEventTime( event
) ) ;
566 UniChar
* charBuf
= NULL
;
567 ByteCount dataSize
= 0 ;
570 if ( GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, 0 , &dataSize
, NULL
) == noErr
)
572 numChars
= dataSize
/ sizeof( UniChar
) + 1;
575 if ( (size_t) numChars
* 2 > sizeof(buf
) )
576 charBuf
= new UniChar
[ numChars
] ;
580 uniChars
= new wchar_t[ numChars
] ;
581 GetEventParameter( event
, kEventParamTextInputSendText
, typeUnicodeText
, NULL
, dataSize
, NULL
, charBuf
) ;
582 charBuf
[ numChars
- 1 ] = 0;
583 #if SIZEOF_WCHAR_T == 2
584 uniChars
= (wchar_t*) charBuf
;
585 /* 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...)
587 // the resulting string will never have more chars than the utf16 version, so this is safe
588 wxMBConvUTF16 converter
;
589 numChars
= converter
.MB2WC( uniChars
, (const char*)charBuf
, numChars
) ;
593 switch ( GetEventKind( event
) )
595 case kEventTextInputUpdateActiveInputArea
:
597 // An IME input event may return several characters, but we need to send one char at a time to
599 for (int pos
=0 ; pos
< numChars
; pos
++)
601 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
602 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
603 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
605 UInt32 message
= uniChars
[pos
] < 128 ? (char)uniChars
[pos
] : '?';
607 NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent
608 multiple times to update the active range during inline input, so this handler will often receive
609 uncommited text, which should usually not trigger side effects. It might be a good idea to check the
610 kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h).
611 On the other hand, it can be useful for some applications to react to uncommitted text (for example,
612 to update a status display), as long as it does not disrupt the inline input session. Ideally, wx
613 should add new event types to support advanced text input. For now, I would keep things as they are.
615 However, the code that was being used caused additional problems:
616 UInt32 message = (0 << 8) + ((char)uniChars[pos] );
617 Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline
618 input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji
619 for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB
620 (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D
621 (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress.
622 Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only
623 overlap with Unicode within the (7-bit) ASCII range.
624 But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks
625 for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII
626 characters as they are and replaces the rest with '?', ensuring that update events are triggered.
627 It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but
628 I don't have time to look into that right now.
631 if ( wxTheApp
->MacSendCharEvent(
632 focus
, message
, 0 , when
, 0 , 0 , uniChars
[pos
] ) )
637 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
641 case kEventTextInputUnicodeForKeyEvent
:
643 UInt32 keyCode
, modifiers
;
646 unsigned char charCode
;
648 GetEventParameter( event
, kEventParamTextInputSendKeyboardEvent
, typeEventRef
, NULL
, sizeof(rawEvent
), NULL
, &rawEvent
) ;
649 GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
, sizeof(char), NULL
, &charCode
);
650 GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &keyCode
);
651 GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
);
652 GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, sizeof(Point
), NULL
, &point
);
654 UInt32 message
= (keyCode
<< 8) + charCode
;
656 // An IME input event may return several characters, but we need to send one char at a time to
658 for (int pos
=0 ; pos
< numChars
; pos
++)
660 WXEVENTREF formerEvent
= wxTheApp
->MacGetCurrentEvent() ;
661 WXEVENTHANDLERCALLREF formerHandler
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
662 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
664 if ( wxTheApp
->MacSendCharEvent(
665 focus
, message
, modifiers
, when
, point
.h
, point
.v
, uniChars
[pos
] ) )
670 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerHandler
) ;
679 if ( charBuf
!= buf
)
685 static pascal OSStatus
686 wxMacWindowCommandEventHandler(EventHandlerCallRef
WXUNUSED(handler
),
690 OSStatus result
= eventNotHandledErr
;
691 wxWindowMac
* focus
= (wxWindowMac
*) data
;
695 wxMacCarbonEvent
cEvent( event
) ;
696 cEvent
.GetParameter
<HICommand
>(kEventParamDirectObject
,typeHICommand
,&command
) ;
698 wxMenuItem
* item
= NULL
;
699 wxMenu
* itemMenu
= wxFindMenuFromMacCommand( command
, item
) ;
703 wxASSERT( itemMenu
!= NULL
) ;
705 switch ( cEvent
.GetKind() )
707 case kEventProcessCommand
:
708 if ( itemMenu
->HandleCommandProcess( item
, focus
) )
712 case kEventCommandUpdateStatus
:
713 if ( itemMenu
->HandleCommandUpdateStatus( item
, focus
) )
724 pascal OSStatus
wxMacWindowEventHandler( EventHandlerCallRef handler
, EventRef event
, void *data
)
726 EventRef formerEvent
= (EventRef
) wxTheApp
->MacGetCurrentEvent() ;
727 EventHandlerCallRef formerEventHandlerCallRef
= (EventHandlerCallRef
) wxTheApp
->MacGetCurrentEventHandlerCallRef() ;
728 wxTheApp
->MacSetCurrentEvent( event
, handler
) ;
729 OSStatus result
= eventNotHandledErr
;
731 switch ( GetEventClass( event
) )
733 case kEventClassCommand
:
734 result
= wxMacWindowCommandEventHandler( handler
, event
, data
) ;
737 case kEventClassControl
:
738 result
= wxMacWindowControlEventHandler( handler
, event
, data
) ;
741 case kEventClassService
:
742 result
= wxMacWindowServiceEventHandler( handler
, event
, data
) ;
745 case kEventClassTextInput
:
746 result
= wxMacUnicodeTextEventHandler( handler
, event
, data
) ;
753 wxTheApp
->MacSetCurrentEvent( formerEvent
, formerEventHandlerCallRef
) ;
758 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler
)
760 // ---------------------------------------------------------------------------
761 // Scrollbar Tracking for all
762 // ---------------------------------------------------------------------------
764 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
) ;
765 pascal void wxMacLiveScrollbarActionProc( ControlRef control
, ControlPartCode partCode
)
769 wxWindow
* wx
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
772 wxEventType scrollEvent
= wxEVT_NULL
;
775 case kControlUpButtonPart
:
776 scrollEvent
= wxEVT_SCROLL_LINEUP
;
779 case kControlDownButtonPart
:
780 scrollEvent
= wxEVT_SCROLL_LINEDOWN
;
783 case kControlPageUpPart
:
784 scrollEvent
= wxEVT_SCROLL_PAGEUP
;
787 case kControlPageDownPart
:
788 scrollEvent
= wxEVT_SCROLL_PAGEDOWN
;
791 case kControlIndicatorPart
:
792 scrollEvent
= wxEVT_SCROLL_THUMBTRACK
;
793 // when this is called as a live proc, mouse is always still down
794 // so no need for thumbrelease
795 // scrollEvent = wxEVT_SCROLL_THUMBRELEASE;
798 wx
->TriggerScrollEvent(scrollEvent
) ;
802 wxMAC_DEFINE_PROC_GETTER( ControlActionUPP
, wxMacLiveScrollbarActionProc
) ;
804 wxWidgetImplType
* wxWidgetImpl::CreateUserPane( wxWindowMac
* wxpeer
, wxWindowMac
* parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
,
805 long style
, long extraStyle
)
807 OSStatus err
= noErr
;
808 Rect bounds
= wxMacGetBoundsForControl( wxpeer
, pos
, size
) ;
809 wxMacControl
* c
= new wxMacControl(wxpeer
) ;
811 | kControlSupportsEmbedding
812 | kControlSupportsLiveFeedback
813 | kControlGetsFocusOnClick
814 // | kControlHasSpecialBackground
815 // | kControlSupportsCalcBestRect
816 | kControlHandlesTracking
817 | kControlSupportsFocus
818 | kControlWantsActivate
819 | kControlWantsIdle
;
821 err
=::CreateUserPaneControl( MAC_WXHWND(wxpeer
->GetParent()->MacGetTopLevelWindowRef()) , &bounds
, features
, c
->GetControlRefAddr() );
827 void wxMacControl::InstallEventHandler( WXWidget control
)
829 wxWidgetImpl::Associate( control
? control
: (WXWidget
) m_controlRef
, this ) ;
830 ::InstallControlEventHandler( control
? (ControlRef
) control
: m_controlRef
, GetwxMacWindowEventHandlerUPP(),
831 GetEventTypeCount(eventList
), eventList
, GetWXPeer(), NULL
);
834 IMPLEMENT_DYNAMIC_CLASS( wxMacControl
, wxWidgetImpl
)
836 wxMacControl::wxMacControl()
841 wxMacControl::wxMacControl(wxWindowMac
* peer
, bool isRootControl
) :
842 wxWidgetImpl( peer
, isRootControl
)
847 wxMacControl::~wxMacControl()
849 if ( m_controlRef
&& !IsRootControl() )
851 wxASSERT_MSG( m_controlRef
!= NULL
, wxT("Control Handle already NULL, Dispose called twice ?") );
852 wxASSERT_MSG( IsValidControlHandle(m_controlRef
) , wxT("Invalid Control Handle (maybe already released) in Dispose") );
854 wxWidgetImpl::RemoveAssociations( this ) ;
855 // we cannot check the ref count here anymore, as autorelease objects might delete their refs later
856 // we can have situations when being embedded, where the control gets deleted behind our back, so only
857 // CFRelease if we are safe
858 if ( IsValidControlHandle(m_controlRef
) )
859 CFRelease(m_controlRef
);
864 void wxMacControl::Init()
867 m_macControlEventHandler
= NULL
;
870 void wxMacControl::RemoveFromParent()
872 // nothing to do here for carbon
873 HIViewRemoveFromSuperview(m_controlRef
);
876 void wxMacControl::Embed( wxWidgetImpl
*parent
)
878 HIViewAddSubview((ControlRef
)parent
->GetWXWidget(), m_controlRef
);
881 void wxMacControl::SetNeedsDisplay( const wxRect
* rect
)
888 HIRect updatearea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
889 HIViewSetNeedsDisplayInRect( m_controlRef
, &updatearea
, true );
892 HIViewSetNeedsDisplay( m_controlRef
, true );
895 void wxMacControl::Raise()
897 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderAbove
, NULL
) );
900 void wxMacControl::Lower()
902 verify_noerr( HIViewSetZOrder( m_controlRef
, kHIViewZOrderBelow
, NULL
) );
905 void wxMacControl::GetContentArea(int &left
, int &top
, int &width
, int &height
) const
907 RgnHandle rgn
= NewRgn() ;
909 if ( GetControlRegion( m_controlRef
, kControlContentMetaPart
, rgn
) == noErr
)
910 GetRegionBounds( rgn
, &content
) ;
913 GetControlBounds( m_controlRef
, &content
);
914 content
.right
-= content
.left
;
916 content
.bottom
-= content
.top
;
924 width
= content
.right
- content
.left
;
925 height
= content
.bottom
- content
.top
;
928 void wxMacControl::Move(int x
, int y
, int width
, int height
)
930 HIRect hir
= CGRectMake(x
,y
,width
,height
);
931 HIViewSetFrame ( m_controlRef
, &hir
);
934 void wxMacControl::GetPosition( int &x
, int &y
) const
937 GetControlBounds( m_controlRef
, &r
);
942 void wxMacControl::GetSize( int &width
, int &height
) const
945 GetControlBounds( m_controlRef
, &r
);
946 width
= r
.right
- r
.left
;
947 height
= r
.bottom
- r
.top
;
950 void wxMacControl::SetControlSize( wxWindowVariant variant
)
955 case wxWINDOW_VARIANT_NORMAL
:
956 size
= kControlSizeNormal
;
959 case wxWINDOW_VARIANT_SMALL
:
960 size
= kControlSizeSmall
;
963 case wxWINDOW_VARIANT_MINI
:
964 // not always defined in the headers
968 case wxWINDOW_VARIANT_LARGE
:
969 size
= kControlSizeLarge
;
973 wxFAIL_MSG(_T("unexpected window variant"));
977 SetData
<ControlSize
>(kControlEntireControl
, kControlSizeTag
, &size
) ;
980 void wxMacControl::ScrollRect( const wxRect
*rect
, int dx
, int dy
)
982 if (GetNeedsDisplay() )
984 // because HIViewScrollRect does not scroll the already invalidated area we have two options:
985 // in case there is already a pending redraw on that area
986 // either immediate redraw or full invalidate
988 // is the better overall solution, as it does not slow down scrolling
991 // this would be the preferred version for fast drawing controls
992 HIViewRender(GetControlRef()) ;
996 // note there currently is a bug in OSX (10.3 +?) which makes inefficient refreshes in case an entire control
997 // area is scrolled, this does not occur if width and height are 2 pixels less,
998 // TODO: write optimal workaround
1000 HIRect scrollarea
= CGRectMake( rect
->x
, rect
->y
, rect
->width
, rect
->height
);
1001 HIViewScrollRect ( m_controlRef
, &scrollarea
, dx
,dy
);
1004 // this would be the preferred version for fast drawing controls
1005 HIViewRender(GetControlRef()) ;
1009 bool wxMacControl::CanFocus() const
1011 // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so
1012 // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning,
1013 // but the value range is nowhere documented
1014 Boolean keyExistsAndHasValidFormat
;
1015 CFIndex fullKeyboardAccess
= CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
1016 kCFPreferencesCurrentApplication
, &keyExistsAndHasValidFormat
);
1018 if ( keyExistsAndHasValidFormat
&& fullKeyboardAccess
> 0 )
1024 UInt32 features
= 0 ;
1025 GetControlFeatures( m_controlRef
, &features
) ;
1027 return features
& ( kControlSupportsFocus
| kControlGetsFocusOnClick
) ;
1031 bool wxMacControl::GetNeedsDisplay() const
1033 return HIViewGetNeedsDisplay( m_controlRef
);
1036 void wxWidgetImpl::Convert( wxPoint
*pt
, wxWidgetImpl
*from
, wxWidgetImpl
*to
)
1042 HIViewConvertPoint( &hiPoint
, (ControlRef
) from
->GetWXWidget() , (ControlRef
) to
->GetWXWidget() );
1043 pt
->x
= (int)hiPoint
.x
;
1044 pt
->y
= (int)hiPoint
.y
;
1047 bool wxMacControl::SetFocus()
1049 // as we cannot rely on the control features to find out whether we are in full keyboard mode,
1050 // we can only leave in case of an error
1052 OSStatus err
= SetKeyboardFocus( GetControlOwner( m_controlRef
), m_controlRef
, kControlFocusNextPart
);
1053 if ( err
== errCouldntSetFocus
)
1055 SetUserFocusWindow(GetControlOwner( m_controlRef
) );
1060 bool wxMacControl::HasFocus() const
1063 GetKeyboardFocus( GetUserFocusWindow() , &control
);
1064 return control
== m_controlRef
;
1067 void wxMacControl::SetCursor(const wxCursor
& cursor
)
1069 wxWindowMac
*mouseWin
= 0 ;
1070 WindowRef window
= GetControlOwner( m_controlRef
) ;
1072 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) window
) ;
1073 if ( tlwwx
!= NULL
)
1075 ControlPartCode part
;
1076 ControlRef control
;
1078 #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
1080 HIGetMousePosition(kHICoordSpaceWindow
, window
, &hiPoint
);
1084 GetGlobalMouse( &pt
);
1087 tlwwx
->ScreenToClient(&x
, &y
);
1091 control
= FindControlUnderMouse( pt
, window
, &part
) ;
1093 mouseWin
= wxFindWindowFromWXWidget( (WXWidget
) control
) ;
1096 if ( mouseWin
== tlwwx
&& !wxIsBusy() )
1097 cursor
.MacInstall() ;
1100 void wxMacControl::CaptureMouse()
1104 void wxMacControl::ReleaseMouse()
1109 // subclass specifics
1112 OSStatus
wxMacControl::GetData(ControlPartCode inPartCode
, ResType inTag
, Size inBufferSize
, void * inOutBuffer
, Size
* outActualSize
) const
1114 return ::GetControlData( m_controlRef
, inPartCode
, inTag
, inBufferSize
, inOutBuffer
, outActualSize
);
1117 OSStatus
wxMacControl::GetDataSize(ControlPartCode inPartCode
, ResType inTag
, Size
* outActualSize
) const
1119 return ::GetControlDataSize( m_controlRef
, inPartCode
, inTag
, outActualSize
);
1122 OSStatus
wxMacControl::SetData(ControlPartCode inPartCode
, ResType inTag
, Size inSize
, const void * inData
)
1124 return ::SetControlData( m_controlRef
, inPartCode
, inTag
, inSize
, inData
);
1127 OSStatus
wxMacControl::SendEvent( EventRef event
, OptionBits inOptions
)
1129 return SendEventToEventTargetWithOptions( event
,
1130 HIObjectGetEventTarget( (HIObjectRef
) m_controlRef
), inOptions
);
1133 OSStatus
wxMacControl::SendHICommand( HICommand
&command
, OptionBits inOptions
)
1135 wxMacCarbonEvent
event( kEventClassCommand
, kEventCommandProcess
);
1137 event
.SetParameter
<HICommand
>(kEventParamDirectObject
,command
);
1139 return SendEvent( event
, inOptions
);
1142 OSStatus
wxMacControl::SendHICommand( UInt32 commandID
, OptionBits inOptions
)
1146 memset( &command
, 0 , sizeof(command
) );
1147 command
.commandID
= commandID
;
1148 return SendHICommand( command
, inOptions
);
1151 void wxMacControl::PerformClick()
1153 HIViewSimulateClick (m_controlRef
, kControlButtonPart
, 0, NULL
);
1156 wxInt32
wxMacControl::GetValue() const
1158 return ::GetControl32BitValue( m_controlRef
);
1161 wxInt32
wxMacControl::GetMaximum() const
1163 return ::GetControl32BitMaximum( m_controlRef
);
1166 wxInt32
wxMacControl::GetMinimum() const
1168 return ::GetControl32BitMinimum( m_controlRef
);
1171 void wxMacControl::SetValue( wxInt32 v
)
1173 ::SetControl32BitValue( m_controlRef
, v
);
1176 void wxMacControl::SetMinimum( wxInt32 v
)
1178 ::SetControl32BitMinimum( m_controlRef
, v
);
1181 void wxMacControl::SetMaximum( wxInt32 v
)
1183 ::SetControl32BitMaximum( m_controlRef
, v
);
1186 void wxMacControl::SetValueAndRange( SInt32 value
, SInt32 minimum
, SInt32 maximum
)
1188 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1189 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1190 ::SetControl32BitValue( m_controlRef
, value
);
1193 void wxMacControl::VisibilityChanged(bool WXUNUSED(shown
))
1197 void wxMacControl::SuperChangedPosition()
1201 void wxMacControl::SetFont( const wxFont
& font
, const wxColour
& foreground
, long windowStyle
, bool ignoreBlack
)
1204 #if wxOSX_USE_CORE_TEXT
1205 if ( UMAGetSystemVersion() >= 0x1050 )
1207 HIViewPartCode part
= 0;
1208 HIThemeTextHorizontalFlush flush
= kHIThemeTextHorizontalFlushDefault
;
1209 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1210 flush
= kHIThemeTextHorizontalFlushCenter
;
1211 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1212 flush
= kHIThemeTextHorizontalFlushRight
;
1213 HIViewSetTextFont( m_controlRef
, part
, (CTFontRef
) font
.MacGetCTFont() );
1214 HIViewSetTextHorizontalFlush( m_controlRef
, part
, flush
);
1216 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1218 ControlFontStyleRec fontStyle
;
1219 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1220 fontStyle
.flags
= kControlUseForeColorMask
;
1221 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1225 #if wxOSX_USE_ATSU_TEXT
1226 ControlFontStyleRec fontStyle
;
1227 if ( font
.MacGetThemeFontID() != kThemeCurrentPortFont
)
1229 switch ( font
.MacGetThemeFontID() )
1231 case kThemeSmallSystemFont
:
1232 fontStyle
.font
= kControlFontSmallSystemFont
;
1235 case 109 : // mini font
1236 fontStyle
.font
= -5;
1239 case kThemeSystemFont
:
1240 fontStyle
.font
= kControlFontBigSystemFont
;
1244 fontStyle
.font
= kControlFontBigSystemFont
;
1248 fontStyle
.flags
= kControlUseFontMask
;
1252 fontStyle
.font
= font
.MacGetFontNum();
1253 fontStyle
.style
= font
.MacGetFontStyle();
1254 fontStyle
.size
= font
.MacGetFontSize();
1255 fontStyle
.flags
= kControlUseFontMask
| kControlUseFaceMask
| kControlUseSizeMask
;
1258 fontStyle
.just
= teJustLeft
;
1259 fontStyle
.flags
|= kControlUseJustMask
;
1260 if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_CENTER_HORIZONTAL
)
1261 fontStyle
.just
= teJustCenter
;
1262 else if ( ( windowStyle
& wxALIGN_MASK
) & wxALIGN_RIGHT
)
1263 fontStyle
.just
= teJustRight
;
1266 // we only should do this in case of a non-standard color, as otherwise 'disabled' controls
1267 // won't get grayed out by the system anymore
1269 if ( foreground
!= *wxBLACK
|| ignoreBlack
== false )
1271 foreground
.GetRGBColor( &fontStyle
.foreColor
);
1272 fontStyle
.flags
|= kControlUseForeColorMask
;
1275 ::SetControlFontStyle( m_controlRef
, &fontStyle
);
1279 void wxMacControl::SetBackgroundColour( const wxColour
&WXUNUSED(col
) )
1281 // HITextViewSetBackgroundColor( m_textView , color );
1284 void wxMacControl::SetRange( SInt32 minimum
, SInt32 maximum
)
1286 ::SetControl32BitMinimum( m_controlRef
, minimum
);
1287 ::SetControl32BitMaximum( m_controlRef
, maximum
);
1290 short wxMacControl::HandleKey( SInt16 keyCode
, SInt16 charCode
, EventModifiers modifiers
)
1292 return HandleControlKey( m_controlRef
, keyCode
, charCode
, modifiers
);
1295 void wxMacControl::SetActionProc( ControlActionUPP actionProc
)
1297 SetControlAction( m_controlRef
, actionProc
);
1300 SInt32
wxMacControl::GetViewSize() const
1302 return GetControlViewSize( m_controlRef
);
1305 bool wxMacControl::IsVisible() const
1307 return IsControlVisible( m_controlRef
);
1310 void wxMacControl::SetVisibility( bool visible
)
1312 SetControlVisibility( m_controlRef
, visible
, true );
1315 bool wxMacControl::IsEnabled() const
1317 return IsControlEnabled( m_controlRef
);
1320 bool wxMacControl::IsActive() const
1322 return IsControlActive( m_controlRef
);
1325 void wxMacControl::Enable( bool enable
)
1328 EnableControl( m_controlRef
);
1330 DisableControl( m_controlRef
);
1333 void wxMacControl::SetDrawingEnabled( bool enable
)
1335 HIViewSetDrawingEnabled( m_controlRef
, enable
);
1338 void wxMacControl::GetRectInWindowCoords( Rect
*r
)
1340 GetControlBounds( m_controlRef
, r
) ;
1342 WindowRef tlwref
= GetControlOwner( m_controlRef
) ;
1344 wxNonOwnedWindow
* tlwwx
= wxNonOwnedWindow::GetFromWXWindow( (WXWindow
) tlwref
) ;
1345 if ( tlwwx
!= NULL
)
1347 ControlRef rootControl
= tlwwx
->GetPeer()->GetControlRef() ;
1348 HIPoint hiPoint
= CGPointMake( 0 , 0 ) ;
1349 HIViewConvertPoint( &hiPoint
, HIViewGetSuperview(m_controlRef
) , rootControl
) ;
1350 OffsetRect( r
, (short) hiPoint
.x
, (short) hiPoint
.y
) ;
1354 void wxMacControl::GetBestRect( wxRect
*rect
) const
1356 short baselineoffset
;
1359 GetBestControlRect( m_controlRef
, &r
, &baselineoffset
);
1360 *rect
= wxRect( r
.left
, r
.top
, r
.right
- r
.left
, r
.bottom
-r
.top
);
1363 void wxMacControl::GetBestRect( Rect
*r
) const
1365 short baselineoffset
;
1366 GetBestControlRect( m_controlRef
, r
, &baselineoffset
);
1369 void wxMacControl::SetLabel( const wxString
&title
, wxFontEncoding encoding
)
1371 SetControlTitleWithCFString( m_controlRef
, wxCFStringRef( title
, encoding
) );
1374 void wxMacControl::GetFeatures( UInt32
* features
)
1376 GetControlFeatures( m_controlRef
, features
);
1379 OSStatus
wxMacControl::GetRegion( ControlPartCode partCode
, RgnHandle region
)
1381 OSStatus err
= GetControlRegion( m_controlRef
, partCode
, region
);
1385 void wxMacControl::PulseGauge()
1389 // SetNeedsDisplay would not invalidate the children
1390 static void InvalidateControlAndChildren( HIViewRef control
)
1392 HIViewSetNeedsDisplay( control
, true );
1393 UInt16 childrenCount
= 0;
1394 OSStatus err
= CountSubControls( control
, &childrenCount
);
1395 if ( err
== errControlIsNotEmbedder
)
1398 wxASSERT_MSG( err
== noErr
, wxT("Unexpected error when accessing subcontrols") );
1400 for ( UInt16 i
= childrenCount
; i
>=1; --i
)
1404 err
= GetIndexedSubControl( control
, i
, & child
);
1405 if ( err
== errControlIsNotEmbedder
)
1408 InvalidateControlAndChildren( child
);
1412 void wxMacControl::InvalidateWithChildren()
1414 InvalidateControlAndChildren( m_controlRef
);
1417 OSType wxMacCreator
= 'WXMC';
1418 OSType wxMacControlProperty
= 'MCCT';
1420 void wxMacControl::SetReferenceInNativeControl()
1423 verify_noerr( SetControlProperty ( m_controlRef
,
1424 wxMacCreator
,wxMacControlProperty
, sizeof(data
), &data
) );
1427 wxMacControl
* wxMacControl::GetReferenceFromNativeControl(ControlRef control
)
1429 wxMacControl
* ctl
= NULL
;
1430 ByteCount actualSize
;
1431 if ( GetControlProperty( control
,wxMacCreator
,wxMacControlProperty
, sizeof(ctl
) ,
1432 &actualSize
, &ctl
) == noErr
)
1439 void wxMacControl::SetBitmap( const wxBitmap
& WXUNUSED(bmp
) )
1441 // implemented in the respective subclasses
1444 void wxMacControl::SetScrollThumb( wxInt32
WXUNUSED(pos
), wxInt32
WXUNUSED(viewsize
) )
1446 // implemented in respective subclass
1453 OSStatus
wxMacControl::SetTabEnabled( SInt16 tabNo
, bool enable
)
1455 return ::SetTabEnabled( m_controlRef
, tabNo
, enable
);
1462 wxWidgetImplType
* wxWidgetImpl::CreateContentView( wxNonOwnedWindow
* now
)
1464 // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of
1465 // the content view, so we have to retrieve it explicitly
1467 wxMacControl
* contentview
= new wxMacControl(now
, true /*isRootControl*/);
1468 HIViewFindByID( HIViewGetRoot( (WindowRef
) now
->GetWXWindow() ) , kHIViewWindowContentID
,
1469 contentview
->GetControlRefAddr() ) ;
1470 if ( !contentview
->IsOk() )
1472 // compatibility mode fallback
1473 GetRootControl( (WindowRef
) now
->GetWXWindow() , contentview
->GetControlRefAddr() ) ;
1476 // the root control level handler
1477 contentview
->InstallEventHandler() ;