1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        mac/toplevel.cpp 
   3 // Purpose:     implements wxTopLevelWindow for Mac 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) 2001-2004 Stefan Csomor 
   9 // License:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "toplevel.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  33     #include "wx/toplevel.h" 
  35     #include "wx/string.h" 
  40 #include "wx/mac/uma.h" 
  41 #include "wx/mac/aga.h" 
  43 #include "wx/tooltip.h" 
  45 #if wxUSE_SYSTEM_OPTIONS 
  46     #include "wx/sysopt.h" 
  49 #include <ToolUtils.h> 
  52 #define wxMAC_DEBUG_REDRAW 0 
  53 #ifndef wxMAC_DEBUG_REDRAW 
  54 #define wxMAC_DEBUG_REDRAW 0 
  57 // ---------------------------------------------------------------------------- 
  59 // ---------------------------------------------------------------------------- 
  61 // list of all frames and modeless dialogs 
  62 wxWindowList       wxModelessWindows
; 
  64 // double click testing 
  65 static   Point     gs_lastWhere
; 
  66 static   long      gs_lastWhen 
= 0; 
  70 static pascal long wxShapedMacWindowDef(short varCode
, WindowRef window
, SInt16 message
, SInt32 param
); 
  73 // ============================================================================ 
  74 // wxTopLevelWindowMac implementation 
  75 // ============================================================================ 
  77 // --------------------------------------------------------------------------- 
  79 // --------------------------------------------------------------------------- 
  83 extern long wxMacTranslateKey(unsigned char key
, unsigned char code
) ; 
  85 static const EventTypeSpec eventList
[] = 
  87     { kEventClassTextInput
, kEventTextInputUnicodeForKeyEvent 
} , 
  89     { kEventClassKeyboard
, kEventRawKeyDown 
} , 
  90     { kEventClassKeyboard
, kEventRawKeyRepeat 
} , 
  91     { kEventClassKeyboard
, kEventRawKeyUp 
} , 
  92     { kEventClassKeyboard
, kEventRawKeyModifiersChanged 
} , 
  94     { kEventClassWindow 
, kEventWindowShown 
} , 
  95     { kEventClassWindow 
, kEventWindowUpdate 
} , 
  96     { kEventClassWindow 
, kEventWindowActivated 
} , 
  97     { kEventClassWindow 
, kEventWindowDeactivated 
} , 
  98     { kEventClassWindow 
, kEventWindowBoundsChanging 
} , 
  99     { kEventClassWindow 
, kEventWindowBoundsChanged 
} , 
 100     { kEventClassWindow 
, kEventWindowClose 
} , 
 102     { kEventClassMouse 
, kEventMouseDown 
} , 
 103     { kEventClassMouse 
, kEventMouseUp 
} , 
 104     { kEventClassMouse 
, kEventMouseWheelMoved 
} , 
 105     { kEventClassMouse 
, kEventMouseMoved 
} , 
 106     { kEventClassMouse 
, kEventMouseDragged 
} , 
 110 static pascal OSStatus 
TextInputEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 112     OSStatus result 
= eventNotHandledErr 
; 
 114     wxWindow
* focus 
= wxWindow::FindFocus() ; 
 122     GetEventParameter( event 
, kEventParamTextInputSendKeyboardEvent 
,typeEventRef
,NULL
,sizeof(rawEvent
),NULL
,&rawEvent 
) ; 
 124     GetEventParameter( rawEvent
, kEventParamKeyMacCharCodes
, typeChar
, NULL
,sizeof(char), NULL
,&charCode 
); 
 125     GetEventParameter( rawEvent
, kEventParamKeyCode
, typeUInt32
, NULL
,  sizeof(UInt32
), NULL
, &keyCode 
); 
 126        GetEventParameter( rawEvent
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
); 
 127     GetEventParameter( rawEvent
, kEventParamMouseLocation
, typeQDPoint
, NULL
, 
 128         sizeof( Point 
), NULL
, &point 
); 
 130     switch ( GetEventKind( event 
) ) 
 132         case kEventTextInputUnicodeForKeyEvent 
: 
 133             // this is only called when no default handler has jumped in, eg a wxControl on a floater window does not 
 134             // get its own kEventTextInputUnicodeForKeyEvent, so we route back the 
 135             wxControl
* control 
= wxDynamicCast( focus 
, wxControl 
) ; 
 138                 ControlHandle macControl 
= (ControlHandle
) control
->GetMacControl() ; 
 141                     ::HandleControlKey( macControl 
, keyCode 
, charCode 
, modifiers 
) ; 
 146             // this may lead to double events sent to a window in case all handlers have skipped the key down event 
 147             UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; 
 148             UInt32 message = (keyCode << 8) + charCode; 
 150             if ( (focus != NULL) && wxTheApp->MacSendKeyDownEvent( 
 151                 focus , message , modifiers , when , point.h , point.v ) ) 
 162 static pascal OSStatus 
KeyboardEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 164     OSStatus result 
= eventNotHandledErr 
; 
 166     wxWindow
* focus 
= wxWindow::FindFocus() ; 
 171     UInt32 when 
= EventTimeToTicks( GetEventTime( event 
) ) ; 
 173     GetEventParameter( event
, kEventParamKeyMacCharCodes
, typeChar
, NULL
,sizeof(char), NULL
,&charCode 
); 
 174     GetEventParameter( event
, kEventParamKeyCode
, typeUInt32
, NULL
,  sizeof(UInt32
), NULL
, &keyCode 
); 
 175        GetEventParameter(event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, sizeof(UInt32
), NULL
, &modifiers
); 
 176     GetEventParameter( event
, kEventParamMouseLocation
, typeQDPoint
, NULL
, 
 177         sizeof( Point 
), NULL
, &point 
); 
 179     UInt32 message 
= (keyCode 
<< 8) + charCode
; 
 180     switch( GetEventKind( event 
) ) 
 182         case kEventRawKeyRepeat 
: 
 183         case kEventRawKeyDown 
: 
 185                 WXEVENTREF formerEvent 
= wxTheApp
->MacGetCurrentEvent() ; 
 186                 WXEVENTHANDLERCALLREF formerHandler 
= wxTheApp
->MacGetCurrentEventHandlerCallRef() ; 
 187                 wxTheApp
->MacSetCurrentEvent( event 
, handler 
) ; 
 188                 if ( (focus 
!= NULL
) && wxTheApp
->MacSendKeyDownEvent( 
 189                     focus 
, message 
, modifiers 
, when 
, point
.h 
, point
.v 
) ) 
 193                 wxTheApp
->MacSetCurrentEvent( formerEvent 
, formerHandler 
) ; 
 196         case kEventRawKeyUp 
