1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     MDI classes 
   4 // Author:      David Webster 
   8 // Copyright:   (c) David Webster 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 // For compilers that support precompilation, includes "wx.h". 
  13 #include "wx/wxprec.h" 
  21     #include "wx/dialog.h" 
  22     #include "wx/statusbr.h" 
  23     #include "wx/settings.h" 
  29 #include "wx/os2/private.h" 
  33 // --------------------------------------------------------------------------- 
  35 // --------------------------------------------------------------------------- 
  37 extern wxWindowList wxModelessWindows
;      // from dialog.cpp 
  38 extern wxMenu 
*wxCurrentPopupMenu
; 
  40 extern wxChar wxMDIFrameClassName
[]; 
  41 extern wxChar wxMDIChildFrameClassName
[]; 
  42 extern wxWindow 
*wxWndHook
;                 // from window.cpp 
  44 extern void wxAssociateWinWithHandle(HWND hWnd
, wxWindow 
*win
); 
  46 static HWND invalidHandle 
= 0; 
  48 // --------------------------------------------------------------------------- 
  50 // --------------------------------------------------------------------------- 
  52 static const int IDM_WINDOWTILE  
= 4001; 
  53 static const int IDM_WINDOWTILEHOR  
= 4001; 
  54 static const int IDM_WINDOWCASCADE 
= 4002; 
  55 static const int IDM_WINDOWICONS 
= 4003; 
  56 static const int IDM_WINDOWNEXT 
= 4004; 
  57 static const int IDM_WINDOWTILEVERT 
= 4005; 
  59 // This range gives a maximum of 500 MDI children. Should be enough :-) 
  60 static const int wxFIRST_MDI_CHILD 
= 4100; 
  61 static const int wxLAST_MDI_CHILD 
= 4600; 
  63 // Status border dimensions 
  64 static const int wxTHICK_LINE_BORDER 
= 3; 
  65 static const int wxTHICK_LINE_WIDTH  
= 1; 
  67 // --------------------------------------------------------------------------- 
  69 // --------------------------------------------------------------------------- 
  71 // set the MDI menus (by sending the WM_MDISETMENU message) and update the menu 
  72 // of the parent of win (which is supposed to be the MDI client window) 
  73 static void MDISetMenu(wxWindow 
*win
, HMENU hmenuFrame
, HMENU hmenuWindow
); 
  75 // insert the window menu (subMenu) into menu just before "Help" submenu or at 
  76 // the very end if not found 
  77 static void InsertWindowMenu(wxWindow 
*win
, WXHMENU menu
, HMENU subMenu
); 
  79 // is this an id of an MDI child? 
  80 inline bool IsMdiCommandId(int id
) 
  82     return (id 
>= wxFIRST_MDI_CHILD
) && (id 
<= wxLAST_MDI_CHILD
); 
  85 static void UnpackMDIActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
  86                               WXWORD 
*activate
, WXHWND 
*hwndAct
, WXHWND 
*hwndDeact
); 
  88 // =========================================================================== 
  90 // =========================================================================== 
  92 // --------------------------------------------------------------------------- 
  94 // --------------------------------------------------------------------------- 
  96     IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame
, wxFrame
) 
  97     IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame
, wxFrame
) 
  98     IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow
, wxWindow
) 
 100 BEGIN_EVENT_TABLE(wxMDIParentFrame
, wxFrame
) 
 101     EVT_SIZE(wxMDIParentFrame::OnSize
) 
 102     EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged
) 
 105 BEGIN_EVENT_TABLE(wxMDIClientWindow
, wxWindow
) 
 106     EVT_SCROLL(wxMDIClientWindow::OnScroll
) 
 109 // =========================================================================== 
 110 // wxMDIParentFrame: the frame which contains the client window which manages 
 112 // =========================================================================== 
 114 wxMDIParentFrame::wxMDIParentFrame() 
 116     m_clientWindow 
= NULL
; 
 117     m_currentChild 
= NULL
; 
 119     m_parentFrameActive 
= TRUE
; 
 122 bool wxMDIParentFrame::Create(wxWindow 
*parent
, 
 124                               const wxString
& title
, 
 128                               const wxString
& name
) 
 130   m_hDefaultIcon 
