+ event.Skip();
+}
+
+void wxMDIClientWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+ // Try to fix a problem whereby if you show an MDI child frame, then reposition the
+ // client area, you can end up with a non-refreshed portion in the client window
+ // (see OGL studio sample). So check if the position is changed and if so,
+ // redraw the MDI child frames.
+
+ const wxPoint oldPos = GetPosition();
+
+ wxWindow::DoSetSize(x, y, width, height, sizeFlags | wxSIZE_FORCE);
+
+ const wxPoint newPos = GetPosition();
+
+ if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y))
+ {
+ if (GetParent())
+ {
+ wxWindowList::compatibility_iterator node = GetParent()->GetChildren().GetFirst();
+ while (node)
+ {
+ wxWindow *child = node->GetData();
+ if (child->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+ {
+ ::RedrawWindow(GetHwndOf(child),
+ NULL,
+ NULL,
+ RDW_FRAME |
+ RDW_ALLCHILDREN |
+ RDW_INVALIDATE);
+ }
+ node = node->GetNext();
+ }
+ }
+ }
+}
+
+void wxMDIChildFrame::OnIdle(wxIdleEvent& event)
+{
+ // wxMSW prior to 2.5.3 created MDI child frames as visible, which resulted
+ // in flicker e.g. when the frame contained controls with non-trivial
+ // layout. Since 2.5.3, the frame is created hidden as all other top level
+ // windows. In order to maintain backward compatibility, the frame is shown
+ // in OnIdle, unless Show(false) was called by the programmer before.
+ if ( m_needsInitialShow )
+ {
+ Show(true);
+ }
+
+ // MDI child frames get their WM_SIZE when they're constructed but at this
+ // moment they don't have any children yet so all child windows will be
+ // positioned incorrectly when they are added later - to fix this, we
+ // generate an artificial size event here
+ if ( m_needsResize )
+ {
+ m_needsResize = false; // avoid any possibility of recursion
+
+ SendSizeEvent();
+ }
+
+ event.Skip();
+}
+
+// ---------------------------------------------------------------------------
+// private helper functions
+// ---------------------------------------------------------------------------
+
+namespace
+{
+
+void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
+{
+ if ( hmenuFrame || hmenuWindow )
+ {
+ if ( !::SendMessage(GetWinHwnd(win),
+ WM_MDISETMENU,
+ (WPARAM)hmenuFrame,
+ (LPARAM)hmenuWindow) )
+ {
+ DWORD err = ::GetLastError();
+ if ( err )
+ {
+ wxLogApiError(wxT("SendMessage(WM_MDISETMENU)"), err);
+ }
+ }
+ }
+
+ // update menu bar of the parent window
+ wxWindow *parent = win->GetParent();
+ wxCHECK_RET( parent, wxT("MDI client without parent frame? weird...") );
+
+ ::SendMessage(GetWinHwnd(win), WM_MDIREFRESHMENU, 0, 0L);
+
+ ::DrawMenuBar(GetWinHwnd(parent));
+}
+
+void MDIInsertWindowMenu(wxWindow *win, WXHMENU hMenu, HMENU menuWin)
+{
+ HMENU hmenu = (HMENU)hMenu;
+
+ if ( menuWin )
+ {
+ // Try to insert Window menu in front of Help, otherwise append it.
+ int N = GetMenuItemCount(hmenu);
+ bool inserted = false;
+ for ( int i = 0; i < N; i++ )
+ {
+ wxChar buf[256];
+ if ( !::GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION) )
+ {
+ wxLogLastError(wxT("GetMenuString"));
+
+ continue;
+ }
+
+ const wxString label = wxStripMenuCodes(buf);
+ if ( label == wxGetStockLabel(wxID_HELP, wxSTOCK_NOFLAGS) )
+ {
+ inserted = true;
+ ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
+ (UINT_PTR)menuWin,
+ wxString(wxGetTranslation(WINDOW_MENU_LABEL)).wx_str());
+ break;
+ }
+ }
+
+ if ( !inserted )
+ {
+ ::AppendMenu(hmenu, MF_POPUP,
+ (UINT_PTR)menuWin,
+ wxString(wxGetTranslation(WINDOW_MENU_LABEL)).wx_str());
+ }
+ }
+
+ MDISetMenu(win, hmenu, menuWin);
+}
+
+void MDIRemoveWindowMenu(wxWindow *win, WXHMENU hMenu)
+{
+ HMENU hmenu = (HMENU)hMenu;
+
+ if ( hmenu )
+ {
+ wxChar buf[1024];
+
+ int N = ::GetMenuItemCount(hmenu);
+ for ( int i = 0; i < N; i++ )
+ {
+ if ( !::GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION) )
+ {
+ // Ignore successful read of menu string with length 0 which
+ // occurs, for example, for a maximized MDI child system menu
+ if ( ::GetLastError() != 0 )
+ {
+ wxLogLastError(wxT("GetMenuString"));
+ }
+
+ continue;
+ }
+
+ if ( wxStrcmp(buf, wxGetTranslation(WINDOW_MENU_LABEL)) == 0 )
+ {
+ if ( !::RemoveMenu(hmenu, i, MF_BYPOSITION) )
+ {
+ wxLogLastError(wxT("RemoveMenu"));
+ }
+
+ break;
+ }
+ }
+ }
+
+ if ( win )
+ {
+ // we don't change the windows menu, but we update the main one
+ MDISetMenu(win, hmenu, NULL);
+ }