: 
 197             if ( (focus 
!= NULL
) && wxTheApp
->MacSendKeyUpEvent( 
 198                 focus 
, message 
, modifiers 
, when 
, point
.h 
, point
.v 
) ) 
 203         case kEventRawKeyModifiersChanged 
: 
 205                 wxKeyEvent 
event(wxEVT_KEY_DOWN
); 
 207                 event
.m_shiftDown 
= modifiers 
& shiftKey
; 
 208                 event
.m_controlDown 
= modifiers 
& controlKey
; 
 209                 event
.m_altDown 
= modifiers 
& optionKey
; 
 210                 event
.m_metaDown 
= modifiers 
& cmdKey
; 
 214                 event
.m_timeStamp 
= when
; 
 215                 wxWindow
* focus 
= wxWindow::FindFocus() ; 
 216                 event
.SetEventObject(focus
); 
 218                 if ( focus 
&& (modifiers 
^ wxTheApp
->s_lastModifiers 
) & controlKey 
) 
 220                     event
.m_keyCode 
= WXK_CONTROL 
; 
 221                     event
.SetEventType( ( modifiers 
& controlKey 
) ? wxEVT_KEY_DOWN 
: wxEVT_KEY_UP 
) ; 
 222                     focus
->GetEventHandler()->ProcessEvent( event 
) ; 
 224                 if ( focus 
&& (modifiers 
^ wxTheApp
->s_lastModifiers 
) & shiftKey 
) 
 226                     event
.m_keyCode 
= WXK_SHIFT 
; 
 227                     event
.SetEventType( ( modifiers 
& shiftKey 
) ? wxEVT_KEY_DOWN 
: wxEVT_KEY_UP 
) ; 
 228                     focus
->GetEventHandler()->ProcessEvent( event 
) ; 
 230                 if ( focus 
&& (modifiers 
^ wxTheApp
->s_lastModifiers 
) & optionKey 
) 
 232                     event
.m_keyCode 
= WXK_ALT 
; 
 233                     event
.SetEventType( ( modifiers 
& optionKey 
) ? wxEVT_KEY_DOWN 
: wxEVT_KEY_UP 
) ; 
 234                     focus
->GetEventHandler()->ProcessEvent( event 
) ; 
 236                 if ( focus 
&& (modifiers 
^ wxTheApp
->s_lastModifiers 
) & cmdKey 
) 
 238                     event
.m_keyCode 
= WXK_COMMAND 
; 
 239                     event
.SetEventType( ( modifiers 
& cmdKey 
) ? wxEVT_KEY_DOWN 
: wxEVT_KEY_UP 
) ; 
 240                     focus
->GetEventHandler()->ProcessEvent( event 
) ; 
 242                 wxTheApp
->s_lastModifiers 
= modifiers 
; 
 250 pascal OSStatus 
MouseEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 252     OSStatus result 
= eventNotHandledErr 
; 
 254     wxTopLevelWindowMac
* toplevelWindow 
= (wxTopLevelWindowMac
*) data 
; 
 256     UInt32 modifiers 
= 0; 
 257     EventMouseButton button 
= 0 ; 
 260     GetEventParameter( event
, kEventParamMouseLocation
, typeQDPoint
, NULL
, 
 261         sizeof( Point 
), NULL
, &point 
); 
 262     GetEventParameter( event
, kEventParamKeyModifiers
, typeUInt32
, NULL
, 
 263         sizeof( UInt32 
), NULL
, &modifiers 
); 
 264     GetEventParameter( event
, kEventParamMouseButton
, typeMouseButton
, NULL
, 
 265         sizeof( EventMouseButton 
), NULL
, &button 
); 
 266     GetEventParameter( event
, kEventParamClickCount
, typeUInt32
, NULL
, 
 267         sizeof( UInt32 
), NULL
, &click 
); 
 269     if ( button 
== 0 || GetEventKind( event 
) == kEventMouseUp 
) 
 270         modifiers 
+= btnState 
; 
 272         // temporary hack to support true two button mouse 
 273         if ( button 
== kEventMouseButtonSecondary 
) 
 275                 modifiers 
|= controlKey 
; 
 278     short windowPart 
= ::FindWindow(point
, &window
); 
 280     // either we really are active or we are capturing mouse events 
 282     if ( (IsWindowActive(window
) && windowPart 
== inContent
) ||  
 283         (wxTheApp
->s_captureWindow 
&& wxTheApp
->s_captureWindow
->MacGetTopLevelWindow() == toplevelWindow
) ) 
 285         switch ( GetEventKind( event 
) ) 
 287             case kEventMouseDown 
: 
 288                 toplevelWindow
->MacFireMouseEvent( mouseDown 
, point
.h 
, point
.v 
, modifiers 
, EventTimeToTicks( GetEventTime( event 
) ) ) ; 
 292                 toplevelWindow
->MacFireMouseEvent( mouseUp 
, point
.h 
, point
.v 
, modifiers 
, EventTimeToTicks( GetEventTime( event 
) ) ) ; 
 295             case kEventMouseMoved 
: 
 296                 wxTheApp
->MacHandleMouseMovedEvent( point
.h 
, point
.v 
, modifiers 
, EventTimeToTicks( GetEventTime( event 
) ) ) ; 
 299             case kEventMouseDragged 
: 
 300                 toplevelWindow
->MacFireMouseEvent( nullEvent 
, point
.h 
, point
.v 
, modifiers 
, EventTimeToTicks( GetEventTime( event 
) ) ) ; 
 303             case kEventMouseWheelMoved 
: 
 305                     //bClearTooltip = false; 
 306                     EventMouseWheelAxis axis 
= kEventMouseWheelAxisY
; 
 308                     Point mouseLoc 
= {0, 0}; 
 309                     if (::GetEventParameter(event
, kEventParamMouseWheelAxis
, typeMouseWheelAxis
, 
 310                                         NULL
, sizeof(EventMouseWheelAxis
), NULL
, &axis
) == noErr 
&& 
 311                         ::GetEventParameter(event
, kEventParamMouseWheelDelta
, typeLongInteger
, 
 312                                         NULL
, sizeof(SInt32
), NULL
, &delta
) == noErr 
&& 
 313                         ::GetEventParameter(event
, kEventParamMouseLocation
, typeQDPoint
, 
 314                                         NULL
, sizeof(Point
), NULL
, &mouseLoc
) == noErr
) 
 316                         wxMouseEvent 
wheelEvent(wxEVT_MOUSEWHEEL
); 
 318                         wheelEvent
.m_x 
= mouseLoc
.h
; 
 319                         wheelEvent
.m_y 
= mouseLoc
.v
; 
 321                         wheelEvent
.m_wheelRotation 
= delta
; 
 322                         wheelEvent
.m_wheelDelta 
= 1; 
 323                         wheelEvent
