1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  21     #pragma implementation "frame.h" 
  24 // For compilers that support precompilation, includes "wx.h". 
  25 #include "wx/wxprec.h" 
  36     #include "wx/dialog.h" 
  37     #include "wx/settings.h" 
  38     #include "wx/dcclient.h" 
  43 #include "wx/msw/private.h" 
  46     #include "wx/statusbr.h" 
  47     #include "wx/generic/statusbr.h" 
  48 #endif // wxUSE_STATUSBAR 
  51     #include "wx/toolbar.h" 
  52 #endif // wxUSE_TOOLBAR 
  54 #include "wx/menuitem.h" 
  57 #ifdef __WXUNIVERSAL__ 
  58     #include "wx/univ/theme.h" 
  59     #include "wx/univ/colschem.h" 
  60 #endif // __WXUNIVERSAL__ 
  62 // ---------------------------------------------------------------------------- 
  64 // ---------------------------------------------------------------------------- 
  66 extern wxWindowList wxModelessWindows
; 
  67 extern wxList WXDLLEXPORT wxPendingDelete
; 
  68 extern const wxChar 
*wxFrameClassName
; 
  70 #if wxUSE_MENUS_NATIVE 
  71 extern wxMenu 
*wxCurrentPopupMenu
; 
  72 #endif // wxUSE_MENUS_NATIVE 
  74 // ---------------------------------------------------------------------------- 
  76 // ---------------------------------------------------------------------------- 
  78 BEGIN_EVENT_TABLE(wxFrameMSW
, wxFrameBase
) 
  79     EVT_ACTIVATE(wxFrameMSW::OnActivate
) 
  80     EVT_SYS_COLOUR_CHANGED(wxFrameMSW::OnSysColourChanged
) 
  83 #ifndef __WXUNIVERSAL__ 
  84     IMPLEMENT_DYNAMIC_CLASS(wxFrame
, wxWindow
) 
  87 // ============================================================================ 
  89 // ============================================================================ 
  91 // ---------------------------------------------------------------------------- 
  92 // static class members 
  93 // ---------------------------------------------------------------------------- 
  96     #if wxUSE_NATIVE_STATUSBAR 
  97         bool wxFrameMSW::m_useNativeStatusBar 
= TRUE
; 
  99         bool wxFrameMSW::m_useNativeStatusBar 
= FALSE
; 
 101 #endif // wxUSE_NATIVE_STATUSBAR 
 103 // ---------------------------------------------------------------------------- 
 104 // creation/destruction 
 105 // ---------------------------------------------------------------------------- 
 107 void wxFrameMSW::Init() 
 110     m_maximizeOnShow 
= FALSE
; 
 116     // Data to save/restore when calling ShowFullScreen 
 118     m_fsOldWindowStyle 
= 0; 
 119     m_fsStatusBarFields 
= 0; 
 120     m_fsStatusBarHeight 
= 0; 
 121     m_fsToolBarHeight 
= 0; 
 123     m_fsIsMaximized 
= FALSE
; 
 124     m_fsIsShowing 
= FALSE
; 
 126     m_winLastFocused 
= (wxWindow 
*)NULL
; 
 128     // unlike (almost?) all other windows, frames are created hidden 
 132 bool wxFrameMSW::Create(wxWindow 
*parent
, 
 134                      const wxString
& title
, 
 138                      const wxString
& name
) 
 141   m_windowStyle 
= style
; 
 143   m_frameMenuBar 
= NULL
; 
 144 #endif // wxUSE_MENUS 
 146   m_frameToolBar 
= NULL
; 
 147 #endif // wxUSE_TOOLBAR 
 149   m_frameStatusBar 
= NULL
; 
 150 #endif // wxUSE_STATUSBAR 
 152   SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
)); 
 157     m_windowId 
= (int)NewControlId(); 
 159   if (parent
) parent
->AddChild(this); 
 168   wxTopLevelWindows
.Append(this); 
 170   MSWCreate(m_windowId
, parent
, wxFrameClassName
, this, title
, 
 171             x
, y
, width
, height
, style
); 
 173   wxModelessWindows
.Append(this); 
 178 wxFrameMSW::~wxFrameMSW() 
 180   m_isBeingDeleted 
= TRUE
; 
 181   wxTopLevelWindows