= (WXHICON
) (wxSTD_MDIPARENTFRAME_ICON 
? wxSTD_MDIPARENTFRAME_ICON 
: wxDEFAULT_MDIPARENTFRAME_ICON
); 
 132   m_clientWindow 
= NULL
; 
 133   m_currentChild 
= NULL
; 
 135   m_parentFrameActive 
= TRUE
; 
 138     wxTopLevelWindows
.Append(this); 
 141   wxWindowBase::Show(TRUE
); // MDI child frame starts off shown 
 142   m_windowStyle 
= style
; 
 144   if (parent
) parent
->AddChild(this); 
 149     m_windowId 
= (int)NewControlId(); 
 156 // TODO:  m_windowMenu = (WXHMENU) ::LoadMenu(wxGetInstance(), wxT("wxWindowMenu")); 
 158   DWORD msflags = WS_OVERLAPPED; 
 159   if (style & wxMINIMIZE_BOX) 
 160     msflags |= WS_MINIMIZEBOX; 
 161   if (style & wxMAXIMIZE_BOX) 
 162     msflags |= WS_MAXIMIZEBOX; 
 163   if (style & wxTHICK_FRAME) 
 164     msflags |= WS_THICKFRAME; 
 165   if (style & wxSYSTEM_MENU) 
 166     msflags |= WS_SYSMENU; 
 167   if ((style & wxMINIMIZE) || (style & wxICONIZE)) 
 168     msflags |= WS_MINIMIZE; 
 169   if (style & wxMAXIMIZE) 
 170     msflags |= WS_MAXIMIZE; 
 171   if (style & wxCAPTION) 
 172     msflags |= WS_CAPTION; 
 174   if (style & wxCLIP_CHILDREN) 
 175     msflags |= WS_CLIPCHILDREN; 
 177   wxWindow::MSWCreate(m_windowId, parent, wxMDIFrameClassName, this, title, x, y, width, height, 
 180   wxModelessWindows
.Append(this); 
 185 wxMDIParentFrame::~wxMDIParentFrame() 
 189 // TODO:    ::DestroyMenu((HMENU)m_windowMenu); 
 192     if ( m_clientWindow 
) 
 194         if ( m_clientWindow
->OS2GetOldWndProc() ) 
 195             m_clientWindow
->UnsubclassWin(); 
 197         m_clientWindow
->SetHWND(0); 
 198         delete m_clientWindow
; 
 202 void wxMDIParentFrame::InternalSetMenuBar() 
 206     HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0); 
 208     m_parentFrameActive = TRUE; 
 210     InsertWindowMenu(GetClientWindow(), m_hMenu, subMenu); 
 214 void wxMDIParentFrame::OnSize(wxSizeEvent
& event
) 
 218     if ( GetClientWindow() ) 
 221         GetClientSize(&width, &height); 
 223         GetClientWindow()->SetSize(0, 0, width, height); 
 228 // Returns the active MDI child window 
 229 wxMDIChildFrame 
*wxMDIParentFrame::GetActiveChild() const 
 231     HWND hWnd 
= 0; // TODO: (HWND)::SendMessage(GetWinHwnd(GetClientWindow()), 
 232 //                                    WM_MDIGETACTIVE, 0, 0L); 
 236         return (wxMDIChildFrame 
*)wxFindWinFromHandle((WXHWND
) hWnd
); 
 239 // Create the client window class (don't Create the window, just return a new 
 241 wxMDIClientWindow 
*wxMDIParentFrame::OnCreateClient() 
 243     return new wxMDIClientWindow
; 
 246 // Responds to colour changes, and passes event on to children. 
 247 void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
) 
 249     if ( m_clientWindow 
) 
 251         m_clientWindow
->SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
)); 
 252         m_clientWindow
->Refresh(); 
 258 // --------------------------------------------------------------------------- 
 260 // --------------------------------------------------------------------------- 
 262 void wxMDIParentFrame::Cascade() 
 264 // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0); 
 267 // TODO: add a direction argument (hor/vert) 
 268 void wxMDIParentFrame::Tile() 
 270 // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0); 
 273 void wxMDIParentFrame::ArrangeIcons() 
 275 // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDIICONARRANGE, 0, 0); 
 278 void wxMDIParentFrame::ActivateNext() 
 280 // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 0); 
 283 void wxMDIParentFrame::ActivatePrevious() 
 285 // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 1); 
 288 // --------------------------------------------------------------------------- 
 289 // the MDI parent frame window proc 
 290 // --------------------------------------------------------------------------- 
 292 MRESULT 