.m_linesPerAction 
= 1; 
 325                         wxWindow
* currentMouseWindow 
= NULL
; 
 326                         wxWindow::MacGetWindowFromPoint(wxPoint(mouseLoc
.h
, mouseLoc
.v
), ¤tMouseWindow
); 
 328                         if (currentMouseWindow
) 
 330                             currentMouseWindow
->GetEventHandler()->ProcessEvent(wheelEvent
); 
 345 static pascal OSStatus 
WindowEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 347     OSStatus result 
= eventNotHandledErr 
; 
 348     OSStatus err 
= noErr 
; 
 351     WindowRef windowRef 
; 
 352     wxTopLevelWindowMac
* toplevelWindow 
= (wxTopLevelWindowMac
*) data 
; 
 354     GetEventParameter( event
, kEventParamDirectObject
, typeWindowRef
, NULL
, 
 355         sizeof( WindowRef 
), NULL
, &windowRef 
); 
 357     switch( GetEventKind( event 
) ) 
 359         case kEventWindowUpdate 
: 
 360             if ( !wxPendingDelete
.Member(toplevelWindow
) ) 
 361                 toplevelWindow
->MacUpdate( EventTimeToTicks( GetEventTime( event 
) ) ) ; 
 364         case kEventWindowActivated 
: 
 365                 toplevelWindow
->MacActivate( EventTimeToTicks( GetEventTime( event 
) ) , true) ; 
 368         case kEventWindowDeactivated 
: 
 369                 toplevelWindow
->MacActivate( EventTimeToTicks( GetEventTime( event 
) ) , false) ; 
 372         case kEventWindowShown 
: 
 373                 toplevelWindow
->Refresh() ; 
 376         case kEventWindowClose 
: 
 377                 toplevelWindow
->Close() ; 
 380         case kEventWindowBoundsChanged 
: 
 381             err 
= GetEventParameter( event
, kEventParamAttributes
, typeUInt32
, 
 382                         NULL
, sizeof( UInt32 
), NULL
, &attributes 
); 
 385                 Rect newContentRect 
; 
 387                 GetEventParameter( event
, kEventParamCurrentBounds
, typeQDRectangle
, NULL
, 
 388                     sizeof( newContentRect 
), NULL
, &newContentRect 
); 
 390                 toplevelWindow
->SetSize( newContentRect
.left 
, newContentRect
.top 
, 
 391                     newContentRect
.right 
- newContentRect
.left 
, 
 392                     newContentRect
.bottom 
- newContentRect
.top
, wxSIZE_USE_EXISTING
); 
 397         case kEventWindowBoundsChanging 
: 
 398             err 
= GetEventParameter( event
, kEventParamAttributes
, typeUInt32
, 
 399                         NULL
, sizeof( UInt32 
), NULL
, &attributes 
); 
 402                 Rect newContentRect 
; 
 404                 GetEventParameter( event
, kEventParamCurrentBounds
, typeQDRectangle
, NULL
, 
 405                     sizeof( newContentRect 
), NULL
, &newContentRect 
); 
 407                 wxSize formerSize 
= toplevelWindow
->GetSize() ; 
 409                 if ( (attributes 
& kWindowBoundsChangeSizeChanged 
) ||  
 410                     ( attributes 
& kWindowBoundsChangeOriginChanged 
) ) 
 411                     toplevelWindow
->SetSize( newContentRect
.left 
, newContentRect
.top 
, 
 412                         newContentRect
.right 
- newContentRect
.left 
, 
 413                         newContentRect
.bottom 
- newContentRect
.top
, wxSIZE_USE_EXISTING
); 
 416                 toplevelWindow
->GetPosition( &x 
, &y 
) ; 
 417                 toplevelWindow
->GetSize( &w 
, &h 
) ; 
 418                 Rect adjustedRect  
= { y 
, x 
, y 
+ h 
, x 
+ w 
} ; 
 420                 if ( !EqualRect( &newContentRect 
, &adjustedRect 
) ) 
 422                     SetEventParameter( event 
, kEventParamCurrentBounds 
, typeQDRectangle
, sizeof( adjustedRect 
) , &adjustedRect 
) ; 
 425                 if ( toplevelWindow
->GetSize() != formerSize 
) 
 426                     toplevelWindow
->Update() ; 
 437 pascal OSStatus 
wxMacWindowEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 439     OSStatus result 
= eventNotHandledErr 
; 
 441     switch ( GetEventClass( event 
) ) 
 443         case kEventClassKeyboard 
: 
 444             result 
= KeyboardEventHandler( handler
, event 
, data 
) ; 
 446         case kEventClassTextInput 
: 
 447             result 
= TextInputEventHandler( handler
, event 
, data 
) ; 
 449         case kEventClassWindow 
: 
 450             result 
= WindowEventHandler( handler
, event 
, data 
) ; 
 452         case kEventClassMouse 
: 
 453             result 
= MouseEventHandler( handler
, event 
, data 
) ; 
 461 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler 
) 
 465 // --------------------------------------------------------------------------- 
 466 // wxWindowMac utility functions 
 467 // --------------------------------------------------------------------------- 
 469 // Find an item given the Macintosh Window Reference 
 471 wxList 
*wxWinMacWindowList 
= NULL
; 
 472 wxTopLevelWindowMac 
*wxFindWinFromMacWindow(WXWindow inWindowRef
) 
 474     if ( wxWinMacWindowList 
== NULL 
) 
 476     wxNode 
*node 
= wxWinMacWindowList
->Find((long)inWindowRef
); 
 479     return (wxTopLevelWindowMac 
*)node
->GetData(); 
 482 void wxAssociateWinWithMacWindow(WindowRef inWindowRef
, wxTopLevelWindowMac 
*win
); 
 483 void wxAssociateWinWithMacWindow(WindowRef inWindowRef
, wxTopLevelWindowMac 
*win
) 
 485     // adding NULL WindowRef is (first) surely a result of an error and 
 486     // (secondly) breaks menu command processing 
 487     wxCHECK_RET( inWindowRef 
!= (WindowRef
) NULL
, wxT("attempt to add a NULL WindowRef to window list") ); 
 489     if ( !wxWinMacWindowList
->Find((long)inWindowRef
) ) 
 490         wxWinMacWindowList
->Append((long)inWindowRef
, win
); 
 493 void wxRemoveMacWindowAssociation(wxTopLevelWindowMac 
*win
) 
 495     wxWinMacWindowList
->DeleteObject(win
); 
 499 // ---------------------------------------------------------------------------- 
 500 // wxTopLevelWindowMac creation 
 501 // ---------------------------------------------------------------------------- 
 503 WXWindow 
wxTopLevelWindowMac::s_macWindowInUpdate 
= NULL
; 
 504 wxTopLevelWindowMac 