.DeleteObject(this); 
 183   // the ~wxToolBar() code relies on the previous line to be executed before 
 184   // this one, i.e. the frame should remove itself from wxTopLevelWindows 
 185   // before destorying its toolbar 
 188   if (wxTheApp 
&& (wxTopLevelWindows
.Number() == 0)) 
 190     wxTheApp
->SetTopWindow(NULL
); 
 192     if (wxTheApp
->GetExitOnFrameDelete()) 
 198   wxModelessWindows
.DeleteObject(this); 
 200   // For some reason, wxWindows can activate another task altogether 
 201   // when a frame is destroyed after a modal dialog has been invoked. 
 202   // Try to bring the parent to the top. 
 203   // MT:Only do this if this frame is currently the active window, else weird 
 204   // things start to happen 
 205   if ( wxGetActiveWindow() == this ) 
 206   if (GetParent() && GetParent()->GetHWND()) 
 207     ::BringWindowToTop((HWND
) GetParent()->GetHWND()); 
 210 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. 
 211 void wxFrameMSW::DoGetClientSize(int *x
, int *y
) const 
 214   ::GetClientRect(GetHwnd(), &rect
); 
 217   if ( GetStatusBar() && GetStatusBar()->IsShown() ) 
 219     int statusX
, statusY
; 
 220     GetStatusBar()->GetClientSize(&statusX
, &statusY
); 
 221     rect
.bottom 
-= statusY
; 
 223 #endif // wxUSE_STATUSBAR 
 225   wxPoint 
pt(GetClientAreaOrigin()); 
 235 // Set the client size (i.e. leave the calculation of borders etc. 
 237 void wxFrameMSW::DoSetClientSize(int width
, int height
) 
 239     HWND hWnd 
= GetHwnd(); 
 242     ::GetClientRect(hWnd
, &rectClient
); 
 245     ::GetWindowRect(hWnd
, &rectTotal
); 
 247     // Find the difference between the entire window (title bar and all) 
 248     // and the client area; add this to the new client size to move the 
 250     width 
+= rectTotal
.right 
- rectTotal
.left 
- rectClient
.right
; 
 251     height 
+= rectTotal
.bottom 
- rectTotal
.top 
- rectClient
.bottom
; 
 254     wxStatusBar 
*statbar 
= GetStatusBar(); 
 255     if ( statbar 
&& statbar
->IsShown() ) 
 257         // leave enough space for the status bar 
 258         height 
+= statbar
->GetSize().y
; 
 260 #endif // wxUSE_STATUSBAR 
 262     // note that this takes the toolbar into account 
 263     wxPoint pt 
= GetClientAreaOrigin(); 
 267     if ( !::MoveWindow(hWnd
, rectTotal
.left
, rectTotal
.top
, 
 268                        width
, height
, TRUE 
/* redraw */) ) 
 270         wxLogLastError(_T("MoveWindow")); 
 273     wxSizeEvent 
event(wxSize(width
, height
), m_windowId
); 
 274     event
.SetEventObject(this); 
 275     GetEventHandler()->ProcessEvent(event
); 
 278 void wxFrameMSW::DoGetSize(int *width
, int *height
) const 
 281     ::GetWindowRect(GetHwnd(), &rect
); 
 283     *width 
= rect
.right 
- rect
.left
; 
 284     *height 
= rect
.bottom 
- rect
.top
; 
 287 void wxFrameMSW::DoGetPosition(int *x
, int *y
) const 
 290     ::GetWindowRect(GetHwnd(), &rect
); 
 296 // ---------------------------------------------------------------------------- 
 297 // variations around ::ShowWindow() 
 298 // ---------------------------------------------------------------------------- 
 300 void wxFrameMSW::DoShowWindow(int nShowCmd
) 
 302     ::ShowWindow(GetHwnd(), nShowCmd
); 
 304     m_iconized 
= nShowCmd 
== SW_MINIMIZE
; 
 307 bool wxFrameMSW::Show(bool show
) 
 309     // don't use wxWindow version as we want to call DoShowWindow() 
 310     if ( !wxWindowBase::Show(show
) ) 
 316         if ( m_maximizeOnShow 
) 
 319             nShowCmd 
= SW_MAXIMIZE
; 
 321             m_maximizeOnShow 
= FALSE
; 
 333     DoShowWindow(nShowCmd
); 
 337         ::BringWindowToTop(GetHwnd()); 
 339         wxActivateEvent 
