]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/mdi.cpp
wxFD_* constants without 2.6 compatibility (heavily extended and modified patch ...
[wxWidgets.git] / src / msw / mdi.cpp
index d3ed9137f9cdbe10e8e8e0971115c53df5e48922..5b7dd5e75ec830e8e32fb01850afb2a84fc3c363 100644 (file)
 // headers
 // ---------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "mdi.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -31,7 +27,6 @@
 #if wxUSE_MDI && !defined(__WXUNIVERSAL__)
 
 #ifndef WX_PRECOMP
-    #include "wx/setup.h"
     #include "wx/frame.h"
     #include "wx/menu.h"
     #include "wx/app.h"
@@ -45,6 +40,7 @@
     #include "wx/log.h"
 #endif
 
+#include "wx/stockitem.h"
 #include "wx/mdi.h"
 #include "wx/msw/private.h"
 
@@ -67,16 +63,12 @@ extern wxMenu *wxCurrentPopupMenu;
 extern const wxChar *wxMDIFrameClassName;   // from app.cpp
 extern const wxChar *wxMDIChildFrameClassName;
 extern const wxChar *wxMDIChildFrameClassNameNoRedraw;
-extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
 extern void wxRemoveHandleAssociation(wxWindow *win);
 
-static HWND invalidHandle = 0;
-
 // ---------------------------------------------------------------------------
 // constants
 // ---------------------------------------------------------------------------
 
-static const int IDM_WINDOWTILE  = 4001;
 static const int IDM_WINDOWTILEHOR  = 4001;
 static const int IDM_WINDOWCASCADE = 4002;
 static const int IDM_WINDOWICONS = 4003;
@@ -88,10 +80,6 @@ static const int IDM_WINDOWPREV = 4006;
 static const int wxFIRST_MDI_CHILD = 4100;
 static const int wxLAST_MDI_CHILD = 4600;
 
-// Status border dimensions
-static const int wxTHICK_LINE_BORDER = 3;
-static const int wxTHICK_LINE_WIDTH  = 1;
-
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
@@ -138,6 +126,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
 
 BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
     EVT_SIZE(wxMDIParentFrame::OnSize)
+    EVT_ICONIZE(wxMDIParentFrame::OnIconized)
     EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
@@ -222,6 +211,8 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
       return false;
   }
 
+  SetOwnBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
+
   // unlike (almost?) all other windows, frames are created hidden
   m_isShown = false;
 
@@ -318,7 +309,7 @@ void wxMDIParentFrame::DoMenuUpdates(wxMenu* menu)
             {
                 int nCount = bar->GetMenuCount();
                 for (int n = 0; n < nCount; n++)
-                bar->GetMenu(n)->UpdateUI(source);
+                    bar->GetMenu(n)->UpdateUI(source);
             }
         }
     }
@@ -328,7 +319,7 @@ void wxMDIParentFrame::DoMenuUpdates(wxMenu* menu)
     }
 }
 
-void wxMDIParentFrame::OnSize(wxSizeEvent&)
+void wxMDIParentFrame::UpdateClientSize()
 {
     if ( GetClientWindow() )
     {
@@ -339,6 +330,23 @@ void wxMDIParentFrame::OnSize(wxSizeEvent&)
     }
 }
 
+void wxMDIParentFrame::OnSize(wxSizeEvent& WXUNUSED(event))
+{
+    UpdateClientSize();
+
+    // do not call event.Skip() here, it somehow messes up MDI client window
+}
+
+void wxMDIParentFrame::OnIconized(wxIconizeEvent& event)
+{
+    event.Skip();
+
+    if ( !event.Iconized() )
+    {
+        UpdateClientSize();
+    }
+}
+
 // Returns the active MDI child window
 wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
 {
@@ -535,6 +543,14 @@ bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
             return win->MSWCommand(cmd, id);
     }
 
+    if (wxCurrentPopupMenu)
+    {
+        wxMenu *popupMenu = wxCurrentPopupMenu;
+        wxCurrentPopupMenu = NULL;
+        if (popupMenu->MSWCommand(cmd, id))
+            return true;
+    }
+
     // is it one of standard MDI commands?
     WXWPARAM wParam = 0;
     WXLPARAM lParam = 0;
