]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/mdi.cpp
wxListCtrl::InsertItem() returned wrong index.
[wxWidgets.git] / src / msw / mdi.cpp
index 4a024cd1a84593908b3cacd5229d885880c133fd..6d9792c7408cdeacd3f250ab7f6494a26828a61e 100644 (file)
 extern wxWindowList wxModelessWindows;      // from dialog.cpp
 extern wxMenu *wxCurrentPopupMenu;
 
 extern wxWindowList wxModelessWindows;      // from dialog.cpp
 extern wxMenu *wxCurrentPopupMenu;
 
-extern const wxChar *wxMDIFrameClassName;
+extern const wxChar *wxMDIFrameClassName;   // from app.cpp
 extern const wxChar *wxMDIChildFrameClassName;
 extern const wxChar *wxMDIChildFrameClassName;
+extern const wxChar *wxMDIChildFrameClassNameNoRedraw;
+
 extern wxWindow *wxWndHook;                 // from window.cpp
 
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
 extern wxWindow *wxWndHook;                 // from window.cpp
 
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
+extern void wxRemoveHandleAssociation(wxWindow *win);
 
 static HWND invalidHandle = 0;
 
 
 static HWND invalidHandle = 0;
 
@@ -131,6 +134,10 @@ BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
     EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
     EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
 END_EVENT_TABLE()
 
+BEGIN_EVENT_TABLE(wxMDIChildFrame, wxFrame)
+    EVT_IDLE(wxMDIChildFrame::OnIdle)
+END_EVENT_TABLE()
+
 BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
     EVT_SCROLL(wxMDIClientWindow::OnScroll)
 END_EVENT_TABLE()
 BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
     EVT_SCROLL(wxMDIClientWindow::OnScroll)
 END_EVENT_TABLE()
@@ -216,11 +223,22 @@ bool wxMDIParentFrame::Create(wxWindow *parent,
   if (style & wxCLIP_CHILDREN)
     msflags |= WS_CLIPCHILDREN;
 
   if (style & wxCLIP_CHILDREN)
     msflags |= WS_CLIPCHILDREN;
 
-  wxWindow::MSWCreate(m_windowId, parent, wxMDIFrameClassName, this, title, x, y, width, height,
-         msflags);
+  if ( !wxWindow::MSWCreate(m_windowId,
+                            parent,
+                            wxMDIFrameClassName,
+                            this,
+                            title,
+                            x, y, width, height,
+                            msflags) )
+  {
+      return FALSE;
+  }
 
   wxModelessWindows.Append(this);
 
 
   wxModelessWindows.Append(this);
 
+  // unlike (almost?) all other windows, frames are created hidden
+  m_isShown = FALSE;
+
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -229,6 +247,7 @@ wxMDIParentFrame::~wxMDIParentFrame()
     DestroyChildren();
     // already delete by DestroyChildren()
     m_frameToolBar = NULL;
     DestroyChildren();
     // already delete by DestroyChildren()
     m_frameToolBar = NULL;
+    m_frameStatusBar = NULL;
 
     // ::DestroyMenu((HMENU)m_windowMenu);
     if (m_windowMenu)
 
     // ::DestroyMenu((HMENU)m_windowMenu);
     if (m_windowMenu)
@@ -557,8 +576,7 @@ bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
     {
         // this shouldn't happen because it means that our messages are being
         // lost (they're not sent to the parent frame nor to the children)
     {
         // this shouldn't happen because it means that our messages are being
         // lost (they're not sent to the parent frame nor to the children)
-        wxFAIL_MSG(wxT("MDI parent frame is not active, "
-                      "yet there is no active MDI child?"));
+        wxFAIL_MSG(wxT("MDI parent frame is not active, yet there is no active MDI child?"));
     }
 
     return FALSE;
     }
 
     return FALSE;
@@ -581,17 +599,20 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg)
 {
     MSG *pMsg = (MSG *)msg;
 
 {
     MSG *pMsg = (MSG *)msg;
 
+    // first let the current child get it
     if ( m_currentChild && m_currentChild->GetHWND() &&
          m_currentChild->MSWTranslateMessage(msg) )
     {
         return TRUE;
     }
 
     if ( m_currentChild && m_currentChild->GetHWND() &&
          m_currentChild->MSWTranslateMessage(msg) )
     {
         return TRUE;
     }
 
-    if ( m_acceleratorTable.Translate(this, msg) )
+    // then try out accel table (will also check the menu accels)
+    if ( wxFrame::MSWTranslateMessage(msg) )
     {
         return TRUE;
     }
 
     {
         return TRUE;
     }
 
+    // finally, check for MDI specific built in accel keys
     if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN )
     {
         if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg))
     if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN )
     {
         if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg))