wxMDIParentFrame::OS2WindowProc(WXUINT message
, 
 297     bool processed 
= FALSE
; 
 305                 WXWORD state, minimized; 
 307                 UnpackActivate(wParam, lParam, &state, &minimized, &hwnd); 
 309                 processed = HandleActivate(state, minimized != 0, hwnd); 
 317                 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd); 
 319                 (void)HandleCommand(id, cmd, hwnd); 
 321                 // even if the frame didn't process it, there is no need to try it 
 322                 // once again (i.e. call wxFrame::HandleCommand()) - we just dud it, 
 323                 // so pretend we processed the message anyhow 
 327             // always pass this message DefFrameProc(), otherwise MDI menu 
 328             // commands (and sys commands - more surprizingly!) won't work 
 329             MSWDefWindowProc(message, wParam, lParam); 
 333             m_clientWindow = OnCreateClient(); 
 334             // Uses own style for client style 
 335             if ( !m_clientWindow->CreateClient(this, GetWindowStyleFlag()) ) 
 337                 wxLogMessage(_("Failed to create MDI parent frame.")); 
 348             // we erase background ourselves 
 356                 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu); 
 358                 if ( m_parentFrameActive ) 
 360                     processed = HandleMenuSelect(item, flags, hmenu); 
 362                 else if (m_currentChild) 
 364                     processed = m_currentChild-> 
 365                         HandleMenuSelect(item, flags, hmenu); 
 371             // as we don't (usually) resize the MDI client to exactly fit the 
 372             // client area (we put it below the toolbar, above statusbar &c), 
 373             // we should not pass this one to DefFrameProc 
 378         rc 
= wxFrame::OS2WindowProc(message
, wParam
, lParam
); 
 383 bool wxMDIParentFrame::HandleActivate(int state
, bool minimized
, WXHWND activate
) 
 385     bool processed 
= FALSE
; 
 389     if ( wxWindow::HandleActivate(state, minimized, activate) ) 
 395     // If this window is an MDI parent, we must also send an OnActivate message 
 396     // to the current child. 
 397     if ( (m_currentChild != NULL) && 
 398          ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) ) 
 400         wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_currentChild->GetId()); 
 401         event.SetEventObject( m_currentChild ); 
 402         if ( m_currentChild->GetEventHandler()->ProcessEvent(event) ) 
 409 bool wxMDIParentFrame::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND hwnd
) 
 411     // In case it's e.g. a toolbar. 
 414         wxWindow 
*win 
= wxFindWinFromHandle(hwnd
); 
 416             return FALSE
; // Need to get wxWindow for OS/2 up to date: win->OS2Command(cmd, id); 
 419     // is it one of standard MDI commands? 
 427         case IDM_WINDOWCASCADE: 
 429             wParam = MDITILE_SKIPDISABLED; 
 432         case IDM_WINDOWTILEHOR: 
 433             wParam |= MDITILE_HORIZONTAL; 
 436         case IDM_WINDOWTILEVERT: 
 438                 wParam = MDITILE_VERTICAL; 
 440             wParam |= MDITILE_SKIPDISABLED; 
 443         case IDM_WINDOWICONS: 
 444             msg = WM_MDIICONARRANGE; 
 457 // TODO:        ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, 0); 
 462     // FIXME VZ: what does this test do?? 
 465         return FALSE
; // Get WndProc to call default proc 
 468     if ( IsMdiCommandId(id
) ) 
 470         wxWindowList::Node
* node 
= GetChildren().GetFirst(); 
 473             wxWindow
* child 
= node
->GetData(); 
 474             if ( child
->GetHWND() ) 
 476                 long childId 
= wxGetWindowId(child
->GetHWND()); 
 477                 if (childId 
== (long)id
) 
 479 // TODO:                    ::SendMessage( GetWinHwnd(GetClientWindow()), 
 481 //                                   (WPARAM)child->GetHWND(), 0); 
 485             node 