@@ -733,7 +749,7 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
     msflags |= WS_MINIMIZEBOX;
   if (style & wxMAXIMIZE_BOX)
     msflags |= WS_MAXIMIZEBOX;
-  if (style & wxTHICK_FRAME)
+  if (style & wxRESIZE_BORDER)
     msflags |= WS_THICKFRAME;
   if (style & wxSYSTEM_MENU)
     msflags |= WS_SYSMENU;
@@ -753,7 +769,13 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
   m_hWnd = (WXHWND)::SendMessage(GetWinHwnd(parent->GetClientWindow()),
                                  WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
 
-  wxAssociateWinWithHandle((HWND) GetHWND(), this);
+  if ( !m_hWnd )
+  {
+      wxLogLastError(_T("WM_MDICREATE"));
+      return false;
+  }
+
+  SubclassWin(m_hWnd);
 
   return true;
 }
@@ -779,7 +801,22 @@ wxMDIChildFrame::~wxMDIChildFrame()
 bool wxMDIChildFrame::Show(bool show)
 {
     m_needsInitialShow = false;
-    return wxFrame::Show(show);
+
+    if (!wxFrame::Show(show))
+        return false;
+
+    // KH: Without this call, new MDI children do not become active.
+    // This was added here after the same BringWindowToTop call was
+    // removed from wxTopLevelWindow::Show (November 2005)
+    if ( show )
+        ::BringWindowToTop(GetHwnd());
+
+    // we need to refresh the MDI frame window menu to include (or exclude if
+    // we've been hidden) this frame
+    wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
+    MDISetMenu(parent->GetClientWindow(), NULL, NULL);
+
+    return true;
 }
 
 // Set the client size (i.e. leave the calculation of borders etc.
@@ -855,6 +892,12 @@ void wxMDIChildFrame::InternalSetMenuBar()
     parent->m_parentFrameActive = false;
 }
 
+void wxMDIChildFrame::DetachMenuBar()
+{
+    RemoveWindowMenu(NULL, m_hMenu);
+    wxFrame::DetachMenuBar();
+}
+
 WXHICON wxMDIChildFrame::GetDefaultIcon() const
 {
     // we don't have any standard icons (any more)
@@ -1058,7 +1101,7 @@ bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
 bool wxMDIChildFrame::HandleWindowPosChanging(void *pos)
 {
     WINDOWPOS *lpPos = (WINDOWPOS *)pos;
-#if defined(__WIN95__)
+
     if (!(lpPos->flags & SWP_NOSIZE))
     {
         RECT rectClient;
@@ -1072,15 +1115,7 @@ bool wxMDIChildFrame::HandleWindowPosChanging(void *pos)
             lpPos->cx = rectClient.right - rectClient.left;
             lpPos->cy = rectClient.bottom - rectClient.top;
         }
-#if wxUSE_TOOLBAR
-        wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
-        if (pFrameWnd && pFrameWnd->GetToolBar() && pFrameWnd->GetToolBar()->IsShown())
-        {
-            pFrameWnd->GetToolBar()->Refresh();
-        }
-#endif
     }
-#endif // Win95
 
     return false;
 }
@@ -1098,14 +1133,14 @@ bool wxMDIChildFrame::HandleGetMinMaxInfo(void *mmInfo)
         minHeight = GetMinHeight();
 
     // but allow GetSizeHints() to set the min size
-    if ( minWidth != -1 )
+    if ( minWidth != wxDefaultCoord )
     {
         info->ptMinTrackSize.x = minWidth;
 
         processed = true;
     }
 
