#include "wx/msgdlg.h"
#include "wx/settings.h"
#include "wx/statbox.h"
+ #include "wx/sizer.h"
#endif
#if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
#endif // everything needed for TrackMouseEvent()
#define USE_DEFERRED_SIZING 1
+#define USE_DEFER_BUG_WORKAROUND 1
// ---------------------------------------------------------------------------
// global variables
m_lastMouseY = -1;
m_lastMouseEvent = -1;
#endif // wxUSE_MOUSEEVENT_HACK
+
+ m_pendingPosition = wxDefaultPosition;
+ m_pendingSize = wxDefaultSize;
}
// Destructor
{
m_isBeingDeleted = true;
- if (m_windowReserved)
- {
- delete (wxExtraWindowData*) m_windowReserved;
- m_windowReserved = NULL;
- }
-
#ifndef __WXUNIVERSAL__
// VS: make sure there's no wxFrame with last focus set to us:
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
}
delete m_childrenDisabled;
+
}
// real construction (Init() must have been called before!)
pRect = NULL;
}
-#ifndef __SMARTPHONE__
+ // RedrawWindow not available on SmartPhone or eVC++ 3
+#if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
if ( eraseBack )
flags |= RDW_ERASE;
// Get total size
void wxWindowMSW::DoGetSize(int *x, int *y) const
{
- wxExtraWindowData* extraData = (wxExtraWindowData*) m_windowReserved;
- if (extraData && extraData->m_deferring && GetParent() && GetParent()->m_hDWP)
- {
- *x = extraData->m_size.x;
- *y = extraData->m_size.y;
- return;
- }
-
RECT rect = wxGetWindowRect(GetHwnd());
if ( x )
// Get size *available for subwindows* i.e. excluding menu bar etc.
void wxWindowMSW::DoGetClientSize(int *x, int *y) const
{
- wxExtraWindowData* extraData = (wxExtraWindowData*) m_windowReserved;
- if (extraData && extraData->m_deferring && GetParent() && GetParent()->m_hDWP)
- {
- *x = extraData->m_pos.x;
- *y = extraData->m_pos.y;
- return;
- }
-
RECT rect = wxGetClientRect(GetHwnd());
if ( x )
HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
#else
HDWP hdwp = 0;
-#endif
+#endif
wxMoveWindowDeferred(hdwp, this, GetHwnd(), x, y, width, height);
- if ( hdwp )
- {
- // Store the size so we can report it accurately
- wxExtraWindowData* extraData = (wxExtraWindowData*) m_windowReserved;
- if (!extraData)
- {
- extraData = new wxExtraWindowData;
- m_windowReserved = (void*) extraData;
- }
- extraData->m_pos = wxPoint(x, y);
- extraData->m_size = wxSize(width, height);
- extraData->m_deferring = true;
-
+#if USE_DEFERRED_SIZING
+ if ( parent )
// hdwp must be updated as it may have been changed
parent->m_hDWP = (WXHANDLE)hdwp;
- }
+#endif
}
// set the size of the window: if the dimensions are positive, just use them,
{
// get the current size and position...
int currentX, currentY;
+ int currentW, currentH;
+
+#if USE_DEFER_BUG_WORKAROUND
+ currentX = m_pendingPosition.x;
+ if (currentX == wxDefaultCoord)
+ GetPosition(¤tX, NULL);
+
+ currentY = m_pendingPosition.y;
+ if (currentY == wxDefaultCoord)
+ GetPosition(NULL, ¤tY);
+
+ currentW = m_pendingSize.x;
+ if (currentW == wxDefaultCoord)
+ GetSize(¤tW, NULL);
+
+ currentH = m_pendingSize.y;
+ if (currentH == wxDefaultCoord)
+ GetSize(NULL, ¤tH);
+#else
GetPosition(¤tX, ¤tY);
- int currentW,currentH;
GetSize(¤tW, ¤tH);
+#endif
// ... and don't do anything (avoiding flicker) if it's already ok
if ( x == currentX && y == currentY &&
}
}
+#if USE_DEFER_BUG_WORKAROUND
+ // We don't actually use the hdwp here, but we need to know whether to
+ // save the pending dimensions or not. This isn't done in DoMoveWindow
+ // (where the hdwp is used) because some controls have thier own
+ // DoMoveWindow so it is easier to catch it here.
+ HDWP hdwp = GetParent() && !IsTopLevel() ? (HDWP)GetParent()->m_hDWP : NULL;
+ if (hdwp)
+ {
+ m_pendingPosition = wxPoint(x, y);
+ m_pendingSize = wxSize(width, height);
+ }
+ else
+ {
+ m_pendingPosition = wxDefaultPosition;
+ m_pendingSize = wxDefaultSize;
+ }
+#endif
+
DoMoveWindow(x, y, width, height);
}
SIZE sizeRect;
TEXTMETRIC tm;
- GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+ ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect);
GetTextMetrics(hdc, &tm);
if ( x )
break;
#endif // !__WXWINCE__
+ case WM_WINDOWPOSCHANGED:
+ {
+ WINDOWPOS *lpPos = (WINDOWPOS *)lParam;
+
+ if ( !(lpPos->flags & SWP_NOSIZE) )
+ {
+ RECT rc;
+ ::GetClientRect(GetHwnd(), &rc);
+
+ AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc));
+ AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x, lpPos->y,
+ lpPos->cx, lpPos->cy));
+ AutoHRGN hrgn(::CreateRectRgn(0, 0, 0, 0));
+
+ // we need to invalidate any new exposed areas here
+ // to force them to repaint
+ if ( ::CombineRgn(hrgn, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION )
+ ::InvalidateRgn(GetHwnd(), hrgn, TRUE);
+ if ( ::CombineRgn(hrgn, hrgnClient, hrgnNew, RGN_DIFF) != NULLREGION )
+ ::InvalidateRgn(GetHwnd(), hrgn, TRUE);
+
+ }
+ }
+ break;
+
#if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
case WM_ACTIVATEAPP:
// This implicitly sends a wxEVT_ACTIVATE_APP event
if ( !::GetCursorPosWinCE(&pt))
#else
if ( !::GetCursorPos(&pt) )
-#endif
+#endif
{
wxLogLastError(wxT("GetCursorPos"));
}
// we want to avoid Windows' "help" and for this we need to have a
// reference bitmap which can tell us what the RGB values change
// to.
+ wxLogNull logNo; // suppress error if we couldn't load the bitmap
wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
if ( stdColourBitmap.Ok() )
{
//
// also note that in this case lParam == PRF_CLIENT but we're
// clearly expected to paint the background and nothing else!
+
+ if ( IsTopLevel() || InheritsBackgroundColour() )
+ return false;
+
for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
{
if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
{
- // when we resize this window, its children are probably going to be
- // repositioned as well, prepare to use DeferWindowPos() for them
#if USE_DEFERRED_SIZING
// when we resize this window, its children are probably going to be
// repositioned as well, prepare to use DeferWindowPos() for them
numChildren ++;
}
- // Protect against valid m_hDWP being overwritten
+ // Protect against valid m_hDWP being overwritten
bool useDefer = false;
if ( numChildren > 1 )
{
if (!m_hDWP)
- {
+ {
m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
if ( !m_hDWP )
{
// may have depending on what the users EVT_SIZE handler does...)
HDWP hDWP = (HDWP)m_hDWP;
m_hDWP = NULL;
-
+
// do put all child controls in place at once
if ( !::EndDeferWindowPos(hDWP) )
{
wxLogLastError(_T("EndDeferWindowPos"));
}
- // Seems to be a bug in DeferWindowPos such that going from (a) to (b) to (a)
- // doesn't work (omits last position/size). So check if there's a disparity,
- // and correct.
+#if USE_DEFER_BUG_WORKAROUND
+ // Reset our children's pending pos/size values.
for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
node;
node = node->GetNext() )
{
wxWindow *child = node->GetData();
- wxExtraWindowData* extraData = (wxExtraWindowData*) child->m_windowReserved;
- if (extraData && extraData->m_deferring)
- {
- wxPoint pos = child->GetPosition();
-
- if (extraData->m_pos != pos)
- child->Move(extraData->m_pos);
-
- extraData->m_deferring = false;
- }
+ child->m_pendingPosition = wxDefaultPosition;
+ child->m_pendingSize = wxDefaultSize;
}
+#endif
}
#endif
#endif // wxUSE_HOTKEY
// Moves a window by deferred method or normal method
-bool wxMoveWindowDeferred(HDWP& hdwp, wxWindow* win, HWND hWnd, int x, int y, int width, int height)
+bool wxMoveWindowDeferred(HDWP& hdwp, wxWindowBase* win, HWND hWnd, int x, int y, int width, int height)
{
if ( hdwp )
{