event(wxEVT_ACTIVATE
, TRUE
, m_windowId
); 
 340         event
.SetEventObject( this ); 
 341         GetEventHandler()->ProcessEvent(event
); 
 345         // Try to highlight the correct window (the parent) 
 348             HWND hWndParent 
= GetHwndOf(GetParent()); 
 350                 ::BringWindowToTop(hWndParent
); 
 357 void wxFrameMSW::Iconize(bool iconize
) 
 359     DoShowWindow(iconize 
? SW_MINIMIZE 
: SW_RESTORE
); 
 362 void wxFrameMSW::Maximize(bool maximize
) 
 366         // just maximize it directly 
 367         DoShowWindow(maximize 
? SW_MAXIMIZE 
: SW_RESTORE
); 
 371         // we can't maximize the hidden frame because it shows it as well, so 
 372         // just remember that we should do it later in this case 
 373         m_maximizeOnShow 
= TRUE
; 
 377 void wxFrameMSW::Restore() 
 379     DoShowWindow(SW_RESTORE
); 
 382 bool wxFrameMSW::IsIconized() const 
 384 #ifdef __WXMICROWIN__ 
 388   ((wxFrameMSW 
*)this)->m_iconized 
= (::IsIconic(GetHwnd()) != 0); 
 394 bool wxFrameMSW::IsMaximized() const 
 396 #ifdef __WXMICROWIN__ 
 400     return (::IsZoomed(GetHwnd()) != 0); 
 404 void wxFrameMSW::SetIcon(const wxIcon
& icon
) 
 406     wxFrameBase::SetIcon(icon
); 
 408 #if defined(__WIN95__) && !defined(__WXMICROWIN__) 
 411         SendMessage(GetHwnd(), WM_SETICON
, 
 412                     (WPARAM
)TRUE
, (LPARAM
)(HICON
) m_icon
.GetHICON()); 
 417 // generate an artificial resize event 
 418 void wxFrameMSW::SendSizeEvent() 
 422     ::GetWindowRect(GetHwnd(), &r
); 
 424     if ( !::GetWindowRect(GetHwnd(), &r
) ) 
 426         wxLogLastError(_T("GetWindowRect")); 
 432         (void)::PostMessage(GetHwnd(), WM_SIZE
, 
 433                             IsMaximized() ? SIZE_MAXIMIZED 
: SIZE_RESTORED
, 
 434                             MAKELPARAM(r
.right 
- r
.left
, r
.bottom 
- r
.top
)); 
 439 wxStatusBar 
*wxFrameMSW::OnCreateStatusBar(int number
, 
 442                                         const wxString
& name
) 
 444     wxStatusBar 
*statusBar 
= NULL
; 
 446 #if wxUSE_NATIVE_STATUSBAR 
 447     if ( !UsesNativeStatusBar() ) 
 449         statusBar 
= (wxStatusBar 
*)new wxStatusBarGeneric(this, id
, style
); 
 454         statusBar 
= new wxStatusBar(this, id
, style
, name
); 
 457     // Set the height according to the font and the border size 
 458     wxClientDC 
dc(statusBar
); 
 459     dc
.SetFont(statusBar
->GetFont()); 
 462     dc
.GetTextExtent(_T("X"), NULL
, &y 
); 
 464     int height 
= (int)( (11*y
)/10 + 2*statusBar
->GetBorderY()); 
 466     statusBar
->SetSize(-1, -1, -1, height
); 
 468     statusBar
->SetFieldsCount(number
); 
 473 void wxFrameMSW::PositionStatusBar() 
 475     if ( !m_frameStatusBar 
) 
 479     GetClientSize(&w
, &h
); 
 481     m_frameStatusBar
->GetSize(&sw
, &sh
); 
 483     // Since we wish the status bar to be directly under the client area, 
 484     // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. 
 485     m_frameStatusBar
->SetSize(0, h
, w
, sh
); 
 487 #endif // wxUSE_STATUSBAR 
 489 void wxFrameMSW::DetachMenuBar() 
 492     if ( m_frameMenuBar 
) 
 494         m_frameMenuBar
->Detach(); 
 495         m_frameMenuBar 