*wxTopLevelWindowMac::s_macDeactivateWindow 
= NULL
; 
 505 bool wxTopLevelWindowMac::s_macWindowCompositing 
= FALSE
; 
 507 void wxTopLevelWindowMac::Init() 
 510     m_maximizeOnShow 
= FALSE
; 
 511     m_macNoEraseUpdateRgn 
= NewRgn() ; 
 512     m_macNeedsErasing 
= false ; 
 514     m_macUsesCompositing 
= FALSE 
; 
 516     m_macEventHandler 
= NULL 
; 
 520 class wxMacDeferredWindowDeleter 
: public wxObject
 
 523     wxMacDeferredWindowDeleter( WindowRef windowRef 
) 
 525         m_macWindow 
= windowRef 
; 
 527     virtual ~wxMacDeferredWindowDeleter() 
 529         UMADisposeWindow( (WindowRef
) m_macWindow 
) ; 
 532     WindowRef m_macWindow 
; 
 535 bool wxTopLevelWindowMac::Create(wxWindow 
*parent
, 
 537                                  const wxString
& title
, 
 541                                  const wxString
& name
) 
 546     m_windowStyle 
= style
; 
 550     m_windowId 
= id 
== -1 ? NewControlId() : id
; 
 552     wxTopLevelWindows
.Append(this); 
 555         parent
->AddChild(this); 
 560 wxTopLevelWindowMac::~wxTopLevelWindowMac() 
 564         wxToolTip::NotifyWindowDelete(m_macWindow
) ; 
 565         wxPendingDelete
.Append( new wxMacDeferredWindowDeleter( (WindowRef
) m_macWindow 
) ) ; 
 569     if ( m_macEventHandler 
) 
 571         ::RemoveEventHandler((EventHandlerRef
) m_macEventHandler
); 
 572         m_macEventHandler 
= NULL 
; 
 576     wxRemoveMacWindowAssociation( this ) ; 
 578     if ( wxModelessWindows
.Find(this) ) 
 579         wxModelessWindows
.DeleteObject(this); 
 581     DisposeRgn( (RgnHandle
) m_macNoEraseUpdateRgn 
) ; 
 585 // ---------------------------------------------------------------------------- 
 586 // wxTopLevelWindowMac maximize/minimize 
 587 // ---------------------------------------------------------------------------- 
 589 void wxTopLevelWindowMac::Maximize(bool maximize
) 
 591     wxMacPortStateHelper 
help( (GrafPtr
) GetWindowPort( (WindowRef
) m_macWindow
) ) ; 
 592     wxMacWindowClipper 
clip (this); 
 593     ZoomWindow( (WindowRef
)m_macWindow 
, maximize 
? inZoomOut 
: inZoomIn 
, false ) ; 
 598     Point pt 
= { 0, 0 } ; 
 599     SetPortWindowPort((WindowRef
)m_macWindow
) ; 
 600     LocalToGlobal( &pt 
) ; 
 603     GetWindowPortBounds((WindowRef
)m_macWindow
, &tempRect 
) ; 
 604     SetSize( pt
.h 
, pt
.v 
, tempRect
.right
-tempRect
.left 
, 
 605         tempRect
.bottom
-tempRect
.top
, wxSIZE_USE_EXISTING
); 
 608 bool wxTopLevelWindowMac::IsMaximized() const 
 610     return IsWindowInStandardState(  (WindowRef
)m_macWindow 
, NULL 
, NULL 
) ; 
 613 void wxTopLevelWindowMac::Iconize(bool iconize
) 
 615     if ( IsWindowCollapsable((WindowRef
)m_macWindow
) ) 
 616         CollapseWindow((WindowRef
)m_macWindow 
, iconize 
) ; 
 619 bool wxTopLevelWindowMac::IsIconized() const 
 621     return IsWindowCollapsed((WindowRef
)m_macWindow 
) ; 
 624 void wxTopLevelWindowMac::Restore() 
 626     // not available on mac 
 629 // ---------------------------------------------------------------------------- 
 630 // wxTopLevelWindowMac misc 
 631 // ---------------------------------------------------------------------------- 
 633 void wxTopLevelWindowMac::SetIcon(const wxIcon
& icon
) 
 636     wxTopLevelWindowBase::SetIcon(icon
); 
 639 void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString
& title
, 
 643            const wxString
& name 
) 
 645     OSStatus err 
= noErr 
; 
 647     m_windowStyle 
= style
; 
 661     m_width 
= WidthDefault(size
.x
); 
 662     m_height 
= HeightDefault(size
.y
); 
 664     ::SetRect(&theBoundsRect
, m_x
, m_y 
, m_x 
+ m_width
, m_y 
+ m_height
); 
 666     // translate the window attributes in the appropriate window class and attributes 
 668     WindowClass wclass 
= 0; 
 669     WindowAttributes attr 
= kWindowNoAttributes 
; 
 671     if ( HasFlag( wxFRAME_TOOL_WINDOW
) ) 
 674             HasFlag( wxMINIMIZE_BOX 
) || HasFlag( wxMAXIMIZE_BOX 
) || 
 675             HasFlag( wxSYSTEM_MENU 
) || HasFlag( wxCAPTION 
) || 
 676             HasFlag(wxTINY_CAPTION_HORIZ
) ||  HasFlag(wxTINY_CAPTION_VERT
) 
 679             wclass 
= kFloatingWindowClass 
; 
 680             if ( HasFlag(wxTINY_CAPTION_VERT
) ) 
 682                 attr 
|= kWindowSideTitlebarAttribute 
; 
 688             wclass 
= kPlainWindowClass 
; 
 690             wclass 
= kFloatingWindowClass 
; 
 694     else if ( HasFlag( wxCAPTION 
) ) 
 696         wclass 
= kDocumentWindowClass 
; 
 700         if ( HasFlag( wxMINIMIZE_BOX 
) || HasFlag( wxMAXIMIZE_BOX 
) || 
 701             HasFlag( wxCLOSE_BOX 
) || HasFlag( wxSYSTEM_MENU 
) ) 
 703             wclass 
= kDocumentWindowClass 
; 
 708             wclass 
= kPlainWindowClass 
; 
 710             wclass 
= kModalWindowClass 
; 
 715     if ( HasFlag( wxMINIMIZE_BOX 
) ) 
 717         attr 
|= kWindowCollapseBoxAttribute 
; 
 719     if ( HasFlag( wxMAXIMIZE_BOX 
) ) 
 721         attr 
|= kWindowFullZoomAttribute 
; 
 723     if ( HasFlag( wxRESIZE_BORDER 
) ) 
 725         attr 
|= kWindowResizableAttribute 
; 
 727     if ( HasFlag( wxCLOSE_BOX
) ) 
 729         attr 
