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:
parent
8810d43125
commit
d4597e138e
@ -90,6 +90,7 @@ protected:
|
||||
|
||||
// implement the geometry-related methods for a top level window
|
||||
virtual void DoSetClientSize(int width, int height);
|
||||
virtual void DoGetClientSize(int *width, int *height) const;
|
||||
|
||||
// get the MSW window flags corresponding to wxWindows ones
|
||||
//
|
||||
|
@ -47,9 +47,9 @@ enum
|
||||
wxFULLSCREEN_NOSTATUSBAR = 0x0004,
|
||||
wxFULLSCREEN_NOBORDER = 0x0008,
|
||||
wxFULLSCREEN_NOCAPTION = 0x0010,
|
||||
|
||||
wxFULLSCREEN_ALL = wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR |
|
||||
wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER |
|
||||
|
||||
wxFULLSCREEN_ALL = wxFULLSCREEN_NOMENUBAR | wxFULLSCREEN_NOTOOLBAR |
|
||||
wxFULLSCREEN_NOSTATUSBAR | wxFULLSCREEN_NOBORDER |
|
||||
wxFULLSCREEN_NOCAPTION
|
||||
};
|
||||
|
||||
@ -105,7 +105,7 @@ public:
|
||||
|
||||
// maximize the window to cover entire screen
|
||||
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) = 0;
|
||||
|
||||
|
||||
// return TRUE if the frame is in fullscreen mode
|
||||
virtual bool IsFullScreen() const = 0;
|
||||
|
||||
@ -122,7 +122,7 @@ public:
|
||||
bool Iconized() const { return IsIconized(); }
|
||||
#endif // WXWIN_COMPATIBILITY_2
|
||||
|
||||
|
||||
|
||||
#ifdef __WXUNIVERSAL__
|
||||
// move/resize the frame interactively, i.e. let the user do it
|
||||
virtual void InteractiveMove(int flags = wxINTERACTIVE_MOVE);
|
||||
|
@ -148,12 +148,13 @@ wxPoint wxFrameBase::GetClientAreaOrigin() const
|
||||
wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin();
|
||||
|
||||
#if wxUSE_TOOLBAR
|
||||
if ( GetToolBar() && GetToolBar()->IsShown() )
|
||||
wxToolBar *toolbar = GetToolBar();
|
||||
if ( toolbar && toolbar->IsShown() )
|
||||
{
|
||||
int w, h;
|
||||
GetToolBar()->GetSize(& w, & h);
|
||||
toolbar->GetSize(&w, &h);
|
||||
|
||||
if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
|
||||
if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
|
||||
{
|
||||
pt.x += w;
|
||||
}
|
||||
@ -186,7 +187,7 @@ bool wxFrameBase::ProcessCommand(int id)
|
||||
{
|
||||
if (!item->IsEnabled())
|
||||
return TRUE;
|
||||
|
||||
|
||||
if (item->IsCheckable())
|
||||
{
|
||||
item->Toggle();
|
||||
|
@ -142,30 +142,9 @@ wxFrame::~wxFrame()
|
||||
DeleteAllBars();
|
||||
}
|
||||
|
||||
// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
|
||||
void wxFrame::DoGetClientSize(int *x, int *y) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxFrame client size calculations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxFrame::DoSetClientSize(int width, int height)
|
||||
{
|
||||
@ -181,6 +160,24 @@ void wxFrame::DoSetClientSize(int width, int 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
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -234,7 +231,7 @@ wxStatusBar *wxFrame::OnCreateStatusBar(int number,
|
||||
|
||||
void wxFrame::PositionStatusBar()
|
||||
{
|
||||
if ( !m_frameStatusBar )
|
||||
if ( !m_frameStatusBar || !m_frameStatusBar->IsShown() )
|
||||
return;
|
||||
|
||||
int w, h;
|
||||
@ -459,36 +456,40 @@ wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& nam
|
||||
|
||||
void wxFrame::PositionToolBar()
|
||||
{
|
||||
RECT rect;
|
||||
::GetClientRect(GetHwnd(), &rect);
|
||||
wxToolBar *toolbar = GetToolBar();
|
||||
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 ( GetStatusBar() )
|
||||
{
|
||||
int statusX, statusY;
|
||||
GetStatusBar()->GetClientSize(&statusX, &statusY);
|
||||
rect.bottom -= statusY;
|
||||
}
|
||||
wxStatusBar *statbar = GetStatusBar();
|
||||
if ( statbar && statbar->IsShown() )
|
||||
{
|
||||
height -= statbar->GetClientSize().y;
|
||||
}
|
||||
#endif // wxUSE_STATUSBAR
|
||||
|
||||
if ( GetToolBar() && GetToolBar()->IsShown() )
|
||||
{
|
||||
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
|
||||
{
|
||||
tw = rect.right;
|
||||
tw = width;
|
||||
}
|
||||
|
||||
// Use the 'real' MSW position here
|
||||
GetToolBar()->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
|
||||
// use the 'real' MSW position here, don't offset relativly to the
|
||||
// client area origin
|
||||
toolbar->SetSize(0, 0, tw, th, wxSIZE_NO_ADJUSTMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // wxUSE_TOOLBAR
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -387,39 +387,30 @@ wxTopLevelWindowMSW::~wxTopLevelWindowMSW()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxTopLevelWindowMSW geometry
|
||||
// wxTopLevelWindowMSW client size
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxTopLevelWindowMSW::DoSetClientSize(int width, int height)
|
||||
{
|
||||
HWND hWnd = GetHwnd();
|
||||
|
||||
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
|
||||
// call GetClientAreaOrigin() to take the toolbar into account
|
||||
wxPoint pt = GetClientAreaOrigin();
|
||||
width += pt.x;
|
||||
height += pt.y;
|
||||
|
||||
if ( !::MoveWindow(hWnd, rectTotal.left, rectTotal.top,
|
||||
width, height, TRUE /* redraw */) )
|
||||
{
|
||||
wxLogLastError(_T("MoveWindow"));
|
||||
}
|
||||
wxWindow::DoSetClientSize(width, height);
|
||||
}
|
||||
|
||||
wxSizeEvent event(wxSize(width, height), m_windowId);
|
||||
event.SetEventObject(this);
|
||||
(void)GetEventHandler()->ProcessEvent(event);
|
||||
void wxTopLevelWindowMSW::DoGetClientSize(int *x, int *y) const
|
||||
{
|
||||
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)
|
||||
{
|
||||
wxWindow *parent = GetParent();
|
||||
HWND hWnd = GetHwnd();
|
||||
HWND hParentWnd = (HWND) 0;
|
||||
if ( parent )
|
||||
hParentWnd = (HWND) parent->GetHWND();
|
||||
|
||||
RECT rect;
|
||||
::GetClientRect(hWnd, &rect);
|
||||
|
||||
RECT rect2;
|
||||
GetWindowRect(hWnd, &rect2);
|
||||
|
||||
// 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 )
|
||||
// setting the client size is less obvious than it it could have been
|
||||
// because in the result of changing the total size the window scrollbar
|
||||
// may [dis]appear and/or its menubar may [un]wrap and so the client size
|
||||
// will not be correct as the difference between the total and client size
|
||||
// changes - so we keep changing it until we get it right
|
||||
//
|
||||
// normally this loop shouldn't take more than 2 iterations (usually 1 but
|
||||
// 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
|
||||
// "infinite" loop (i.e. leaving break inside as the only way to get out)
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
{
|
||||
::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
|
||||
|
Loading…
Reference in New Issue
Block a user