= NULL
; 
 497 #endif // wxUSE_MENUS 
 500 void wxFrameMSW::SetMenuBar(wxMenuBar 
*menubar
) 
 503     // detach the old menu bar in any case 
 506 #if wxUSE_MENUS_NATIVE 
 509         // actually remove the menu from the frame 
 510         m_hMenu 
= (WXHMENU
)0; 
 511         InternalSetMenuBar(); 
 513     else // set new non NULL menu bar 
 515         // Can set a menubar several times. 
 516         if ( menubar
->GetHMenu() ) 
 518             m_hMenu 
= menubar
->GetHMenu(); 
 522             if (menubar
->IsAttached()) 
 525             m_hMenu 
= menubar
->Create(); 
 531         InternalSetMenuBar(); 
 533 #endif // wxUSE_MENUS_NATIVE 
 537         m_frameMenuBar 
= menubar
; 
 538         menubar
->Attach((wxFrame 
*)this); 
 540 #endif // wxUSE_MENUS 
 543 #if wxUSE_MENUS_NATIVE 
 545 void wxFrameMSW::InternalSetMenuBar() 
 547 #ifndef __WXMICROWIN__ 
 548     if ( !::SetMenu(GetHwnd(), (HMENU
)m_hMenu
) ) 
 550         wxLogLastError(wxT("SetMenu")); 
 555 #endif // wxUSE_MENUS_NATIVE 
 557 // Responds to colour changes, and passes event on to children. 
 558 void wxFrameMSW::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 560     SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
)); 
 564     if ( m_frameStatusBar 
) 
 566         wxSysColourChangedEvent event2
; 
 567         event2
.SetEventObject( m_frameStatusBar 
); 
 568         m_frameStatusBar
->GetEventHandler()->ProcessEvent(event2
); 
 570 #endif // wxUSE_STATUSBAR 
 572     // Propagate the event to the non-top-level children 
 573     wxWindow::OnSysColourChanged(event
); 
 576 // Pass TRUE to show full screen, FALSE to restore. 
 577 bool wxFrameMSW::ShowFullScreen(bool show
, long style
) 
 584         m_fsIsShowing 
= TRUE
; 
 588         wxToolBar 
*theToolBar 
= GetToolBar(); 
 590             theToolBar
->GetSize(NULL
, &m_fsToolBarHeight
); 
 592         // zap the toolbar, menubar, and statusbar 
 594         if ((style 
& wxFULLSCREEN_NOTOOLBAR
) && theToolBar
) 
 596             theToolBar
->SetSize(-1,0); 
 597             theToolBar
->Show(FALSE
); 
 599 #endif // wxUSE_TOOLBAR 
 601 #ifndef __WXMICROWIN__ 
 602         if (style 
& wxFULLSCREEN_NOMENUBAR
) 
 603             SetMenu((HWND
)GetHWND(), (HMENU
) NULL
); 
 607         wxStatusBar 
*theStatusBar 
= GetStatusBar(); 
 609             theStatusBar
->GetSize(NULL
, &m_fsStatusBarHeight
); 
 611         // Save the number of fields in the statusbar 
 612         if ((style 
& wxFULLSCREEN_NOSTATUSBAR
) && theStatusBar
) 
 614             //m_fsStatusBarFields = theStatusBar->GetFieldsCount(); 
 615             //SetStatusBar((wxStatusBar*) NULL); 
 616             //delete theStatusBar; 
 617             theStatusBar
->Show(FALSE
); 
 620             m_fsStatusBarFields 
= 0; 
 621 #endif // wxUSE_STATUSBAR 
 623         // zap the frame borders 
 625         // save the 'normal' window style 
 626         m_fsOldWindowStyle 
= GetWindowLong((HWND
)GetHWND(), GWL_STYLE
); 
 628         // save the old position, width & height, maximize state 
 629         m_fsOldSize 
= GetRect(); 
 630         m_fsIsMaximized 
= IsMaximized(); 
 632         // decide which window style flags to turn off 
 633         LONG newStyle 
= m_fsOldWindowStyle
; 
 636         if (style 
& wxFULLSCREEN_NOBORDER
) 
 637             offFlags 
|= WS_BORDER
; 
 638         if (style 
& wxFULLSCREEN_NOCAPTION
) 
 639             offFlags 
|= (WS_CAPTION 
| WS_SYSMENU
); 
 641         newStyle 