= node
->GetNext(); 
 488     else if ( m_parentFrameActive 
) 
 490         return ProcessCommand(id
); 
 492     else if ( m_currentChild 
) 
 494         return m_currentChild
->HandleCommand(id
, cmd
, hwnd
); 
 498         // this shouldn't happen because it means that our messages are being 
 499         // lost (they're not sent to the parent frame nor to the children) 
 500         wxFAIL_MSG(wxT("MDI parent frame is not active, " 
 501                       "yet there is no active MDI child?")); 
 507 MRESULT 
wxMDIParentFrame::OS2DefWindowProc(WXUINT message
, 
 512     if ( GetClientWindow() ) 
 513         clientWnd 
= GetClientWindow()->GetHWND(); 
 517 // TODO:    return DefFrameProc(GetHwnd(), (HWND)clientWnd, message, wParam, lParam); 
 521 bool wxMDIParentFrame::OS2TranslateMessage(WXMSG
* msg
) 
 525     if ( m_currentChild && m_currentChild->GetHWND() && 
 526          m_currentChild->OS2TranslateMessage(msg) ) 
 531     if ( m_acceleratorTable.Translate(this, msg) ) 
 536     if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN ) 
 538         if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg)) 
 545 // =========================================================================== 
 547 // =========================================================================== 
 549 wxMDIChildFrame::wxMDIChildFrame() 
 553 bool wxMDIChildFrame::Create(wxMDIParentFrame 
*parent
, 
 555                              const wxString
& title
, 
 559                              const wxString
& name
) 
 561   m_hDefaultIcon 
= (WXHICON
)(wxSTD_MDICHILDFRAME_ICON 
? wxSTD_MDICHILDFRAME_ICON
 
 562                                                       : wxDEFAULT_MDICHILDFRAME_ICON
); 
 569     m_windowId 
= (int)NewControlId(); 
 573       parent
->AddChild(this); 
 587   mcs.szClass = wxMDIChildFrameClassName; 
 589   mcs.hOwner = wxGetInstance(); 
 593       mcs.x = CW_USEDEFAULT; 
 598       mcs.y = CW_USEDEFAULT; 
 603       mcs.cx = CW_USEDEFAULT; 
 608       mcs.cy = CW_USEDEFAULT; 
 610   DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN; 
 611   if (style & wxMINIMIZE_BOX) 
 612     msflags |= WS_MINIMIZEBOX; 
 613   if (style & wxMAXIMIZE_BOX) 
 614     msflags |= WS_MAXIMIZEBOX; 
 615   if (style & wxTHICK_FRAME) 
 616     msflags |= WS_THICKFRAME; 
 617   if (style & wxSYSTEM_MENU) 
 618     msflags |= WS_SYSMENU; 
 619   if ((style & wxMINIMIZE) || (style & wxICONIZE)) 
 620     msflags |= WS_MINIMIZE; 
 621   if (style & wxMAXIMIZE) 
 622     msflags |= WS_MAXIMIZE; 
 623   if (style & wxCAPTION) 
 624     msflags |= WS_CAPTION; 
 630   DWORD Return 
= 0; // SendMessage(GetWinHwnd(parent->GetClientWindow()), 
 631 //                             WM_MDICREATE, 0, (LONG)(LPSTR)&mcs); 
 632   m_hWnd 
= (WXHWND
)Return
; 
 635   wxAssociateWinWithHandle((HWND
) GetHWND(), this); 
 637   // VZ: what's this? an act of piracy? 
 638   //SetWindowLong(GetHwnd(), 0, (long)this); 
 640   wxModelessWindows
.Append(this); 
 644 wxMDIChildFrame::~wxMDIChildFrame() 
 649 // Set the client size (i.e. leave the calculation of borders etc. 
 651 void wxMDIChildFrame::DoSetClientSize(int width
, int height
) 
 653   HWND hWnd 