|= kWindowCloseBoxAttribute 
; 
 732     if (UMAGetSystemVersion() >= 0x1000) 
 734         //turn on live resizing (OS X only) 
 735         attr 
|= kWindowLiveResizeAttribute
; 
 739 #if 0 //  having problems right now with that 
 740     if (HasFlag(wxSTAY_ON_TOP
)) 
 741         wclass 
= kUtilityWindowClass
; 
 745     //this setup lets us have compositing and non-compositing  
 746     //windows in the same application.  
 748 #if UNIVERSAL_INTERFACES_VERSION >= 0x0400   
 749     if ( wxTopLevelWindowMac::s_macWindowCompositing 
) 
 751         attr 
|= kWindowCompositingAttribute
; 
 752         m_macUsesCompositing 
= TRUE
; 
 757         m_macUsesCompositing 
= FALSE
; 
 761     if ( HasFlag(wxFRAME_SHAPED
) ) 
 763         WindowDefSpec customWindowDefSpec
; 
 764         customWindowDefSpec
.defType 
= kWindowDefProcPtr
; 
 765         customWindowDefSpec
.u
.defProc 
= NewWindowDefUPP(wxShapedMacWindowDef
); 
 767         err 
= ::CreateCustomWindow( &customWindowDefSpec
, wclass
, 
 768                               attr
, &theBoundsRect
, 
 769                               (WindowRef
*) &m_macWindow
); 
 774         err 
= ::CreateNewWindow( wclass 
, attr 
, &theBoundsRect 
, (WindowRef
*)&m_macWindow 
) ; 
 777     wxCHECK_RET( err 
== noErr
, wxT("Mac OS error when trying to create new window") ); 
 778     wxAssociateWinWithMacWindow( (WindowRef
) m_macWindow 
, this ) ; 
 779     UMASetWTitle( (WindowRef
)m_macWindow 
, title 
, m_font
.GetEncoding() ) ; 
 780     if ( wxTopLevelWindowMac::s_macWindowCompositing 
) 
 782         ::GetRootControl( (WindowRef
)m_macWindow
, (ControlHandle
*)&m_macRootControl 
) ; 
 786         ::CreateRootControl( (WindowRef
)m_macWindow 
, (ControlHandle
*)&m_macRootControl 
) ; 
 789     InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow
)) ) ; 
 790     InstallWindowEventHandler(MAC_WXHWND(m_macWindow
), GetwxMacWindowEventHandlerUPP(), 
 791         GetEventTypeCount(eventList
), eventList
, this, (EventHandlerRef 
*)&m_macEventHandler
); 
 797     if ( HasFlag(wxFRAME_SHAPED
) ) 
 799         // default shape matches the window size 
 800         wxRegion 
rgn(0, 0, m_width
, m_height
); 
 805     wxWindowCreateEvent 
event(this); 
 806     GetEventHandler()->ProcessEvent(event
); 
 809 bool wxTopLevelWindowMac::MacEnableCompositing( bool useCompositing 
) 
 811     bool oldval 
= s_macWindowCompositing
; 
 812     s_macWindowCompositing 
= useCompositing
;  
 816 void wxTopLevelWindowMac::MacGetPortParams(WXPOINTPTR localOrigin
, WXRECTPTR clipRect
, WXWindow 
*window  
, wxWindowMac
** rootwin
) 
 818     ((Point
*)localOrigin
)->h 
= 0; 
 819     ((Point
*)localOrigin
)->v 
= 0; 
 820     ((Rect
*)clipRect
)->left 
= 0; 
 821     ((Rect
*)clipRect
)->top 
= 0; 
 822     ((Rect
*)clipRect
)->right 
= m_width
; 
 823     ((Rect
*)clipRect
)->bottom 
= m_height
; 
 824     *window 
= m_macWindow 
; 
 828 void wxTopLevelWindowMac::ClearBackground() 
 830     wxWindow::ClearBackground() ; 
 833 WXWidget 
wxTopLevelWindowMac::MacGetContainerForEmbedding() 
 835     return m_macRootControl 
; 
 839 void wxTopLevelWindowMac::MacUpdate( long timestamp
) 
 841     wxMacPortStateHelper 
help( (GrafPtr
) GetWindowPort( (WindowRef
) m_macWindow
) ) ; 
 843     RgnHandle       visRgn 
= NewRgn() ; 
 844     GetPortVisibleRegion( GetWindowPort( (WindowRef
)m_macWindow 
), visRgn 
); 
 845     BeginUpdate( (WindowRef
)m_macWindow 
) ; 
 847     RgnHandle       updateRgn 
= NewRgn(); 
 848     RgnHandle       diffRgn 
= NewRgn() ; 
 850     if ( updateRgn 
&& diffRgn 
) 
 853         // macos internal control redraws clean up areas we'd like to redraw ourselves 
 854         // therefore we pick the boundary rect and make sure we can redraw it 
 855         // this has to be intersected by the visRgn in order to avoid drawing over its own 
 857         RgnHandle trueUpdateRgn 
= NewRgn() ; 
 858         Rect trueUpdateRgnBoundary 
; 
 859         GetPortVisibleRegion( GetWindowPort( (WindowRef
)m_macWindow 
), trueUpdateRgn 
); 
 860         GetRegionBounds( trueUpdateRgn 
, &trueUpdateRgnBoundary 
) ; 
 861         RectRgn( updateRgn 
, &trueUpdateRgnBoundary 
) ; 
 862         SectRgn( updateRgn 
, visRgn 
, updateRgn 
) ; 
 864             DisposeRgn( trueUpdateRgn 
) ; 
 865         SetPortVisibleRegion(  GetWindowPort( (WindowRef
)m_macWindow 
), updateRgn 
) ; 
 867         GetPortVisibleRegion( GetWindowPort( (WindowRef
)m_macWindow 
), updateRgn 
); 
 869         DiffRgn( updateRgn 
, (RgnHandle
) m_macNoEraseUpdateRgn 
, diffRgn 
) ; 
 870         if ( !EmptyRgn( updateRgn 
) ) 
 872             MacRedraw( updateRgn 
, timestamp 
, m_macNeedsErasing 
|| !EmptyRgn( diffRgn 
)  ) ; 
 876         DisposeRgn( updateRgn 
); 
 878         DisposeRgn( diffRgn 
); 
 880         DisposeRgn( visRgn 
) ; 
 882     EndUpdate( (WindowRef
)m_macWindow 
) ; 
 883     SetEmptyRgn( (RgnHandle
) m_macNoEraseUpdateRgn 
) ; 
 884     m_macNeedsErasing 