&= (~offFlags
); 
 643         // change our window style to be compatible with full-screen mode 
 644         SetWindowLong((HWND
)GetHWND(), GWL_STYLE
, newStyle
); 
 646         // resize to the size of the desktop 
 650         ::GetWindowRect(GetDesktopWindow(), &rect
); 
 651         width 
= rect
.right 
- rect
.left
; 
 652         height 
= rect
.bottom 
- rect
.top
; 
 654         SetSize(width
, height
); 
 656         // now flush the window style cache and actually go full-screen 
 657         SetWindowPos((HWND
)GetHWND(), HWND_TOP
, 0, 0, width
, height
, SWP_FRAMECHANGED
); 
 659         wxSizeEvent 
event(wxSize(width
, height
), GetId()); 
 660         GetEventHandler()->ProcessEvent(event
); 
 669         m_fsIsShowing 
= FALSE
; 
 672         wxToolBar 
*theToolBar 
= GetToolBar(); 
 674         // restore the toolbar, menubar, and statusbar 
 675         if (theToolBar 
&& (m_fsStyle 
& wxFULLSCREEN_NOTOOLBAR
)) 
 677             theToolBar
->SetSize(-1, m_fsToolBarHeight
); 
 678             theToolBar
->Show(TRUE
); 
 680 #endif // wxUSE_TOOLBAR 
 683         if ( m_fsStyle 
& wxFULLSCREEN_NOSTATUSBAR 
) 
 685             //CreateStatusBar(m_fsStatusBarFields); 
 688                 GetStatusBar()->Show(TRUE
); 
 692 #endif // wxUSE_STATUSBAR 
 694 #ifndef __WXMICROWIN__ 
 695         if ((m_fsStyle 
& wxFULLSCREEN_NOMENUBAR
) && (m_hMenu 
!= 0)) 
 696             SetMenu((HWND
)GetHWND(), (HMENU
)m_hMenu
); 
 699         Maximize(m_fsIsMaximized
); 
 700         SetWindowLong((HWND
)GetHWND(),GWL_STYLE
, m_fsOldWindowStyle
); 
 701         SetWindowPos((HWND
)GetHWND(),HWND_TOP
,m_fsOldSize
.x
, m_fsOldSize
.y
, 
 702             m_fsOldSize
.width
, m_fsOldSize
.height
, SWP_FRAMECHANGED
); 
 713 bool wxFrameMSW::MSWCreate(int id
, wxWindow 
*parent
, const wxChar 
*wclass
, wxWindow 
*wx_win
, const wxChar 
*title
, 
 714                    int x
, int y
, int width
, int height
, long style
) 
 717   m_defaultIcon 
= (WXHICON
) (wxSTD_FRAME_ICON 
? wxSTD_FRAME_ICON 
: wxDEFAULT_FRAME_ICON
); 
 719   // If child windows aren't properly drawn initially, WS_CLIPCHILDREN 
 720   // could be the culprit. But without it, you can get a lot of flicker. 
 723   if ( style 
& wxCAPTION 
) 
 725     if ( style 
& wxFRAME_TOOL_WINDOW 
) 
 726         msflags 
|= WS_POPUPWINDOW
; 
 728         msflags 
|= WS_OVERLAPPED
; 
 735   if (style 
& wxMINIMIZE_BOX
) 
 736     msflags 
|= WS_MINIMIZEBOX
; 
 737   if (style 
& wxMAXIMIZE_BOX
) 
 738     msflags 
|= WS_MAXIMIZEBOX
; 
 739   if (style 
& wxTHICK_FRAME
) 
 740     msflags 
|= WS_THICKFRAME
; 
 741   if (style 
& wxSYSTEM_MENU
) 
 742     msflags 
|= WS_SYSMENU
; 
 743   if ( style 
& wxMINIMIZE 
) 
 744     msflags 
|= WS_MINIMIZE
; 
 745   if (style 
& wxMAXIMIZE
) 
 746     msflags 
|= WS_MAXIMIZE
; 
 747   if (style 
& wxCAPTION
) 
 748     msflags 
|= WS_CAPTION
; 
 749   if (style 
& wxCLIP_CHILDREN
) 
 750     msflags 
|= WS_CLIPCHILDREN
; 
 752   // Keep this in wxFrameMSW because it saves recoding this function 
 754 #if wxUSE_ITSY_BITSY && !defined(__WIN32__) 
 755   if (style 
& wxTINY_CAPTION_VERT
) 
 756     msflags 