= GetHwnd(); 
 658   ::GetClientRect(hWnd, &rect); 
 661   GetWindowRect(hWnd, &rect2); 
 663   // Find the difference between the entire window (title bar and all) 
 664   // and the client area; add this to the new client size to move the 
 666   int actual_width = rect2.right - rect2.left - rect.right + width; 
 667   int actual_height = rect2.bottom - rect2.top - rect.bottom + height; 
 672     GetStatusBar()->GetSize(&sx, &sy); 
 677   point.x = rect2.left; 
 680   // If there's an MDI parent, must subtract the parent's top left corner 
 681   // since MoveWindow moves relative to the parent 
 682   wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent(); 
 683   ::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point); 
 685   MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE); 
 687   wxSizeEvent event(wxSize(width, height), m_windowId); 
 688   event.SetEventObject( this ); 
 689   GetEventHandler()->ProcessEvent(event); 
 693 void wxMDIChildFrame::DoGetPosition(int *x
, int *y
) const 
 698   GetWindowRect(GetHwnd(), &rect); 
 703   // Since we now have the absolute screen coords, 
 704   // if there's a parent we must subtract its top left corner 
 705   wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent(); 
 706   ::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point); 
 713 void wxMDIChildFrame::InternalSetMenuBar() 
 718     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); 
 720     HMENU subMenu = GetSubMenu((HMENU)parent->GetWindowMenu(), 0); 
 722     InsertWindowMenu(parent->GetClientWindow(), m_hMenu, subMenu); 
 724     parent->m_parentFrameActive = FALSE; 
 728 // --------------------------------------------------------------------------- 
 730 // --------------------------------------------------------------------------- 
 732 void wxMDIChildFrame::Maximize(bool maximize
) 
 734     wxMDIParentFrame 
*parent 
= (wxMDIParentFrame 
*)GetParent(); 
 737     if ( parent && parent->GetClientWindow() ) 
 739         ::SendMessage(GetWinHwnd(parent->GetClientWindow()), 
 740                       maximize ? WM_MDIMAXIMIZE : WM_MDIRESTORE, 
 741                       (WPARAM)GetHwnd(), 0); 
 746 void wxMDIChildFrame::Restore() 
 750     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); 
 751     if ( parent && parent->GetClientWindow() ) 
 753         ::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIRESTORE, 
 754                       (WPARAM) GetHwnd(), 0); 
 759 void wxMDIChildFrame::Activate() 
 763     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent(); 
 764     if ( parent && parent->GetClientWindow() ) 
 766         ::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIACTIVATE, 
 767                       (WPARAM) GetHwnd(), 0); 
 772 // --------------------------------------------------------------------------- 
 773 // MDI window proc and message handlers 
 774 // --------------------------------------------------------------------------- 
 776 MRESULT 
wxMDIChildFrame::OS2WindowProc(WXUINT message
, 
 781     bool processed 
= FALSE
; 
 791                 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam, 
 794                 processed = HandleCommand(id, cmd, (WXHWND)hwnd); 
 798         case WM_GETMINMAXINFO: 
 799             // let the default window proc calculate the size of MDI children 
 800             // frames because it is based on the size of the MDI client window, 
 801             // not on the values specified in wxWindow m_min/max variables 
 802             return MSWDefWindowProc(message, wParam, lParam); 
 807                 WXHWND hwndAct, hwndDeact; 
 808                 UnpackMDIActivate(wParam, lParam, &act, &hwndAct, &hwndDeact); 
 810                 processed = HandleMDIActivate(act, hwndAct, hwndDeact); 
 815             // must pass WM_MOVE to DefMDIChildProc() to recalculate MDI client 
 816             // scrollbars if necessary 
 821             // must pass WM_SIZE to DefMDIChildProc(), otherwise many weird 
 823             MSWDefWindowProc(message, wParam, lParam); 
 827             // DefMDIChildProc handles SC_{NEXT/PREV}WINDOW here, so pass it 
 828             // the message (the base class version does not) 
 829             return MSWDefWindowProc(message, wParam, lParam); 
 831         case WM_WINDOWPOSCHANGING: 
 832             processed = HandleWindowPosChanging((LPWINDOWPOS)lParam); 
 837         rc 
= wxFrame::OS2WindowProc(message
, wParam
, lParam
); 
 842 bool wxMDIChildFrame::HandleSize(int x
, int y
, WXUINT id
) 
 844     HWND hwnd 
= GetHwnd(); 
 846     if ( !hwnd 
|| hwnd 
== invalidHandle 
) 
 867         // forward WM_SIZE to status bar control 
 868 #if wxUSE_NATIVE_STATUSBAR 
 869         if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95))) 
 871             wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId()); 
 872             event.SetEventObject( m_frameStatusBar ); 
 874             ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event); 
 876 #endif // wxUSE_NATIVE_STATUSBAR 
 881         return wxWindow::HandleSize(x, y, id); 
 891 bool wxMDIChildFrame::HandleCommand(WXWORD id
, WXWORD cmd
, WXHWND hwnd
) 
 893     // In case it's e.g. a toolbar. 
 896         wxWindow 
