fix window position under MSW when limited by short
range
This commit is contained in:
@@ -729,8 +729,27 @@ private:
|
|||||||
bool MSWSafeIsDialogMessage(WXMSG* msg);
|
bool MSWSafeIsDialogMessage(WXMSG* msg);
|
||||||
#endif // __WXUNIVERSAL__
|
#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:
|
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
|
// this function is called after the window was resized to its new size
|
||||||
virtual void MSWEndDeferWindowPos()
|
virtual void MSWEndDeferWindowPos()
|
||||||
{
|
{
|
||||||
|
@@ -132,7 +132,7 @@ bool wxControl::MSWCreateControl(const wxChar *classname,
|
|||||||
// ... and adjust it to account for a possible parent frames toolbar
|
// ... and adjust it to account for a possible parent frames toolbar
|
||||||
AdjustForParentClientOrigin(x, y);
|
AdjustForParentClientOrigin(x, y);
|
||||||
|
|
||||||
m_hWnd = (WXHWND)::CreateWindowEx
|
m_hWnd = MSWCreateWindowAtAnyPosition
|
||||||
(
|
(
|
||||||
exstyle, // extended style
|
exstyle, // extended style
|
||||||
classname, // the kind of control to create
|
classname, // the kind of control to create
|
||||||
@@ -140,19 +140,11 @@ bool wxControl::MSWCreateControl(const wxChar *classname,
|
|||||||
style, // the window style
|
style, // the window style
|
||||||
x, y, w, h, // the window position and size
|
x, y, w, h, // the window position and size
|
||||||
GetHwndOf(GetParent()), // parent
|
GetHwndOf(GetParent()), // parent
|
||||||
(HMENU)wxUIntToPtr(GetId()), // child id
|
GetId() // child id
|
||||||
wxGetInstance(), // app instance
|
|
||||||
NULL // creation parameters
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( !m_hWnd )
|
if ( !m_hWnd )
|
||||||
{
|
{
|
||||||
wxLogLastError(wxString::Format
|
|
||||||
(
|
|
||||||
wxT("CreateWindowEx(\"%s\", flags=%08lx, ex=%08lx)"),
|
|
||||||
classname, style, exstyle
|
|
||||||
));
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -298,7 +298,7 @@ bool wxSpinCtrl::Create(wxWindow *parent,
|
|||||||
|
|
||||||
// create the text window
|
// create the text window
|
||||||
|
|
||||||
m_hwndBuddy = (WXHWND)::CreateWindowEx
|
m_hwndBuddy = MSWCreateWindowAtAnyPosition
|
||||||
(
|
(
|
||||||
exStyle, // sunken border
|
exStyle, // sunken border
|
||||||
wxT("EDIT"), // window class
|
wxT("EDIT"), // window class
|
||||||
@@ -307,9 +307,7 @@ bool wxSpinCtrl::Create(wxWindow *parent,
|
|||||||
pos.x, pos.y, // position
|
pos.x, pos.y, // position
|
||||||
0, 0, // size (will be set later)
|
0, 0, // size (will be set later)
|
||||||
GetHwndOf(parent), // parent
|
GetHwndOf(parent), // parent
|
||||||
(HMENU)-1, // control id
|
-1 // control id
|
||||||
wxGetInstance(), // app instance
|
|
||||||
NULL // unused client data
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( !m_hwndBuddy )
|
if ( !m_hwndBuddy )
|
||||||
|
@@ -333,7 +333,7 @@ void wxStaticBitmap::SetImageNoCopy( wxGDIImage* image)
|
|||||||
w = width;
|
w = width;
|
||||||
h = height;
|
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
|
#if wxUSE_DEFERRED_SIZING
|
||||||
else
|
else if ( MSWIsPositionDirectlySupported(x, y) )
|
||||||
{
|
{
|
||||||
// if our parent had prepared a defer window handle for us, use it (unless
|
// if our parent had prepared a defer window handle for us, use it
|
||||||
// we are a top level window)
|
|
||||||
wxWindowMSW * const parent = GetParent();
|
wxWindowMSW * const parent = GetParent();
|
||||||
|
|
||||||
HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
|
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
|
#endif // wxUSE_DEFERRED_SIZING
|
||||||
|
|
||||||
if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) )
|
MSWMoveWindowToAnyPosition(hwnd, x, y, width, height, IsShown());
|
||||||
{
|
|
||||||
wxLogLastError(wxT("MoveWindow"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if wxUSE_DEFERRED_SIZING, indicates that we didn't use deferred move,
|
// if wxUSE_DEFERRED_SIZING, indicates that we didn't use deferred move,
|
||||||
// ignored otherwise
|
// ignored otherwise
|
||||||
return false;
|
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)
|
void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
// TODO: is this consistent with other platforms?
|
// 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
|
// and not defer it here as otherwise the value returned by
|
||||||
// GetClient/WindowRect() wouldn't change as the window wouldn't be
|
// GetClient/WindowRect() wouldn't change as the window wouldn't be
|
||||||
// really resized
|
// really resized
|
||||||
if ( !::MoveWindow(GetHwnd(),
|
MSWMoveWindowToAnyPosition(GetHwnd(), rectWin.left, rectWin.top,
|
||||||
rectWin.left,
|
|
||||||
rectWin.top,
|
|
||||||
width + widthWin - rectClient.right,
|
width + widthWin - rectClient.right,
|
||||||
height + heightWin - rectClient.bottom,
|
height + heightWin - rectClient.bottom, true);
|
||||||
TRUE) )
|
|
||||||
{
|
|
||||||
wxLogLastError(wxT("MoveWindow"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3900,23 +3913,19 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
|
|||||||
// do create the window
|
// do create the window
|
||||||
wxWindowCreationHook hook(this);
|
wxWindowCreationHook hook(this);
|
||||||
|
|
||||||
m_hWnd = (WXHWND)::CreateWindowEx
|
m_hWnd = MSWCreateWindowAtAnyPosition
|
||||||
(
|
(
|
||||||
extendedStyle,
|
extendedStyle,
|
||||||
wclass,
|
wclass,
|
||||||
title ? title : m_windowName.t_str(),
|
title ? title : m_windowName.t_str(),
|
||||||
style,
|
style,
|
||||||
x, y, w, h,
|
x, y, w, h,
|
||||||
(HWND)MSWGetParent(),
|
MSWGetParent(),
|
||||||
(HMENU)wxUIntToPtr(controlId),
|
controlId
|
||||||
wxGetInstance(),
|
|
||||||
NULL // no extra data
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( !m_hWnd )
|
if ( !m_hWnd )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("Can't create window of class %s"), wclass);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3925,6 +3934,32 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
|
|||||||
return true;
|
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
|
// MSW message handlers
|
||||||
// ===========================================================================
|
// ===========================================================================
|
||||||
|
Reference in New Issue
Block a user