fixed bugs with setting the client size when the difference between the total and client size changes as the result (e.g. because the scrollbars [dis]appear or the menu bar [un]wraps
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12934 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -90,6 +90,7 @@ protected:
|
|||||||
|
|
||||||
// implement the geometry-related methods for a top level window
|
// implement the geometry-related methods for a top level window
|
||||||
virtual void DoSetClientSize(int width, int height);
|
virtual void DoSetClientSize(int width, int height);
|
||||||
|
virtual void DoGetClientSize(int *width, int *height) const;
|
||||||
|
|
||||||
// get the MSW window flags corresponding to wxWindows ones
|
// get the MSW window flags corresponding to wxWindows ones
|
||||||
//
|
//
|
||||||
|
@@ -47,9 +47,9 @@ enum
|
|||||||
wxFULLSCREEN_NOSTATUSBAR = 0x0004,
|
wxFULLSCREEN_NOSTATUSBAR = 0x0004,
|
||||||
wxFULLSCREEN_NOBORDER = 0x0008,
|
wxFULLSCREEN_NOBORDER = 0x0008,
|
||||||
wxFULLSCREEN_NOCAPTION = 0x0010,
|
wxFULLSCREEN_NOCAPTION = 0x0010,
|
||||||
|
|
||||||
wxFULLSCREEN_ALL = wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR |
|
wxFULLSCREEN_ALL = wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR |
|
||||||
wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER |
|
wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER |
|
||||||
wxFULLSCREEN_NOCAPTION
|
wxFULLSCREEN_NOCAPTION
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ public:
|
|||||||
|
|
||||||
// maximize the window to cover entire screen
|
// maximize the window to cover entire screen
|
||||||
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) = 0;
|
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) = 0;
|
||||||
|
|
||||||
// return TRUE if the frame is in fullscreen mode
|
// return TRUE if the frame is in fullscreen mode
|
||||||
virtual bool IsFullScreen() const = 0;
|
virtual bool IsFullScreen() const = 0;
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ public:
|
|||||||
bool Iconized() const { return IsIconized(); }
|
bool Iconized() const { return IsIconized(); }
|
||||||
#endif // WXWIN_COMPATIBILITY_2
|
#endif // WXWIN_COMPATIBILITY_2
|
||||||
|
|
||||||
|
|
||||||
#ifdef __WXUNIVERSAL__
|
#ifdef __WXUNIVERSAL__
|
||||||
// move/resize the frame interactively, i.e. let the user do it
|
// move/resize the frame interactively, i.e. let the user do it
|
||||||
virtual void InteractiveMove(int flags = wxINTERACTIVE_MOVE);
|
virtual void InteractiveMove(int flags = wxINTERACTIVE_MOVE);
|
||||||
|
@@ -148,12 +148,13 @@ wxPoint wxFrameBase::GetClientAreaOrigin() const
|
|||||||
wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
|
wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
|
||||||
|
|
||||||
#if wxUSE_TOOLBAR
|
#if wxUSE_TOOLBAR
|
||||||
if ( GetToolBar() && GetToolBar()->IsShown() )
|
wxToolBar *toolbar = GetToolBar();
|
||||||
|
if ( toolbar && toolbar->IsShown() )
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
GetToolBar()->GetSize(& w, & h);
|
toolbar->GetSize(&w, &h);
|
||||||
|
|
||||||
if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
|
if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
|
||||||
{
|
{
|
||||||
pt.x += w;
|
pt.x += w;
|
||||||
}
|
}
|
||||||
@@ -186,7 +187,7 @@ bool wxFrameBase::ProcessCommand(int id)
|
|||||||
{
|
{
|
||||||
if (!item->IsEnabled())
|
if (!item->IsEnabled())
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (item->IsCheckable())
|
if (item->IsCheckable())
|
||||||
{
|
{
|
||||||
item->Toggle();
|
item->Toggle();
|
||||||
|
@@ -142,30 +142,9 @@ wxFrame::~wxFrame()
|
|||||||
DeleteAllBars();
|
DeleteAllBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
|
// ----------------------------------------------------------------------------
|
||||||
void wxFrame::DoGetClientSize(int *x, int *y) const
|
// wxFrame client size calculations
|
||||||
{
|
// ----------------------------------------------------------------------------
|
||||||
RECT rect;
|
|
||||||
::GetClientRect(GetHwnd(), &rect);
|
|
||||||
|
|
||||||
#if wxUSE_STATUSBAR
|
|
||||||
if ( GetStatusBar() && GetStatusBar()->IsShown() )
|
|
||||||
{
|
|
||||||
int statusX, statusY;
|
|
||||||
GetStatusBar()->GetClientSize(&statusX, &statusY);
|
|
||||||
rect.bottom -= statusY;
|
|
||||||
}
|
|
||||||
#endif // wxUSE_STATUSBAR
|
|
||||||
|
|
||||||
wxPoint pt(GetClientAreaOrigin());
|
|
||||||
rect.bottom -= pt.y;
|
|
||||||
rect.right -= pt.x;
|
|
||||||
|
|
||||||
if ( x )
|
|
||||||
*x = rect.right;
|
|
||||||
if ( y )
|
|
||||||
*y = rect.bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxFrame::DoSetClientSize(int width, int height)
|
void wxFrame::DoSetClientSize(int width, int height)
|
||||||
{
|
{
|
||||||
@@ -181,6 +160,24 @@ void wxFrame::DoSetClientSize(int width, int height)
|
|||||||
wxTopLevelWindow::DoSetClientSize(width, height);
|
wxTopLevelWindow::DoSetClientSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
|
||||||
|
void wxFrame::DoGetClientSize(int *x, int *y) const
|
||||||
|
{
|
||||||
|
wxTopLevelWindow::DoGetClientSize(x, y);
|
||||||
|
|
||||||
|
#if wxUSE_STATUSBAR
|
||||||
|
// adjust client area height to take the status bar into account
|
||||||
|
if ( y )
|
||||||
|
{
|
||||||
|
wxStatusBar *statbar = GetStatusBar();
|
||||||
|
if ( statbar && statbar->IsShown() )
|
||||||
|
{
|
||||||
|
*y -= statbar->GetClientSize().y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // wxUSE_STATUSBAR
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxFrame: various geometry-related functions
|
// wxFrame: various geometry-related functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -234,7 +231,7 @@ wxStatusBar *wxFrame::OnCreateStatusBar(int number,
|
|||||||
|
|
||||||
void wxFrame::PositionStatusBar()
|
void wxFrame::PositionStatusBar()
|
||||||
{
|
{
|
||||||
if ( !m_frameStatusBar )
|
if ( !m_frameStatusBar || !m_frameStatusBar->IsShown() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
@@ -459,36 +456,40 @@ wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& nam
|
|||||||
|
|
||||||
void wxFrame::PositionToolBar()
|
void wxFrame::PositionToolBar()
|
||||||
{
|
{
|
||||||
RECT rect;
|
wxToolBar *toolbar = GetToolBar();
|
||||||
::GetClientRect(GetHwnd(), &rect);
|
if ( toolbar && toolbar->IsShown() )
|
||||||
|
{
|
||||||
|
// don't call our (or even wxTopLevelWindow) version because we want
|
||||||
|
// the real (full) client area size, not excluding the tool/status bar
|
||||||
|
int width, height;
|
||||||
|
wxWindow::DoGetClientSize(&width, &height);
|
||||||
|
|
||||||
#if wxUSE_STATUSBAR
|
#if wxUSE_STATUSBAR
|
||||||
if ( GetStatusBar() )
|
wxStatusBar *statbar = GetStatusBar();
|
||||||
{
|
if ( statbar && statbar->IsShown() )
|
||||||
int statusX, statusY;
|
{
|
||||||
GetStatusBar()->GetClientSize(&statusX, &statusY);
|
height -= statbar->GetClientSize().y;
|
||||||
rect.bottom -= statusY;
|
}
|
||||||
}
|
|
||||||
#endif // wxUSE_STATUSBAR
|
#endif // wxUSE_STATUSBAR
|
||||||
|
|
||||||
if ( GetToolBar() && GetToolBar()->IsShown() )
|
|
||||||
{
|
|
||||||
int tw, th;
|
int tw, th;
|
||||||
GetToolBar()->GetSize(&tw, &th);
|
toolbar->GetSize(&tw, &th);
|
||||||
|
|
||||||
if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
|
if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
|
||||||
{
|
{
|
||||||
th = rect.bottom;
|
th = height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tw = rect.right;
|
tw = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the 'real' MSW position here
|
// use the 'real' MSW position here, don't offset relativly to the
|
||||||
GetToolBar()->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
|
// client area origin
|
||||||
|
toolbar->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_TOOLBAR
|
#endif // wxUSE_TOOLBAR
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -387,39 +387,30 @@ wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// wxTopLevelWindowMSW geometry
|
// wxTopLevelWindowMSW client size
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxTopLevelWindowMSW::DoSetClientSize(int width, int height)
|
void wxTopLevelWindowMSW::DoSetClientSize(int width, int height)
|
||||||
{
|
{
|
||||||
HWND hWnd = GetHwnd();
|
// call GetClientAreaOrigin() to take the toolbar into account
|
||||||
|
|
||||||
RECT rectClient;
|
|
||||||
::GetClientRect(hWnd, &rectClient);
|
|
||||||
|
|
||||||
RECT rectTotal;
|
|
||||||
::GetWindowRect(hWnd, &rectTotal);
|
|
||||||
|
|
||||||
// Find the difference between the entire window (title bar and all)
|
|
||||||
// and the client area; add this to the new client size to move the
|
|
||||||
// window
|
|
||||||
width += rectTotal.right - rectTotal.left - rectClient.right;
|
|
||||||
height += rectTotal.bottom - rectTotal.top - rectClient.bottom;
|
|
||||||
|
|
||||||
// note that calling GetClientAreaOrigin() takes the toolbar into account
|
|
||||||
wxPoint pt = GetClientAreaOrigin();
|
wxPoint pt = GetClientAreaOrigin();
|
||||||
width += pt.x;
|
width += pt.x;
|
||||||
height += pt.y;
|
height += pt.y;
|
||||||
|
|
||||||
if ( !::MoveWindow(hWnd, rectTotal.left, rectTotal.top,
|
wxWindow::DoSetClientSize(width, height);
|
||||||
width, height, TRUE /* redraw */) )
|
}
|
||||||
{
|
|
||||||
wxLogLastError(_T("MoveWindow"));
|
|
||||||
}
|
|
||||||
|
|
||||||
wxSizeEvent event(wxSize(width, height), m_windowId);
|
void wxTopLevelWindowMSW::DoGetClientSize(int *x, int *y) const
|
||||||
event.SetEventObject(this);
|
{
|
||||||
(void)GetEventHandler()->ProcessEvent(event);
|
wxWindow::DoGetClientSize(x, y);
|
||||||
|
|
||||||
|
wxPoint pt = GetClientAreaOrigin();
|
||||||
|
|
||||||
|
if ( x )
|
||||||
|
*x -= pt.x;
|
||||||
|
|
||||||
|
if ( y )
|
||||||
|
*y -= pt.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -1493,40 +1493,65 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
|
|||||||
|
|
||||||
void wxWindowMSW::DoSetClientSize(int width, int height)
|
void wxWindowMSW::DoSetClientSize(int width, int height)
|
||||||
{
|
{
|
||||||
wxWindow *parent = GetParent();
|
// setting the client size is less obvious than it it could have been
|
||||||
HWND hWnd = GetHwnd();
|
// because in the result of changing the total size the window scrollbar
|
||||||
HWND hParentWnd = (HWND) 0;
|
// may [dis]appear and/or its menubar may [un]wrap and so the client size
|
||||||
if ( parent )
|
// will not be correct as the difference between the total and client size
|
||||||
hParentWnd = (HWND) parent->GetHWND();
|
// changes - so we keep changing it until we get it right
|
||||||
|
//
|
||||||
RECT rect;
|
// normally this loop shouldn't take more than 2 iterations (usually 1 but
|
||||||
::GetClientRect(hWnd, &rect);
|
// if scrollbars [dis]appear as the result of the first call, then 2) but
|
||||||
|
// just to be on the safe side we check for it instead of making it an
|
||||||
RECT rect2;
|
// "infinite" loop (i.e. leaving break inside as the only way to get out)
|
||||||
GetWindowRect(hWnd, &rect2);
|
for ( int i = 0; i < 3; i++ )
|
||||||
|
|
||||||
// Find the difference between the entire window (title bar and all)
|
|
||||||
// and the client area; add this to the new client size to move the
|
|
||||||
// window
|
|
||||||
int actual_width = rect2.right - rect2.left - rect.right + width;
|
|
||||||
int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
|
|
||||||
|
|
||||||
// If there's a parent, must subtract the parent's top left corner
|
|
||||||
// since MoveWindow moves relative to the parent
|
|
||||||
|
|
||||||
POINT point;
|
|
||||||
point.x = rect2.left;
|
|
||||||
point.y = rect2.top;
|
|
||||||
if ( parent )
|
|
||||||
{
|
{
|
||||||
::ScreenToClient(hParentWnd, &point);
|
RECT rectClient;
|
||||||
|
::GetClientRect(GetHwnd(), &rectClient);
|
||||||
|
|
||||||
|
// if the size is already ok, stop here (rectClient.left = top = 0)
|
||||||
|
if ( rectClient.right == width && rectClient.bottom == height )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( i == 2 )
|
||||||
|
{
|
||||||
|
// how did it happen? maybe OnSize() handler does something really
|
||||||
|
// strange in this class?
|
||||||
|
wxFAIL_MSG( _T("logic error in DoSetClientSize") );
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int widthClient = width,
|
||||||
|
heightClient = height;
|
||||||
|
|
||||||
|
// Find the difference between the entire window (title bar and all)
|
||||||
|
// and the client area; add this to the new client size to move the
|
||||||
|
// window
|
||||||
|
RECT rectWin;
|
||||||
|
::GetWindowRect(GetHwnd(), &rectWin);
|
||||||
|
|
||||||
|
widthClient += rectWin.right - rectWin.left - rectClient.right;
|
||||||
|
heightClient += rectWin.bottom - rectWin.top - rectClient.bottom;
|
||||||
|
|
||||||
|
POINT point;
|
||||||
|
point.x = rectWin.left;
|
||||||
|
point.y = rectWin.top;
|
||||||
|
|
||||||
|
// MoveWindow positions the child windows relative to the parent, so
|
||||||
|
// adjust if necessary
|
||||||
|
if ( !IsTopLevel() )
|
||||||
|
{
|
||||||
|
wxWindow *parent = GetParent();
|
||||||
|
if ( parent )
|
||||||
|
{
|
||||||
|
::ScreenToClient(GetHwndOf(parent), &point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoMoveWindow(point.x, point.y, widthClient, heightClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
DoMoveWindow(point.x, point.y, actual_width, actual_height);
|
|
||||||
|
|
||||||
wxSizeEvent event(wxSize(width, height), m_windowId);
|
|
||||||
event.SetEventObject(this);
|
|
||||||
GetEventHandler()->ProcessEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For implementation purposes - sometimes decorations make the client area
|
// For implementation purposes - sometimes decorations make the client area
|
||||||
|
Reference in New Issue
Block a user