@@ -605,8 +626,9 @@ bool wxMDIParentFrame::MSWTranslateMessage(WXMSG* msg)
 // wxMDIChildFrame
 // ===========================================================================
 
 // wxMDIChildFrame
 // ===========================================================================
 
-wxMDIChildFrame::wxMDIChildFrame()
+void wxMDIChildFrame::Init()
 {
 {
+    m_needsResize = TRUE;
 }
 
 bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 }
 
 bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
@@ -641,7 +663,9 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 
   MDICREATESTRUCT mcs;
 
 
   MDICREATESTRUCT mcs;
 
-  mcs.szClass = wxMDIChildFrameClassName;
+  mcs.szClass = style & wxNO_FULL_REPAINT_ON_RESIZE
+                    ? wxMDIChildFrameClassNameNoRedraw
+                    : wxMDIChildFrameClassName;
   mcs.szTitle = title;
   mcs.hOwner = wxGetInstance();
   if (x > -1)
   mcs.szTitle = title;
   mcs.hOwner = wxGetInstance();
   if (x > -1)
@@ -684,12 +708,8 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 
   mcs.lParam = 0;
 
 
   mcs.lParam = 0;
 
-  DWORD Return = SendMessage(GetWinHwnd(parent->GetClientWindow()),
-                             WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
-
-  //handle = (HWND)LOWORD(Return);
-  // Must be the DWORRD for WIN32. And in 16 bits, HIWORD=0 (says Microsoft)
-  m_hWnd = (WXHWND)Return;
+  m_hWnd = (WXHWND)::SendMessage(GetWinHwnd(parent->GetClientWindow()),
+                                 WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
 
   wxWndHook = NULL;
   wxAssociateWinWithHandle((HWND) GetHWND(), this);
 
   wxWndHook = NULL;
   wxAssociateWinWithHandle((HWND) GetHWND(), this);
@@ -703,6 +723,12 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
 
 wxMDIChildFrame::~wxMDIChildFrame()
 {
 
 wxMDIChildFrame::~wxMDIChildFrame()
 {
+    DestroyChildren();
+
+    // already delete by DestroyChildren()
+    m_frameToolBar = NULL;
+    m_frameStatusBar = NULL;
+
     MSWDestroyWindow();
 }
 
     MSWDestroyWindow();
 }
 
@@ -899,15 +925,17 @@ bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
             return TRUE;
     }
 
             return TRUE;
     }
 
+    bool processed;
     if (GetMenuBar() && GetMenuBar()->FindItem(id))
     {
     if (GetMenuBar() && GetMenuBar()->FindItem(id))
     {
-        ProcessCommand(id);
-        return TRUE;
+        processed = ProcessCommand(id);
     }
     else
     }
     else
-        return FALSE;
+    {
+        processed = FALSE;
+    }
 
 
-    return TRUE;
+    return processed;
 }
 
 bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
 }
 
 bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
