]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/toplevel.cpp
fixing infinite recursion
[wxWidgets.git] / src / msw / toplevel.cpp
index 5fb5fd504feabaccb006a71bd0dba361ab2b869e..a61f3336a711f4a64cb694800732c0f11cc112bf 100644 (file)
@@ -225,7 +225,7 @@ WXDWORD wxTopLevelWindowMSW::MSWGetStyle(long style, WXDWORD *exflags) const
         msflags |= WS_MAXIMIZE;
 
     // Keep this here because it saves recoding this function in wxTinyFrame
-    if ( style & (wxTINY_CAPTION_VERT | wxTINY_CAPTION_HORIZ) )
+    if ( style & wxTINY_CAPTION )
         msflags |= WS_CAPTION;
 
     if ( exflags )
@@ -375,8 +375,7 @@ bool wxTopLevelWindowMSW::CreateDialog(const void *dlgTemplate,
 #else // !__WXMICROWIN__
     // static cast is valid as we're only ever called for dialogs
     wxWindow * const
-        parent = static_cast<wxDialog *>(this)->
-                    GetParentForModalDialog(GetParent());
+        parent = static_cast<wxDialog *>(this)->GetParentForModalDialog();
 
     m_hWnd = (WXHWND)::CreateDialogIndirect
                        (
@@ -482,12 +481,15 @@ bool wxTopLevelWindowMSW::Create(wxWindow *parent,
         sizeReal.SetDefaults(GetDefaultSize());
     }
 
+    // notice that we should append this window to wxTopLevelWindows list
+    // before calling CreateBase() as it behaves differently for TLW and
+    // non-TLW windows
+    wxTopLevelWindows.Append(this);
+
     bool ret = CreateBase(parent, id, pos, sizeReal, style, name);
     if ( !ret )
         return false;
 
-    wxTopLevelWindows.Append(this);
-
     if ( parent )
         parent->AddChild(this);
 
@@ -613,7 +615,7 @@ void wxTopLevelWindowMSW::ShowWithoutActivating()
 {
     if ( !wxWindowBase::Show(true) )
         return;
-        
+
     DoShowWindow(SW_SHOWNA);
 }
 
@@ -660,6 +662,16 @@ bool wxTopLevelWindowMSW::Show(bool show)
         nShowCmd = SW_HIDE;
     }
 
+    // we only set pending size if we're maximized before being shown, now that
+    // we're shown we don't need it any more (it is reset in size event handler
+    // for child windows but we have to do it ourselves for this parent window)
+    //
+    // make sure to reset it before actually showing the window as this will
+    // generate WM_SIZE events and we want to use the correct client size from
+    // them, not the size returned by WM_NCCALCSIZE in DoGetClientSize() which
+    // turns out to be wrong for maximized windows (see #11762)
+    m_pendingSize = wxDefaultSize;
+
     DoShowWindow(nShowCmd);
 
 #if defined(__WXWINCE__) && (_WIN32_WCE >= 400 && !defined(__POCKETPC__) && !defined(__SMARTPHONE__))
@@ -669,11 +681,6 @@ bool wxTopLevelWindowMSW::Show(bool show)
         frame->GetMenuBar()->AddAdornments(GetWindowStyleFlag());
 #endif
 
-    // we only set pending size if we're maximized before being shown, now that
-    // we're shown we don't need it any more (it is reset in size event handler
-    // for child windows but we have to do it ourselves for this parent window)
-    m_pendingSize = wxDefaultSize;
-
     return true;
 }
 
@@ -842,6 +849,72 @@ void wxTopLevelWindowMSW::DoGetSize(int *width, int *height) const
 
 #endif // __WXWINCE__
 
+void
+wxTopLevelWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
+                                              const wxSize& size,
+                                              int& x, int& y,
+                                              int& w, int& h) const
+{
+    // let the system position the window if no explicit position was specified
+    if ( pos.x == wxDefaultCoord )
+    {
+        // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we
+        // can just as well set it to CW_USEDEFAULT as well
+        x =
+        y = CW_USEDEFAULT;
+    }
+    else
+    {
+        // OTOH, if x is not set to CW_USEDEFAULT, y shouldn't be set to it
+        // neither because it is not handled as a special value by Windows then
+        // and so we have to choose some default value for it, even if a
+        // completely arbitrary one
+        static const int DEFAULT_Y = 200;
+
+        x = pos.x;
+        y = pos.y == wxDefaultCoord ? DEFAULT_Y : pos.y;
+    }
+
+    if ( size.x == wxDefaultCoord || size.y == wxDefaultCoord )
+    {
+        // We don't use CW_USEDEFAULT here for several reasons:
+        //
+        //  1. It results in huge frames on modern screens (1000*800 is not
+        //     uncommon on my 1280*1024 screen) which is way too big for a half
+        //     empty frame of most of wxWidgets samples for example)
+        //
+        //  2. It is buggy for frames with wxFRAME_TOOL_WINDOW style for which
+        //     the default is for whatever reason 8*8 which breaks client <->
+        //     window size calculations (it would be nice if it didn't, but it
+        //     does and the simplest way to fix it seemed to change the broken
+        //     default size anyhow)
+        //
+        //  3. There is just no advantage in doing it: with x and y it is
+        //     possible that [future versions of] Windows position the new top
+        //     level window in some smart way which we can't do, but we can
+        //     guess a reasonably good size for a new window just as well
+        //     ourselves
+        //
+        // The only exception is for the Windows CE platform where the system
+        // does know better than we how should the windows be sized
+#ifdef _WIN32_WCE
+        w =
+        h = CW_USEDEFAULT;
+#else // !_WIN32_WCE
+        wxSize sizeReal = size;
+        sizeReal.SetDefaults(GetDefaultSize());
+
+        w = sizeReal.x;
+        h = sizeReal.y;
+#endif // _WIN32_WCE/!_WIN32_WCE
+    }
+    else
+    {
+        w = size.x;
+        h = size.y;
+    }
+}
+
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowMSW fullscreen
 // ----------------------------------------------------------------------------