= false ; 
 888 // Raise the window to the top of the Z order 
 889 void wxTopLevelWindowMac::Raise() 
 891     ::SelectWindow( (WindowRef
)m_macWindow 
) ; 
 894 // Lower the window to the bottom of the Z order 
 895 void wxTopLevelWindowMac::Lower() 
 897     ::SendBehind( (WindowRef
)m_macWindow 
, NULL 
) ; 
 900 void wxTopLevelWindowMac::MacFireMouseEvent( 
 901     wxUint16 kind 
, wxInt32 x 
, wxInt32 y 
,wxUint32 modifiers 
, long timestamp 
) 
 903     wxMouseEvent 
event(wxEVT_LEFT_DOWN
); 
 904     bool isDown 
= !(modifiers 
& btnState
) ; // 1 is for up 
 905     bool controlDown 
= modifiers 
& controlKey 
; // for simulating right mouse 
 907     event
.m_leftDown 
= isDown 
&& !controlDown
; 
 909     event
.m_middleDown 
= FALSE
; 
 910     event
.m_rightDown 
= isDown 
&& controlDown
; 
 912     if ( kind 
== mouseDown 
) 
 915             event
.SetEventType(wxEVT_RIGHT_DOWN 
) ; 
 917             event
.SetEventType(wxEVT_LEFT_DOWN 
) ; 
 919     else if ( kind 
== mouseUp 
) 
 922             event
.SetEventType(wxEVT_RIGHT_UP 
) ; 
 924             event
.SetEventType(wxEVT_LEFT_UP 
) ; 
 928         event
.SetEventType(wxEVT_MOTION 
) ; 
 931     event
.m_shiftDown 
= modifiers 
& shiftKey
; 
 932     event
.m_controlDown 
= modifiers 
& controlKey
; 
 933     event
.m_altDown 
= modifiers 
& optionKey
; 
 934     event
.m_metaDown 
= modifiers 
& cmdKey
; 
 942     ::SetPort( UMAGetWindowPort( (WindowRef
)m_macWindow 
) ) ; 
 943     ::GlobalToLocal( &localwhere 
) ; 
 946     if ( kind 
== mouseDown 
) 
 948         if ( timestamp 
- gs_lastWhen 
<= (long) GetDblTime() ) 
 950             if ( abs( localwhere
.h 
- gs_lastWhere
.h 
) < 3 && abs( localwhere
.v 
- gs_lastWhere
.v 
) < 3 ) 
 952                 // This is not right if the second mouse down 
 953                 // event occured in a differen window. We 
 954                 // correct this in MacDispatchMouseEvent. 
 956                     event
.SetEventType(wxEVT_RIGHT_DCLICK 
) ; 
 958                     event
.SetEventType(wxEVT_LEFT_DCLICK 
) ; 
 964             gs_lastWhen 
= timestamp 
; 
 966         gs_lastWhere 
= localwhere 
; 
 969     event
.m_x 
= localwhere
.h
; 
 970     event
.m_y 
= localwhere
.v
; 
 974     event
.m_timeStamp 
= timestamp
; 
 975     event
.SetEventObject(this); 
 976     if ( wxTheApp
->s_captureWindow 
) 
 980         wxTheApp
->s_captureWindow
->ScreenToClient( &x 
, &y 
) ; 
 983         event
.SetEventObject( wxTheApp
->s_captureWindow 
) ; 
 984         wxTheApp
->s_captureWindow
->GetEventHandler()->ProcessEvent( event 
) ; 
 986         if ( kind 
== mouseUp 
) 
 988             wxTheApp
->s_captureWindow 
= NULL 
; 
 991                 m_cursor
