fix window position under MSW when limited by short
range
This commit is contained in:
@@ -729,8 +729,27 @@ private:
|
||||
bool MSWSafeIsDialogMessage(WXMSG* msg);
|
||||
#endif // __WXUNIVERSAL__
|
||||
|
||||
#if wxUSE_DEFERRED_SIZING
|
||||
static inline bool MSWIsPositionDirectlySupported(int x, int y)
|
||||
{
|
||||
// The supported coordinate intervals for various functions are:
|
||||
// - MoveWindow, DeferWindowPos: [-32768, 32767] a.k.a. [SHRT_MIN, SHRT_MAX];
|
||||
// - CreateWindow, CreateWindowEx: [-32768, 32554].
|
||||
// CreateXXX will _sometimes_ manage to create the window at higher coordinates
|
||||
// like 32580, 32684, 32710, but that was not consistent and the lowest common
|
||||
// limit was 32554 (so far at least).
|
||||
return (x >= SHRT_MIN && x <= 32554 && y >= SHRT_MIN && y <= 32554);
|
||||
}
|
||||
|
||||
protected:
|
||||
WXHWND MSWCreateWindowAtAnyPosition(WXDWORD exStyle, const wxChar* clName,
|
||||
const wxChar* title, WXDWORD style,
|
||||
int x, int y, int width, int height,
|
||||
WXHWND parent, wxWindowID id);
|
||||
|
||||
void MSWMoveWindowToAnyPosition(WXHWND hwnd, int x, int y,
|
||||
int width, int height, bool bRepaint);
|
||||
|
||||
#if wxUSE_DEFERRED_SIZING
|
||||
// this function is called after the window was resized to its new size
|
||||
virtual void MSWEndDeferWindowPos()
|
||||
{
|
||||
|
@@ -132,7 +132,7 @@ bool wxControl::MSWCreateControl(const wxChar *classname,
|
||||
// ... and adjust it to account for a possible parent frames toolbar
|
||||
AdjustForParentClientOrigin(x, y);
|
||||
|
||||
m_hWnd = (WXHWND)::CreateWindowEx
|
||||
m_hWnd = MSWCreateWindowAtAnyPosition
|
||||
(
|
||||
exstyle, // extended style
|
||||
classname, // the kind of control to create
|
||||
@@ -140,19 +140,11 @@ bool wxControl::MSWCreateControl(const wxChar *classname,
|
||||
style, // the window style
|
||||
x, y, w, h, // the window position and size
|
||||
GetHwndOf(GetParent()), // parent
|
||||
(HMENU)wxUIntToPtr(GetId()), // child id
|
||||
wxGetInstance(), // app instance
|
||||
NULL // creation parameters
|
||||
GetId() // child id
|
||||
);
|
||||
|
||||
if ( !m_hWnd )
|
||||
{
|
||||
wxLogLastError(wxString::Format
|
||||
(
|
||||
wxT("CreateWindowEx(\"%s\", flags=%08lx, ex=%08lx)"),
|
||||
classname, style, exstyle
|
||||
));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -298,7 +298,7 @@ bool wxSpinCtrl::Create(wxWindow *parent,
|
||||
|
||||
// create the text window
|
||||
|
||||
m_hwndBuddy = (WXHWND)::CreateWindowEx
|
||||
m_hwndBuddy = MSWCreateWindowAtAnyPosition
|
||||
(
|
||||
exStyle, // sunken border
|
||||
wxT("EDIT"), // window class
|
||||
@@ -307,9 +307,7 @@ bool wxSpinCtrl::Create(wxWindow *parent,
|
||||
pos.x, pos.y, // position
|
||||
0, 0, // size (will be set later)
|
||||
GetHwndOf(parent), // parent
|
||||
(HMENU)-1, // control id
|
||||
wxGetInstance(), // app instance
|
||||
NULL // unused client data
|
||||
-1 // control id
|
||||
);
|
||||
|
||||
if ( !m_hwndBuddy )
|
||||
|
@@ -333,7 +333,7 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
|
||||
w = width;
|
||||
h = height;
|
||||
|
||||
::MoveWindow(GetHwnd(), x, y, width, height, FALSE);
|
||||
MSWMoveWindowToAnyPosition(GetHwnd(), x, y, width, height, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1955,10 +1955,9 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
|
||||
}
|
||||
|
||||
#if wxUSE_DEFERRED_SIZING
|
||||
else
|
||||
else if ( MSWIsPositionDirectlySupported(x, y) )
|
||||
{
|
||||
// if our parent had prepared a defer window handle for us, use it (unless
|
||||
// we are a top level window)
|
||||
// if our parent had prepared a defer window handle for us, use it
|
||||
wxWindowMSW * const parent = GetParent();
|
||||
|
||||
HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
|
||||
@@ -1989,16 +1988,36 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
|
||||
}
|
||||
#endif // wxUSE_DEFERRED_SIZING
|
||||
|
||||
if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) )
|
||||
{
|
||||
wxLogLastError(wxT("MoveWindow"));
|
||||
}
|
||||
MSWMoveWindowToAnyPosition(hwnd, x, y, width, height, IsShown());
|
||||
|
||||
// if wxUSE_DEFERRED_SIZING, indicates that we didn't use deferred move,
|
||||
// ignored otherwise
|
||||
return false;
|
||||
}
|
||||
|
||||
void wxWindowMSW::MSWMoveWindowToAnyPosition(WXHWND hwnd, int x, int y, int width, int height, bool bRepaint)
|
||||
{
|
||||
bool scroll = GetParent() && !MSWIsPositionDirectlySupported(x, y);
|
||||
|
||||
if ( scroll )
|
||||
{
|
||||
// scroll to the actual position (looks like there is no need to Freeze() the parent)
|
||||
::ScrollWindow(GetHwndOf(GetParent()), -x, -y, NULL, NULL);
|
||||
}
|
||||
|
||||
// move to relative coordinates
|
||||
if ( !::MoveWindow(hwnd, (scroll ? 0 : x), (scroll ? 0 : y), width, height, bRepaint) )
|
||||
{
|
||||
wxLogLastError(wxT("MoveWindow"));
|
||||
}
|
||||
|
||||
if ( scroll )
|
||||
{
|
||||
// scroll back
|
||||
::ScrollWindow(GetHwndOf(GetParent()), x, y, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
|
||||
{
|
||||
// TODO: is this consistent with other platforms?
|
||||
@@ -2171,15 +2190,9 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
|
||||
// and not defer it here as otherwise the value returned by
|
||||
// GetClient/WindowRect() wouldn't change as the window wouldn't be
|
||||
// really resized
|
||||
if ( !::MoveWindow(GetHwnd(),
|
||||
rectWin.left,
|
||||
rectWin.top,
|
||||
MSWMoveWindowToAnyPosition(GetHwnd(), rectWin.left, rectWin.top,
|
||||
width + widthWin - rectClient.right,
|
||||
height + heightWin - rectClient.bottom,
|
||||
TRUE) )
|
||||
{
|
||||
wxLogLastError(wxT("MoveWindow"));
|
||||
}
|
||||
height + heightWin - rectClient.bottom, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3900,23 +3913,19 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
|
||||
// do create the window
|
||||
wxWindowCreationHook hook(this);
|
||||
|
||||
m_hWnd = (WXHWND)::CreateWindowEx
|
||||
m_hWnd = MSWCreateWindowAtAnyPosition
|
||||
(
|
||||
extendedStyle,
|
||||
wclass,
|
||||
title ? title : m_windowName.t_str(),
|
||||
style,
|
||||
x, y, w, h,
|
||||
(HWND)MSWGetParent(),
|
||||
(HMENU)wxUIntToPtr(controlId),
|
||||
wxGetInstance(),
|
||||
NULL // no extra data
|
||||
MSWGetParent(),
|
||||
controlId
|
||||
);
|
||||
|
||||
if ( !m_hWnd )
|
||||
{
|
||||
wxLogSysError(_("Can't create window of class %s"), wclass);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3925,6 +3934,32 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
|
||||
return true;
|
||||
}
|
||||
|
||||
WXHWND wxWindowMSW::MSWCreateWindowAtAnyPosition(WXDWORD exStyle, const wxChar* clName,
|
||||
const wxChar* title, WXDWORD style,
|
||||
int x, int y, int width, int height,
|
||||
WXHWND parent, wxWindowID id)
|
||||
{
|
||||
WXHWND hWnd = ::CreateWindowEx(exStyle, clName, title, style, x, y, width, height,
|
||||
parent, (HMENU)wxUIntToPtr(id), wxGetInstance(),
|
||||
NULL); // no extra data
|
||||
|
||||
if ( !hWnd )
|
||||
{
|
||||
wxLogLastError(wxString::Format
|
||||
(
|
||||
wxT("CreateWindowEx(\"%s\", flags=%08lx, ex=%08lx)"),
|
||||
clName, style, exStyle
|
||||
));
|
||||
}
|
||||
else if ( !IsTopLevel() && !MSWIsPositionDirectlySupported(x, y) )
|
||||
{
|
||||
// fix position if limited by Short range
|
||||
MSWMoveWindowToAnyPosition(hWnd, x, y, width, height, IsShown());
|
||||
}
|
||||
|
||||
return hWnd;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// MSW message handlers
|
||||
// ===========================================================================
|
||||
|
Reference in New Issue
Block a user