-    if ( minHeight != -1 )
+    if ( minHeight != wxDefaultCoord )
     {
         info->ptMinTrackSize.y = minHeight;
 
@@ -1127,7 +1162,9 @@ WXLRESULT wxMDIChildFrame::MSWDefWindowProc(WXUINT message, WXWPARAM wParam, WXL
 
 bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg)
 {
-    return wxFrame::MSWTranslateMessage(msg);
+    // we must pass the parent frame to ::TranslateAccelerator(), otherwise it
+    // doesn't do its job correctly for MDI child menus
+    return MSWDoTranslateMessage((wxMDIChildFrame *)GetParent(), msg);
 }
 
 // ---------------------------------------------------------------------------
@@ -1136,8 +1173,6 @@ bool wxMDIChildFrame::MSWTranslateMessage(WXMSG* msg)
 
 void wxMDIChildFrame::MSWDestroyWindow()
 {
-    invalidHandle = GetHwnd();
-
     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
 
     // Must make sure this handle is invalidated (set to NULL) since all sorts
@@ -1151,8 +1186,6 @@ void wxMDIChildFrame::MSWDestroyWindow()
     if (parent->GetActiveChild() == (wxMDIChildFrame*) NULL)
         ResetWindowStyle((void*) NULL);
 
-    invalidHandle = 0;
-
     if (m_hMenu)
     {
         ::DestroyMenu((HMENU) m_hMenu);
@@ -1166,10 +1199,10 @@ void wxMDIChildFrame::MSWDestroyWindow()
 // style when a child is maximised (a double border looks silly.)
 bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
 {
-#if defined(__WIN95__)
     RECT *rect = (RECT *)vrect;
     wxMDIParentFrame* pFrameWnd = (wxMDIParentFrame *)GetParent();
     wxMDIChildFrame* pChild = pFrameWnd->GetActiveChild();
+
     if (!pChild || (pChild == this))
     {
         HWND hwndClient = GetWinHwnd(pFrameWnd->GetClientWindow());
@@ -1201,7 +1234,6 @@ bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
             return true;
         }
     }
-#endif // Win95
 
     return false;
 }
@@ -1230,11 +1262,7 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
     if ( style & wxVSCROLL )
         msStyle |= WS_VSCROLL;
 
-#if defined(__WIN95__)
     DWORD exStyle = WS_EX_CLIENTEDGE;
-#else
-    DWORD exStyle = 0;
-#endif
 
     wxWindowCreationHook hook(this);
     m_hWnd = (WXHWND)::CreateWindowEx
@@ -1284,11 +1312,11 @@ void wxMDIClientWindow::DoSetSize(int x, int y, int width, int height, int sizeF
     // (see OGL studio sample). So check if the position is changed and if so,
     // redraw the MDI child frames.
 
-    wxPoint oldPos = GetPosition();
+    const wxPoint oldPos = GetPosition();
 
-    wxWindow::DoSetSize(x, y, width, height, sizeFlags);
+    wxWindow::DoSetSize(x, y, width, height, sizeFlags | wxSIZE_FORCE);
 
-    wxPoint newPos = GetPosition();
+    const wxPoint newPos = GetPosition();
 
     if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y))
     {
@@ -1345,13 +1373,16 @@ void wxMDIChildFrame::OnIdle(wxIdleEvent& event)
 
 static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
 {
-    ::SendMessage(GetWinHwnd(win), WM_MDISETMENU,
-#ifdef __WIN32__
-                  (WPARAM)hmenuFrame, (LPARAM)hmenuWindow
-#else
-                  0, MAKELPARAM(hmenuFrame, hmenuWindow)
-#endif
-                 );
+    if ( hmenuFrame || hmenuWindow )
+    {
+        if ( !::SendMessage(GetWinHwnd(win),
+                            WM_MDISETMENU,
+                            (WPARAM)hmenuFrame,
+                            (LPARAM)hmenuWindow) )
+        {
+            wxLogLastError(_T("SendMessage(WM_MDISETMENU)"));
+        }
+    }
 
     // update menu bar of the parent window
     wxWindow *parent = win->GetParent();
@@ -1382,7 +1413,8 @@ static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
                 continue;
             }
 
-            if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Help")) )
+            wxString strBuf(buf);
+            if ( wxStripMenuCodes(strBuf) == wxGetStockLabel(wxID_HELP,false) )
             {
                 success = true;
                 ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
@@ -1451,4 +1483,3 @@ static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
 }
 
 #endif // wxUSE_MDI && !defined(__WXUNIVERSAL__)
-