.MacInstall() ; 
 997         MacDispatchMouseEvent( event 
) ; 
1003 void wxTopLevelWindowMac::MacMouseDown( WXEVENTREF ev 
, short part
) 
1005     MacFireMouseEvent( mouseDown 
, ((EventRecord
*)ev
)->where
.h 
, ((EventRecord
*)ev
)->where
.v 
, 
1006         ((EventRecord
*)ev
)->modifiers 
, ((EventRecord
*)ev
)->when 
) ; 
1009 void wxTopLevelWindowMac::MacMouseUp( WXEVENTREF ev 
, short part
) 
1015                 MacFireMouseEvent( mouseUp 
, ((EventRecord
*)ev
)->where
.h 
, ((EventRecord
*)ev
)->where
.v 
, 
1016                     ((EventRecord
*)ev
)->modifiers 
, ((EventRecord
*)ev
)->when 
) ; 
1022 void wxTopLevelWindowMac::MacMouseMoved( WXEVENTREF ev 
, short part
) 
1028                 MacFireMouseEvent( nullEvent 
/*moved*/ , ((EventRecord
*)ev
)->where
.h 
, ((EventRecord
*)ev
)->where
.v 
, 
1029                     ((EventRecord
*)ev
)->modifiers 
, ((EventRecord
*)ev
)->when 
) ; 
1037 void wxTopLevelWindowMac::MacDelayedDeactivation(long timestamp
) 
1039     if(s_macDeactivateWindow
) 
1041         wxLogDebug(wxT("Doing delayed deactivation of %p"),s_macDeactivateWindow
); 
1042         s_macDeactivateWindow
->MacActivate(timestamp
, false); 
1046 void wxTopLevelWindowMac::MacActivate( long timestamp 
, bool inIsActivating 
) 
1048     // wxLogDebug(wxT("TopLevel=%p::MacActivate"),this); 
1050     if(s_macDeactivateWindow
==this) 
1051         s_macDeactivateWindow
=NULL
; 
1052     MacDelayedDeactivation(timestamp
); 
1053     wxActivateEvent 
event(wxEVT_ACTIVATE
, inIsActivating 
, m_windowId
); 
1054     event
.m_timeStamp 
= timestamp 
; 
1055     event
.SetEventObject(this); 
1057     GetEventHandler()->ProcessEvent(event
); 
1059     UMAHighlightAndActivateWindow( (WindowRef
)m_macWindow 
, inIsActivating 
) ; 
1061     // Early versions of MacOS X don't refresh backgrounds properly, 
1062     // so refresh the whole window on activation and deactivation. 
1063     long osVersion 
= UMAGetSystemVersion(); 
1064     if (osVersion 
>= 0x1000 && osVersion 
< 0x1020 ) 
1070         // for the moment we have to resolve some redrawing issues like this 
1071         // the OS is stealing some redrawing areas as soon as it draws a control 
1078 void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev 
) 
1084 void wxTopLevelWindowMac::SetTitle(const wxString
& title
) 
1086     wxWindow::SetTitle( title 
) ; 
1087     UMASetWTitle( (WindowRef
)m_macWindow 
, title 
, m_font
.GetEncoding() ) ; 
1090 bool wxTopLevelWindowMac::Show(bool show
) 
1092     if ( !wxWindow::Show(show
) ) 
1097         #if wxUSE_SYSTEM_OPTIONS        //code contributed by Ryan Wilcox December 18, 2003 
1098         if ( (wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION
) ) && ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION 
) == 1) ) 
1100            ::ShowWindow( (WindowRef
)m_macWindow 
); 
1105            ::TransitionWindow((WindowRef
)m_macWindow
,kWindowZoomTransitionEffect
,kWindowShowTransitionAction
,nil
); 
1107         ::SelectWindow( (WindowRef
)m_macWindow 
) ; 
1108         // no need to generate events here, they will get them triggered by macos 
1109         // actually they should be , but apparently they are not 
1110         wxSize 
size(m_width
, m_height
); 
1111         wxSizeEvent 
event(size
, m_windowId
); 
1112         event
.SetEventObject(this); 
1113         GetEventHandler()->ProcessEvent(event
); 
1117         #if wxUSE_SYSTEM_OPTIONS 
1118         if ( (wxSystemOptions::HasOption(wxMAC_WINDOW_PLAIN_TRANSITION
) ) && ( wxSystemOptions::GetOptionInt( wxMAC_WINDOW_PLAIN_TRANSITION 
) == 1) ) 
1120            ::HideWindow((WindowRef
) m_macWindow 
); 
1125            ::TransitionWindow((WindowRef
)m_macWindow
,kWindowZoomTransitionEffect
,kWindowHideTransitionAction
,nil
); 
1140 void wxTopLevelWindowMac::DoMoveWindow(int x
, int y
, int width
, int height
) 
1142     wxMacPortStateHelper 
help( (GrafPtr
) GetWindowPort( (WindowRef
) m_macWindow
) ) ; 
1143     wxMacWindowClipper 
clip (this); 
1145     int former_x 
= m_x 
; 
1146     int former_y 
= m_y 
; 
1147     int former_w 
= m_width 
; 
1148     int former_h 
= m_height 
; 
1150     int actualWidth 
= width
; 
1151     int actualHeight 
= height
; 
1155     if ((m_minWidth 
!= -1) && (actualWidth 
< m_minWidth
)) 
1156         actualWidth 
= m_minWidth
; 
1157     if ((m_minHeight 
!= -1) && (actualHeight 
< m_minHeight
)) 
1158         actualHeight 
= m_minHeight
; 
1159     if ((m_maxWidth 
!= -1) && (actualWidth 
> m_maxWidth
)) 
1160         actualWidth 
= m_maxWidth
; 
1161     if ((m_maxHeight 
!= -1) && (actualHeight 
> m_maxHeight
)) 
1162         actualHeight 
= m_maxHeight
; 
1164     bool doMove 
= false ; 
1165     bool doResize 
= false ; 
1167     if ( actualX 
!= former_x 
|| actualY 
!= former_y 
) 
1171     if ( actualWidth 
!= former_w 
|| actualHeight 
!= former_h 
) 
1176     if ( doMove 
|| doResize 
) 
1182             ::MoveWindow((WindowRef
)m_macWindow
, m_x
, m_y  
, false); // don't make frontmost 
1184         m_width 
= actualWidth 
; 
1185         m_height 
= actualHeight 
; 
1188             ::SizeWindow((WindowRef
)m_macWindow
, m_width
, m_height  
, true); 
1190         // the OS takes care of invalidating and erasing the new area so we only have to 
1191         // take care of refreshing for full repaints 
1193         if ( doResize 
&& HasFlag(wxFULL_REPAINT_ON_RESIZE
) ) 
1197         if ( IsKindOf( CLASSINFO( wxFrame 
) ) ) 
1199             wxFrame
* frame 
= (wxFrame
*) this ; 
1201             frame
->PositionStatusBar(); 
1204             frame
->PositionToolBar(); 
1208             wxWindowMac::MacTopLevelWindowChangedPosition() ; // like this only children will be notified 
1210         MacRepositionScrollBars() ; 
1213             wxPoint 
point(m_x
, m_y
); 
1214             wxMoveEvent 
event(point
, m_windowId
); 
1215             event
.SetEventObject(this); 
1216             GetEventHandler()->ProcessEvent(event
) ; 
1220              MacRepositionScrollBars() ; 
1221              wxSize 
size(m_width
, m_height
); 
1222              wxSizeEvent 
event(size
, m_windowId
); 
1223              event
.SetEventObject(this); 
1224              GetEventHandler()->ProcessEvent(event
); 
1231  * Invalidation Mechanism 
1233  * The update mechanism reflects exactely the windows mechanism 
1234  * the rect gets added to the window invalidate region, if the eraseBackground flag 
1235  * has been true for any part of the update rgn the background is erased in the entire region 
1236  * not just in the specified rect. 
1238  * In order to achive this, we also have an internal m_macNoEraseUpdateRgn, all rects that have 
1239  * the eraseBackground flag set to false are also added to this rgn. upon receiving an update event 
1240  * the update rgn is compared to the m_macNoEraseUpdateRgn and in case they differ, every window 
1241  * will get the eraseBackground event first 
1244 void wxTopLevelWindowMac::MacInvalidate( const WXRECTPTR rect
, bool eraseBackground 
) 
1246     GrafPtr formerPort 
; 
1247     GetPort( &formerPort 
) ; 
1248     SetPortWindowPort( (WindowRef
)m_macWindow 
) ; 
1250     m_macNeedsErasing 
|= eraseBackground 
; 
1252     // if we already know that we will have to erase, there's no need to track the rest 
1253     if ( !m_macNeedsErasing
) 
1255         // we end only here if eraseBackground is false 
1256         // if we already have a difference between m_macNoEraseUpdateRgn and UpdateRgn 
1257         // we will have to erase anyway 
1259         RgnHandle       updateRgn 
= NewRgn(); 
1260         RgnHandle       diffRgn 
= NewRgn() ; 
1261         if ( updateRgn 
&& diffRgn 
) 
1263             GetWindowUpdateRgn( (WindowRef
)m_macWindow 
, updateRgn 
); 
1265             LocalToGlobal( &pt 
) ; 
1266             OffsetRgn( updateRgn 
, -pt
.h 
, -pt
.v 
) ; 
1267             DiffRgn( updateRgn 
, (RgnHandle
) m_macNoEraseUpdateRgn 
, diffRgn 
) ; 
1268             if ( !EmptyRgn( diffRgn 
) ) 
1270                 m_macNeedsErasing 
= true ; 
1274             DisposeRgn( updateRgn 
); 
1276             DisposeRgn( diffRgn 
); 
1278         if ( !m_macNeedsErasing 
) 
1280             RgnHandle rectRgn 
= NewRgn() ; 
1281             SetRectRgn( rectRgn 
, ((Rect
*)rect
)->left 
, ((Rect
*)rect
)->top 
, ((Rect
*)rect
)->right 
, ((Rect
*)rect
)->bottom 
) ; 
1282             UnionRgn( (RgnHandle
) m_macNoEraseUpdateRgn 
, rectRgn 
, (RgnHandle
) m_macNoEraseUpdateRgn 
) ; 
1283             DisposeRgn( rectRgn 
) ; 
1286     InvalWindowRect( (WindowRef
)m_macWindow 
, (Rect
*)rect 
) ; 
1287     // turn this on to debug the refreshing cycle 
1288 #if wxMAC_DEBUG_REDRAW 
1291     SetPort( formerPort 
) ; 
1295 bool wxTopLevelWindowMac::SetShape(const wxRegion
& region
) 
1297     wxCHECK_MSG( HasFlag(wxFRAME_SHAPED
), FALSE
, 
1298                  _T("Shaped windows must be created with the wxFRAME_SHAPED style.")); 
1301     // The empty region signifies that the shape should be removed from the 
1303     if ( region
.IsEmpty() ) 
1305         wxSize sz 
= GetClientSize(); 
1306         wxRegion 
rgn(0, 0, sz
.x
, sz
.y
); 
1307         return SetShape(rgn
); 
1310     // Make a copy of the region 
1311     RgnHandle  shapeRegion 
= NewRgn(); 
1312     CopyRgn( (RgnHandle
)region
.GetWXHRGN(), shapeRegion 
); 
1314     // Dispose of any shape region we may already have 
1315     RgnHandle oldRgn 
= (RgnHandle
)GetWRefCon( (WindowRef
)MacGetWindowRef() ); 
1319     // Save the region so we can use it later 
1320     SetWRefCon((WindowRef
)MacGetWindowRef(), (SInt32
)shapeRegion
); 
1322     // Tell the window manager that the window has changed shape 
1323     ReshapeCustomWindow((WindowRef
)MacGetWindowRef()); 
1330 // --------------------------------------------------------------------------- 
1331 // Support functions for shaped windows, based on Apple's CustomWindow sample at 
1332 // http://developer.apple.com/samplecode/Sample_Code/Human_Interface_Toolbox/Mac_OS_High_Level_Toolbox/CustomWindow.htm 
1333 // --------------------------------------------------------------------------- 
1337 static void wxShapedMacWindowGetPos(WindowRef window
, Rect
* inRect
) 
1339     GetWindowPortBounds(window
, inRect
); 
1340     Point pt 
= {inRect
->left
, inRect
->top
}; 
1341     SetPort((GrafPtr
) GetWindowPort(window
)); 
1344     inRect
->left 
= pt
.h
; 
1345     inRect
->bottom 
+= pt
.v
; 
1346     inRect
->right 
+= pt
.h
; 
1350 static SInt32 
wxShapedMacWindowGetFeatures(WindowRef window
, SInt32 param
) 
1352     /*------------------------------------------------------ 
1353         Define which options your custom window supports. 
1354     --------------------------------------------------------*/ 
1355     //just enable everything for our demo 
1356     *(OptionBits
*)param
=//kWindowCanGrow| 
1358                         //kWindowCanCollapse| 
1359                         //kWindowCanGetWindowRegion| 
1360                         //kWindowHasTitleBar| 
1361                         //kWindowSupportsDragHilite| 
1362                         kWindowCanDrawInCurrentPort
| 
1363                         //kWindowCanMeasureTitle| 
1364                         kWindowWantsDisposeAtProcessDeath
| 
1365                         kWindowSupportsSetGrowImageRegion
| 
1366                         kWindowDefSupportsColorGrafPort
; 
1370 // The content region is left as a rectangle matching the window size, this is 
1371 // so the origin in the paint event, and etc. still matches what the 
1372 // programmer expects. 
1373 static void wxShapedMacWindowContentRegion(WindowRef window
, RgnHandle rgn
) 
1376     wxTopLevelWindowMac
* win 
= wxFindWinFromMacWindow(window
); 
1379         wxRect r 
= win
->GetRect(); 
1380         SetRectRgn(rgn
, r
.GetLeft(), r
.GetTop(), r
.GetRight(), r
.GetBottom()); 
1384 // The structure region is set to the shape given to the SetShape method. 
1385 static void wxShapedMacWindowStructureRegion(WindowRef window
, RgnHandle rgn
) 
1387     RgnHandle cachedRegion 
= (RgnHandle
) GetWRefCon(window
); 
1393         wxShapedMacWindowGetPos(window
, &windowRect
);   //how big is the window 
1394         CopyRgn(cachedRegion
, rgn
);             //make a copy of our cached region 
1395         OffsetRgn(rgn
, windowRect
.left
, windowRect
.top
); // position it over window 
1396         //MapRgn(rgn, &mMaskSize, &windowRect); //scale it to our actual window size 
1402 static SInt32 
wxShapedMacWindowGetRegion(WindowRef window
, SInt32 param
) 
1404     GetWindowRegionPtr rgnRec
=(GetWindowRegionPtr
)param
; 
1406     switch(rgnRec
->regionCode
) 
1408         case kWindowStructureRgn
: 
1409             wxShapedMacWindowStructureRegion(window
, rgnRec
->winRgn
); 
1411         case kWindowContentRgn
: 
1412             wxShapedMacWindowContentRegion(window
, rgnRec
->winRgn
); 
1415             SetEmptyRgn(rgnRec
->winRgn
); 
1422 static SInt32 
wxShapedMacWindowHitTest(WindowRef window
,SInt32 param
) 
1424     /*------------------------------------------------------ 
1425         Determine the region of the window which was hit 
1426     --------------------------------------------------------*/ 
1428     static RgnHandle tempRgn
=nil
; 
1433     SetPt(&hitPoint
,LoWord(param
),HiWord(param
));//get the point clicked 
1435      //Mac OS 8.5 or later 
1436     wxShapedMacWindowStructureRegion(window
, tempRgn
); 
1437     if (PtInRgn(hitPoint
, tempRgn
)) //in window content region? 
1440     return wNoHit
;//no significant area was hit. 
1444 static pascal long wxShapedMacWindowDef(short varCode
, WindowRef window
, SInt16 message
, SInt32 param
) 
1448         case kWindowMsgHitTest
: 
1449             return wxShapedMacWindowHitTest(window
,param
); 
1451         case kWindowMsgGetFeatures
: 
1452             return wxShapedMacWindowGetFeatures(window
,param
); 
1454         // kWindowMsgGetRegion is sent during CreateCustomWindow and ReshapeCustomWindow 
1455         case kWindowMsgGetRegion
: 
1456             return wxShapedMacWindowGetRegion(window
,param
); 
1463 // ---------------------------------------------------------------------------