*win 
= wxFindWinFromHandle(hwnd
); 
 898 // Fix dependent stuff           return win->OS2Command(cmd, id); 
 901     if (wxCurrentPopupMenu
) 
 903         wxMenu 
*popupMenu 
= wxCurrentPopupMenu
; 
 904         wxCurrentPopupMenu 
= NULL
; 
 905 // Fix dependent stuff        if (popupMenu->OS2Command(cmd, id)) 
 909     if (GetMenuBar() && GetMenuBar()->FindItem(id
)) 
 920 bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate
), 
 924     wxMDIParentFrame 
*parent 
= (wxMDIParentFrame 
*)GetParent(); 
 930     if ( m_hWnd 
== hwndAct 
) 
 933         parent
->m_currentChild 
= this; 
 935         HMENU child_menu 
= (HMENU
)GetWinMenu(); 
 938             parent
->m_parentFrameActive 
= FALSE
; 
 940             menuToSet 
= child_menu
; 
 943     else if ( m_hWnd 
== hwndDeact 
) 
 945         wxASSERT_MSG( parent
->m_currentChild 
== this, 
 946                       wxT("can't deactivate MDI child which wasn't active!") ); 
 949         parent
->m_currentChild 
= NULL
; 
 951         HMENU parent_menu 
= (HMENU
)parent
->GetWinMenu(); 
 954             parent
->m_parentFrameActive 
= TRUE
; 
 956             menuToSet 
= parent_menu
; 
 961         // we have nothing to with it 
 967         HMENU subMenu 
= 0; // TODO: GetSubMenu((HMENU) parent->GetWindowMenu(), 0); 
 969         MDISetMenu(parent
->GetClientWindow(), menuToSet
, subMenu
); 
 972     wxActivateEvent 
event(wxEVT_ACTIVATE
, activated
, m_windowId
); 
 973     event
.SetEventObject( this ); 
 975     return GetEventHandler()->ProcessEvent(event
); 
 978 bool wxMDIChildFrame::HandleWindowPosChanging(void *pos
) 
 980 //    WINDOWPOS *lpPos = (WINDOWPOS *)pos; 
 984 // --------------------------------------------------------------------------- 
 985 // MDI specific message translation/preprocessing 
 986 // --------------------------------------------------------------------------- 
 988 MRESULT 