|= IBS_VERTCAPTION
; 
 757   if (style 
& wxTINY_CAPTION_HORIZ
) 
 758     msflags 
|= IBS_HORZCAPTION
; 
 760   if (style 
& wxTINY_CAPTION_VERT
) 
 761     msflags 
|= WS_CAPTION
; 
 762   if (style 
& wxTINY_CAPTION_HORIZ
) 
 763     msflags 
|= WS_CAPTION
; 
 765   if ((style 
& wxTHICK_FRAME
) == 0) 
 766     msflags 
|= WS_BORDER
; 
 768   WXDWORD extendedStyle 
= MakeExtendedStyle(style
); 
 770   // make all frames appear in the win9x shell taskbar unless 
 771   // wxFRAME_TOOL_WINDOW or wxFRAME_NO_TASKBAR is given - without giving them 
 772   // WS_EX_APPWINDOW style, the child (i.e. owned) frames wouldn't appear in it 
 773 #if !defined(__WIN16__) && !defined(__SC__) 
 774   if ( (style 
& wxFRAME_TOOL_WINDOW
) || 
 775        (style 
& wxFRAME_NO_TASKBAR
) ) 
 776       extendedStyle 
|= WS_EX_TOOLWINDOW
; 
 777   else if ( !(style 
& wxFRAME_NO_TASKBAR
) ) 
 778       extendedStyle 
|= WS_EX_APPWINDOW
; 
 781   if (style 
& wxSTAY_ON_TOP
) 
 782     extendedStyle 
|= WS_EX_TOPMOST
; 
 785   if (m_exStyle 
& wxFRAME_EX_CONTEXTHELP
) 
 786     extendedStyle 
|= WS_EX_CONTEXTHELP
; 
 790   if ( !wxWindow::MSWCreate(id
, parent
, wclass
, wx_win
, title
, x
, y
, width
, height
, 
 791          msflags
, NULL
, extendedStyle
) ) 
 794   // Seems to be necessary if we use WS_POPUP 
 795   // style instead of WS_OVERLAPPED 
 796   if (width 
> -1 && height 
> -1) 
 797     ::PostMessage(GetHwnd(), WM_SIZE
, SIZE_RESTORED
, MAKELPARAM(width
, height
)); 
 802 // Default activation behaviour - set the focus for the first child 
 804 void wxFrameMSW::OnActivate(wxActivateEvent
& event
) 
 806     if ( event
.GetActive() ) 
 808         // restore focus to the child which was last focused 
 809         wxLogTrace(_T("focus"), _T("wxFrameMSW %08x activated."), m_hWnd
); 
 811         wxWindow 
*parent 
= m_winLastFocused 
? m_winLastFocused
->GetParent() 
 818         wxSetFocusToChild(parent
, &m_winLastFocused
); 
 822         // remember the last focused child if it is our child 
 823         m_winLastFocused 
= FindFocus(); 
 825         // so we NULL it out if it's a child from some other frame 
 826         wxWindow 
*win 
= m_winLastFocused
; 
 829             if ( win
->IsTopLevel() ) 
 833                     m_winLastFocused 
= NULL
; 
 839             win 
