From fa5f4858288ebd8e031b9d3e89d4ec89e8f212e7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 22 Apr 2010 11:21:21 +0000 Subject: [PATCH] Override wxWindow::MSWGetCreateWindowCoords() in wxTopLevelWindow. The old code was messy because it handled both top level and child windows at wxWindow level when they need quite different treatment. This resulted in several errors: first, wxWindow versions of WidthDefault and HeightDefault were used to determine the initial size even of top level windows which was clearly wrong as it created tiny windows (20*20). Second, CW_USEDEFAULT could be used for child window for which this shouldn't be done. Fix this by making MSWGetCreateWindowCoords() virtual and overriding it in wxTopLevelWindow. This makes the code much simpler and more obviously correct. Also make MSWGetCreateWindowCoords() void, as nobody was using its return value anyhow (and the old version also had a bug in it and wrongly returned true when default size was passed to it). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64101 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/toplevel.h | 6 ++++ include/wx/msw/window.h | 16 ++++----- src/msw/toplevel.cpp | 68 ++++++++++++++++++++++++++++++++++- src/msw/window.cpp | 74 ++++++--------------------------------- 4 files changed, 90 insertions(+), 74 deletions(-) diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index b464c227b7..fb242e68f7 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -147,6 +147,12 @@ protected: // returns true if the icon was set bool DoSelectAndSetIcon(const wxIconBundle& icons, int smX, int smY, int i); + // override wxWindow virtual method to use CW_USEDEFAULT if necessary + virtual void MSWGetCreateWindowCoords(const wxPoint& pos, + const wxSize& size, + int& x, int& y, + int& w, int& h) const; + // is the window currently iconized? bool m_iconized; diff --git a/include/wx/msw/window.h b/include/wx/msw/window.h index 52bdd1eeb2..96b6d1bbe6 100644 --- a/include/wx/msw/window.h +++ b/include/wx/msw/window.h @@ -234,15 +234,6 @@ public: // created yet) void MSWUpdateStyle(long flagsOld, long exflagsOld); - // translate wxWidgets coords into Windows ones suitable to be passed to - // ::CreateWindow() - // - // returns true if non default coords are returned, false otherwise - bool MSWGetCreateWindowCoords(const wxPoint& pos, - const wxSize& size, - int& x, int& y, - int& w, int& h) const; - // get the HWND to be used as parent of this window with CreateWindow() virtual WXHWND MSWGetParent() const; @@ -592,6 +583,13 @@ protected: // for state as the system will decide for us what needs to be set void MSWUpdateUIState(int action, int state = 0); + // translate wxWidgets coords into Windows ones suitable to be passed to + // ::CreateWindow(), called from MSWCreate() + virtual void MSWGetCreateWindowCoords(const wxPoint& pos, + const wxSize& size, + int& x, int& y, + int& w, int& h) const; + private: // common part of all ctors void Init(); diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index cfcf7f7836..dc5b8bd83d 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -615,7 +615,7 @@ void wxTopLevelWindowMSW::ShowWithoutActivating() { if ( !wxWindowBase::Show(true) ) return; - + DoShowWindow(SW_SHOWNA); } @@ -844,6 +844,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 // ---------------------------------------------------------------------------- diff --git a/src/msw/window.cpp b/src/msw/window.cpp index da62175805..b814cb6565 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -3640,33 +3640,22 @@ void wxWindowMSW::MSWDestroyWindow() { } -bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, +void wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, const wxSize& size, int& x, int& y, int& w, int& h) const { - // yes, those are just some arbitrary hardcoded numbers - static const int DEFAULT_Y = 200; + // CW_USEDEFAULT can't be used for child windows so just position them at + // the origin by default + x = pos.x == wxDefaultCoord ? 0 : pos.x; + y = pos.y == wxDefaultCoord ? 0 : pos.y; - bool nonDefault = false; - - 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 - x = pos.x; - y = pos.y == wxDefaultCoord ? DEFAULT_Y : pos.y; + AdjustForParentClientOrigin(x, y); - nonDefault = true; - } + // We don't have any clearly good choice for the size by default neither + // but we must use something non-zero. + w = WidthDefault(size.x); + h = HeightDefault(size.y); /* NB: there used to be some code here which set the initial size of the @@ -3684,49 +3673,6 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos, this and ignore any attempts to change the window size to the size it already has - so no WM_SIZE would be sent. */ - - - // 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 - - // However, on PocketPC devices, we must use the default - // size if possible. -#ifdef _WIN32_WCE - if (size.x == wxDefaultCoord) - w = CW_USEDEFAULT; - else - w = size.x; - if (size.y == wxDefaultCoord) - h = CW_USEDEFAULT; - else - h = size.y; -#else - if ( size.x == wxDefaultCoord || size.y == wxDefaultCoord) - { - nonDefault = true; - } - w = WidthDefault(size.x); - h = HeightDefault(size.y); -#endif - - AdjustForParentClientOrigin(x, y); - - return nonDefault; } WXHWND wxWindowMSW::MSWGetParent() const -- 2.45.2