X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/54753c3d75cce7721667aef855fe30a0f90dcedd..777469ca936965a1ed15f70f3fe81f665833bf6a:/src/msw/window.cpp diff --git a/src/msw/window.cpp b/src/msw/window.cpp index c614dca82d..d16f4990ff 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -4,7 +4,6 @@ // Author: Julian Smart // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation // Created: 04/01/98 -// RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -3433,32 +3432,31 @@ wxWindowMSW::MSWHandleMessage(WXLRESULT *result, #if !defined(__WXWINCE__) case WM_CONTEXTMENU: { - // As with WM_HELP above, this message is propagated upwards - // the parent chain by DefWindowProc() itself, so we should - // always mark it as processed to prevent it from doing this - // as this would result in duplicate calls to event handlers. - processed = true; + // Ignore the events that are propagated from a child window by + // DefWindowProc(): as wxContextMenuEvent is already propagated + // upwards the window hierarchy by us, not doing this would + // result in duplicate events being sent. + WXHWND hWnd = (WXHWND)wParam; + if ( hWnd != m_hWnd ) + { + wxWindowMSW *win = FindItemByHWND(hWnd); + if ( win && IsDescendant(win) ) + { + // We had already generated wxContextMenuEvent when we + // got WM_CONTEXTMENU for that window. + processed = true; + break; + } + } // we don't convert from screen to client coordinates as // the event may be handled by a parent window wxPoint pt(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt); + evtCtx.SetEventObject(this); - // we could have got an event from our child, reflect it back - // to it if this is the case - wxWindowMSW *win = NULL; - WXHWND hWnd = (WXHWND)wParam; - if ( hWnd != m_hWnd ) - { - win = FindItemByHWND(hWnd); - } - - if ( !win ) - win = this; - - evtCtx.SetEventObject(win); - win->HandleWindowEvent(evtCtx); + processed = HandleWindowEvent(evtCtx); } break; #endif @@ -5109,11 +5107,9 @@ bool wxWindowMSW::HandleExitSizeMove() return HandleWindowEvent(event); } -bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) +bool wxWindowMSW::BeginRepositioningChildren() { #if wxUSE_DEFERRED_SIZING - // when we resize this window, its children are probably going to be - // repositioned as well, prepare to use DeferWindowPos() for them int numChildren = 0; for ( HWND child = ::GetWindow(GetHwndOf(this), GW_CHILD); child; @@ -5122,23 +5118,60 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) numChildren ++; } + // Nothing is gained by deferring the repositioning of a single child. + if ( numChildren < 2 ) + return false; + // Protect against valid m_hDWP being overwritten - bool useDefer = false; + if ( m_hDWP ) + return false; - if ( numChildren > 1 ) + m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren); + if ( !m_hDWP ) { - if (!m_hDWP) - { - m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren); - if ( !m_hDWP ) - { - wxLogLastError(wxT("BeginDeferWindowPos")); - } - if (m_hDWP) - useDefer = true; - } + wxLogLastError(wxT("BeginDeferWindowPos")); + return false; } + + // Return true to indicate that EndDeferWindowPos() should be called. + return true; #endif // wxUSE_DEFERRED_SIZING +} + +void wxWindowMSW::EndRepositioningChildren() +{ +#if wxUSE_DEFERRED_SIZING + wxASSERT_MSG( m_hDWP, wxS("Shouldn't be called") ); + + // reset m_hDWP to NULL so that child windows don't try to use our + // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't + // happen anyhow normally but who knows what weird flow of control we + // 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(wxT("EndDeferWindowPos")); + } + + // Reset our children's pending pos/size values. + for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); + node; + node = node->GetNext() ) + { + wxWindowMSW * const child = node->GetData(); + child->MSWEndDeferWindowPos(); + } +#endif // wxUSE_DEFERRED_SIZING +} + +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 + ChildrenRepositioningGuard repositionGuard(this); // update this window size bool processed = false; @@ -5171,34 +5204,6 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam) processed = HandleWindowEvent(event); } -#if wxUSE_DEFERRED_SIZING - // and finally change the positions of all child windows at once - if ( useDefer && m_hDWP ) - { - // reset m_hDWP to NULL so that child windows don't try to use our - // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't - // happen anyhow normally but who knows what weird flow of control we - // 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(wxT("EndDeferWindowPos")); - } - - // Reset our children's pending pos/size values. - for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - node; - node = node->GetNext() ) - { - wxWindowMSW * const child = node->GetData(); - child->MSWEndDeferWindowPos(); - } - } -#endif // wxUSE_DEFERRED_SIZING - return processed; } @@ -5600,7 +5605,20 @@ wxWindowMSW::HandleMouseWheel(wxMouseWheelAxis axis, } } + static int s_columnsPerRotation = -1; + if ( s_columnsPerRotation == -1 ) + { + if ( !::SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, + &s_columnsPerRotation, 0)) + { + // this setting is not supported on Windows 2000/XP, so use the value of 1 + // http://msdn.microsoft.com/en-us/library/ms997498.aspx + s_columnsPerRotation = 1; + } + } + event.m_linesPerAction = s_linesPerRotation; + event.m_columnsPerAction = s_columnsPerRotation; return HandleWindowEvent(event); #else // !wxUSE_MOUSEWHEEL