= win
->GetParent(); 
 842         wxLogTrace(_T("focus"), 
 843                    _T("wxFrameMSW %08x deactivated, last focused: %08x."), 
 845                    m_winLastFocused 
? GetHwndOf(m_winLastFocused
) 
 852 // ---------------------------------------------------------------------------- 
 853 // tool/status bar stuff 
 854 // ---------------------------------------------------------------------------- 
 858 wxToolBar
* wxFrameMSW::CreateToolBar(long style
, wxWindowID id
, const wxString
& name
) 
 860     if ( wxFrameBase::CreateToolBar(style
, id
, name
) ) 
 865     return m_frameToolBar
; 
 868 void wxFrameMSW::PositionToolBar() 
 871     ::GetClientRect(GetHwnd(), &rect
); 
 874     if ( GetStatusBar() ) 
 876         int statusX
, statusY
; 
 877         GetStatusBar()->GetClientSize(&statusX
, &statusY
); 
 878         rect
.bottom 
-= statusY
; 
 880 #endif // wxUSE_STATUSBAR 
 882     if ( GetToolBar() && GetToolBar()->IsShown() ) 
 885         GetToolBar()->GetSize(&tw
, &th
); 
 887         if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 896         // Use the 'real' MSW position here 
 897         GetToolBar()->SetSize(0, 0, tw
, th
, wxSIZE_NO_ADJUSTMENTS
); 
 900 #endif // wxUSE_TOOLBAR 
 902 // ---------------------------------------------------------------------------- 
 903 // frame state (iconized/maximized/...) 
 904 // ---------------------------------------------------------------------------- 
 906 // propagate our state change to all child frames: this allows us to emulate X 
 907 // Windows behaviour where child frames float independently of the parent one 
 908 // on the desktop, but are iconized/restored with it 
 909 void wxFrameMSW::IconizeChildFrames(bool bIconize
) 
 911     for ( wxWindowList::Node 
*node 
= GetChildren().GetFirst(); 
 913           node 
= node
->GetNext() ) 
 915         wxWindow 
*win 
= node
->GetData(); 
 917         // iconizing the frames with this style under Win95 shell puts them at 
 918         // the bottom of the screen (as the MDI children) instead of making 
 919         // them appear in the taskbar because they are, by virtue of this 
 920         // style, not managed by the taskbar - instead leave Windows take care 
 923         if ( win
->GetWindowStyle() & wxFRAME_TOOL_WINDOW 
) 
 927         // the child MDI frames are a special case and should not be touched by 
 928         // the parent frame - instead, they are managed by the user 
 929         wxFrameMSW 
*frame 
= wxDynamicCast(win
, wxFrameMSW
); 
 931 #if wxUSE_MDI_ARCHITECTURE 
 932                 && !wxDynamicCast(frame
, wxMDIChildFrame
) 
 933 #endif // wxUSE_MDI_ARCHITECTURE 
 936             frame
->Iconize(bIconize
); 
 941 // =========================================================================== 
 942 // message processing 
 943 // =========================================================================== 
 945 // --------------------------------------------------------------------------- 
 947 // --------------------------------------------------------------------------- 
 949 bool wxFrameMSW::MSWTranslateMessage(WXMSG
* pMsg
) 
 951     if ( wxWindow::MSWTranslateMessage(pMsg
) ) 
 954 #if wxUSE_MENUS && wxUSE_ACCEL && !defined(__WXUNIVERSAL__) 
 955     // try the menu bar accels 
 956     wxMenuBar 
*menuBar 
= GetMenuBar(); 
 960     const wxAcceleratorTable
& acceleratorTable 
= menuBar
->GetAccelTable(); 
 961     return acceleratorTable
.Translate(this, pMsg
); 
 964 #endif // wxUSE_MENUS && wxUSE_ACCEL 
 967 // --------------------------------------------------------------------------- 
 968 // our private (non virtual) message handlers 
 969 // --------------------------------------------------------------------------- 
 971 bool wxFrameMSW::HandlePaint() 
 974     if ( GetUpdateRect(GetHwnd(), &rect
, FALSE
) ) 
 976 #ifndef __WXMICROWIN__ 
 979             HICON hIcon 
= m_icon
.Ok() ? GetHiconOf(m_icon
) 
 980                                       : (HICON
)m_defaultIcon
; 
 982             // Hold a pointer to the dc so long as the OnPaint() message 
 983             // is being processed 
 985             HDC hdc 
= ::BeginPaint(GetHwnd(), &ps
); 
 987             // Erase background before painting or we get white background 
 988             MSWDefWindowProc(WM_ICONERASEBKGND
, (WORD
)(LONG
)ps
.hdc
, 0L); 
 993                 ::GetClientRect(GetHwnd(), &rect
); 
 995                 // FIXME: why hardcoded? 
 996                 static const int icon_width 
= 32; 
 997                 static const int icon_height 
= 32; 
 999                 int icon_x 
= (int)((rect
.right 
- icon_width
)/2); 
1000                 int icon_y 
= (int)((rect
.bottom 
- icon_height
)/2); 
1002                 ::DrawIcon(hdc
, icon_x
, icon_y
, hIcon
); 
1005             ::EndPaint(GetHwnd(), &ps
); 
1012             return wxWindow::HandlePaint(); 
1017         // nothing to paint - processed 
1022 bool wxFrameMSW::HandleSize(int x
, int y
, WXUINT id
) 
1024     bool processed 
= FALSE
; 
1025 #ifndef __WXMICROWIN__ 
1030             // only do it it if we were iconized before, otherwise resizing the 
1031             // parent frame has a curious side effect of bringing it under it's 
1036             // restore all child frames too 
1037             IconizeChildFrames(FALSE
); 
1039             (void)SendIconizeEvent(FALSE
); 
1043         case SIZEFULLSCREEN
: 
1048             // iconize all child frames too 
1049             IconizeChildFrames(TRUE
); 
1051             (void)SendIconizeEvent(); 
1061         PositionStatusBar(); 
1062 #endif // wxUSE_STATUSBAR 
1066 #endif // wxUSE_TOOLBAR 
1068         wxSizeEvent 
event(wxSize(x
, y
), m_windowId
); 
1069         event
.SetEventObject( this ); 
1070         processed 
= GetEventHandler()->ProcessEvent(event
); 
1076 bool wxFrameMSW::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND control
) 
1080         // In case it's e.g. a toolbar. 
1081         wxWindow 
*win 
= wxFindWinFromHandle(control
); 
1083             return win
->MSWCommand(cmd
, id
); 
1086     // handle here commands from menus and accelerators 
1087     if ( cmd 
== 0 || cmd 
== 1 ) 
1089 #if wxUSE_MENUS_NATIVE 
1090         if ( wxCurrentPopupMenu 
) 
1092             wxMenu 
*popupMenu 
= wxCurrentPopupMenu
; 
1093             wxCurrentPopupMenu 
= NULL
; 
1095             return popupMenu
->MSWCommand(cmd
, id
); 
1097 #endif // wxUSE_MENUS_NATIVE 
1099         if ( ProcessCommand(id
) ) 
1108 bool wxFrameMSW::HandleMenuSelect(WXWORD nItem
, WXWORD flags
, WXHMENU hMenu
) 
1111     if ( flags 
== 0xFFFF && hMenu 
== 0 ) 
1113         // menu was removed from screen 
1116 #ifndef __WXMICROWIN__ 
1117     else if ( !(flags 
& MF_POPUP
) && !(flags 
& MF_SEPARATOR
) ) 
1125         // don't give hints for separators (doesn't make sense) nor for the 
1126         // items opening popup menus (they don't have them anyhow) but do clear 
1127         // the status line - otherwise, we would be left with the help message 
1128         // for the previous item which doesn't apply any more 
1129         wxStatusBar 
*statbar 
= GetStatusBar(); 
1132             statbar
->SetStatusText(wxEmptyString
); 
1134 #endif // wxUSE_STATUSBAR 
1139     wxMenuEvent 
event(wxEVT_MENU_HIGHLIGHT
, item
); 
1140     event
.SetEventObject( this ); 
1142     return GetEventHandler()->ProcessEvent(event
); 
1145 // --------------------------------------------------------------------------- 
1146 // the window proc for wxFrameMSW 
1147 // --------------------------------------------------------------------------- 
1149 long wxFrameMSW::MSWWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
1152     bool processed 
= FALSE
; 
1157             // if we can't close, tell the system that we processed the 
1158             // message - otherwise it would close us 
1159             processed 
= !Close(); 
1166                 UnpackCommand((WXWPARAM
)wParam
, (WXLPARAM
)lParam
, 
1169                 processed 
= HandleCommand(id
, cmd
, (WXHWND
)hwnd
); 
1173 #ifndef __WXMICROWIN__ 
1178                 UnpackMenuSelect(wParam
, lParam
, &item
, &flags
, &hmenu
); 
1180                 processed 
= HandleMenuSelect(item
, flags
, hmenu
); 
1186             processed 
= HandlePaint(); 
1189 #ifndef __WXMICROWIN__ 
1190         case WM_QUERYDRAGICON
: 
1192                 HICON hIcon 
= m_icon
.Ok() ? GetHiconOf(m_icon
) 
1193                                           : (HICON
)(m_defaultIcon
); 
1195                 processed 
= rc 
!= 0; 
1201             processed 
= HandleSize(LOWORD(lParam
), HIWORD(lParam
), wParam
); 
1206         rc 
= wxWindow::MSWWindowProc(message
, wParam
, lParam
);