wxMDIChildFrame::OS2DefWindowProc(WXUINT message
, WXWPARAM wParam
, WXLPARAM lParam
) 
 992     return DefMDIChildProc(GetHwnd(), 
 993                            (UINT)message, (WPARAM)wParam, (LPARAM)lParam); 
 998 bool wxMDIChildFrame::OS2TranslateMessage(WXMSG
* msg
) 
1001     return m_acceleratorTable
.Translate(GetParent()->GetHWND(), msg
); 
1004 #endif  //wxUSE_ACCEL 
1008 // --------------------------------------------------------------------------- 
1010 // --------------------------------------------------------------------------- 
1012 void wxMDIChildFrame::OS2DestroyWindow() 
1014 // get wxWindow up to date    OS2DetachWindowMenu(); 
1015     invalidHandle 
= GetHwnd(); 
1017     wxMDIParentFrame 
*parent 
= (wxMDIParentFrame 
*)GetParent(); 
1019     // Must make sure this handle is invalidated (set to NULL) since all sorts 
1020     // of things could happen after the child client is destroyed, but before 
1021     // the wxFrame is destroyed. 
1023     HWND oldHandle 
= (HWND
)GetHWND(); 
1024 // TODO:    SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIDESTROY, 
1025 //                (WPARAM)oldHandle, 0); 
1030 // TODO:        ::DestroyMenu((HMENU) m_hMenu); 
1036 // Change the client window's extended style so we don't get a client edge 
1037 // style when a child is maximised (a double border looks silly.) 
1038 bool wxMDIChildFrame::ResetWindowStyle(void *vrect
) 
1043 // =========================================================================== 
1044 // wxMDIClientWindow: the window of predefined (by Windows) class which 
1045 // contains the child frames 
1046 // =========================================================================== 
1048 bool wxMDIClientWindow::CreateClient(wxMDIParentFrame 
*parent
, long style
) 
1050     m_backgroundColour 
= wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE
); 
1054     CLIENTCREATESTRUCT ccs; 
1055     m_windowStyle = style; 
1058     ccs.hWindowMenu = (HMENU)parent->GetWindowMenu(); 
1059     ccs.idFirstChild = wxFIRST_MDI_CHILD; 
1061     DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN; 
1062     if ( style & wxHSCROLL ) 
1063         msStyle |= WS_HSCROLL; 
1064     if ( style & wxVSCROLL ) 
1065         msStyle |= WS_VSCROLL; 
1067 #if defined(__WIN95__) 
1068     DWORD exStyle = WS_EX_CLIENTEDGE; 
1074     m_hWnd = (WXHWND)::CreateWindowEx 
1084                         (LPSTR)(LPCLIENTCREATESTRUCT)&ccs); 
1087         wxLogLastError("CreateWindowEx(MDI client)"); 
1092     SubclassWin(m_hWnd); 
1098 // Explicitly call default scroll behaviour 
1099 void wxMDIClientWindow::OnScroll(wxScrollEvent
& event
) 
1101     // Note: for client windows, the scroll position is not set in 
1102     // WM_HSCROLL, WM_VSCROLL, so we can't easily determine what 
1103     // scroll position we're at. 
1104     // This makes it hard to paint patterns or bitmaps in the background, 
1105     // and have the client area scrollable as well. 
1107     if ( event
.GetOrientation() == wxHORIZONTAL 
) 
1108         m_scrollX 
= event
.GetPosition(); // Always returns zero! 
1110         m_scrollY 
= event
.GetPosition(); // Always returns zero! 
1115 // --------------------------------------------------------------------------- 
1116 // non member functions 
1117 // --------------------------------------------------------------------------- 
1119 static void MDISetMenu(wxWindow 
*win
, HMENU hmenuFrame
, HMENU hmenuWindow
) 
1123     ::SendMessage(GetWinHwnd(win), WM_MDISETMENU, 
1124                   (WPARAM)hmenuFrame, (LPARAM)hmenuWindow); 
1125     // update menu bar of the parent window 
1126     wxWindow *parent = win->GetParent(); 
1127     wxCHECK_RET( parent, wxT("MDI client without parent frame? weird...") ); 
1129     ::DrawMenuBar(GetWinHwnd(parent)); 
1133 static void InsertWindowMenu(wxWindow 
*win
, WXHMENU menu
, HMENU subMenu
) 
1136     // Try to insert Window menu in front of Help, otherwise append it. 
1137     HMENU hmenu = (HMENU)menu; 
1138     int N = GetMenuItemCount(hmenu); 
1139     bool success = FALSE; 
1140     for ( int i = 0; i < N; i++ ) 
1143         int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION); 
1146             wxLogLastError(wxT("GetMenuString")); 
1151         if ( wxStripMenuCodes(wxString(buf)).IsSameAs(wxT("Help")) ) 
1154             ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, 
1155                          (UINT)subMenu, wxT("&Window")); 
1162         ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, wxT("&Window")); 
1164     MDISetMenu(win, hmenu, subMenu); 
1168 static void UnpackMDIActivate(WXWPARAM wParam
, WXLPARAM lParam
, 
1169                               WXWORD 
*activate
, WXHWND 
*hwndAct
, WXHWND 
*hwndDeact
) 
1172     *hwndAct 
= (WXHWND
)lParam
; 
1173     *hwndDeact 
= (WXHWND
)wParam
;