@@ -1042,6 +1070,7 @@ void wxMDIChildFrame::MSWDestroyWindow()
         ::DestroyMenu((HMENU) m_hMenu);
         m_hMenu = 0;
     }
         ::DestroyMenu((HMENU) m_hMenu);
         m_hMenu = 0;
     }
+    wxRemoveHandleAssociation(this);
     m_hWnd = 0;
 }
 
     m_hWnd = 0;
 }
 
@@ -1127,7 +1156,7 @@ bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
                         (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
     if ( !m_hWnd )
     {
                         (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
     if ( !m_hWnd )
     {
-        wxLogLastError("CreateWindowEx(MDI client)");
+        wxLogLastError(wxT("CreateWindowEx(MDI client)"));
 
         return FALSE;
     }
 
         return FALSE;
     }
@@ -1155,6 +1184,54 @@ void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
     event.Skip();
 }
 
     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.
+
+    wxPoint oldPos = GetPosition();
+
+    wxWindow::DoSetSize(x, y, width, height, sizeFlags);
+
+    wxPoint newPos = GetPosition();
+
+    if ((newPos.x != oldPos.x) || (newPos.y != oldPos.y))
+    {
+        if (GetParent())
+        {
+            wxNode* node = GetParent()->GetChildren().First();
+            while (node)
+            {
+                wxWindow* child = (wxWindow*) node->Data();
+                if (child->IsKindOf(CLASSINFO(wxMDIChildFrame)))
+                {
+                    HWND hWnd = (HWND) child->GetHWND();
+                   ::RedrawWindow(hWnd, NULL, NULL, RDW_FRAME|RDW_ALLCHILDREN|RDW_INVALIDATE );
+                }
+                node = node->Next();
+            }
+        }
+    }
+}
+
+void wxMDIChildFrame::OnIdle(wxIdleEvent& event)
+{
+    // 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();
+}
+
 // ---------------------------------------------------------------------------
 // non member functions
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // non member functions
 // ---------------------------------------------------------------------------
@@ -1163,10 +1240,11 @@ static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
 {
     ::SendMessage(GetWinHwnd(win), WM_MDISETMENU,
 #ifdef __WIN32__
 {
     ::SendMessage(GetWinHwnd(win), WM_MDISETMENU,
 #ifdef __WIN32__
-                  (WPARAM)hmenuFrame, (LPARAM)hmenuWindow);
+                  (WPARAM)hmenuFrame, (LPARAM)hmenuWindow
 #else
 #else
-                  0, MAKELPARAM(hmenuFrame, hmenuWindow));
+                  0, MAKELPARAM(hmenuFrame, hmenuWindow)
 #endif
 #endif
+                 );
 
     // update menu bar of the parent window
     wxWindow *parent = win->GetParent();
 
     // update menu bar of the parent window
     wxWindow *parent = win->GetParent();
@@ -1195,18 +1273,18 @@ static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
             continue;
         }
 
             continue;
         }
 
-        if ( wxStripMenuCodes(wxString(buf)).IsSameAs(wxT("Help")) )
+        if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Help")) )
         {
             success = TRUE;
             ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
         {
             success = TRUE;
             ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
-                         (UINT)subMenu, wxT("&Window"));
+                         (UINT)subMenu, _("&Window"));
             break;
         }
     }
 
     if ( !success )
     {
             break;
         }
     }
 
     if ( !success )
     {
-        ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, wxT("&Window"));
+        ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, _("&Window"));
     }
     }
 
     }
     }
 
@@ -1230,7 +1308,7 @@ static void RemoveWindowMenu(wxWindow *win, WXHMENU menu)
             continue;
         }
 
             continue;
         }
 
-        if ( wxStripMenuCodes(wxString(buf)).IsSameAs(wxT("Window")) )
+        if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Window")) )
         {
             success = TRUE;
             ::RemoveMenu(hmenu, i, MF_BYPOSITION);
         {
             success = TRUE;
             ::RemoveMenu(hmenu, i, MF_BYPOSITION);