]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Make sure -DNO_GCC_PRAGMA is in wx-config output regardless of the reason.
[wxWidgets.git] / src / msw / window.cpp
index 72a51acc98be44059b0646e2c9a2328c600b353e..0597f96da22a822fe9f209fe42cf55a34f172a09 100644 (file)
@@ -436,10 +436,8 @@ void wxWindowMSW::Init()
     m_childrenDisabled = NULL;
     m_frozenness = 0;
 
-    // wxWnd
-    m_hMenu = 0;
-
     m_hWnd = 0;
+    m_hDWP = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
@@ -1145,11 +1143,16 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle()
     WXDWORD style = WS_CHILD;
 
-    if ( flags & wxCLIP_CHILDREN )
-        style |= WS_CLIPCHILDREN;
+    // using this flag results in very significant reduction in flicker,
+    // especially with controls inside the static boxes (as the interior of the
+    // box is not redrawn twice)
+    style |= WS_CLIPCHILDREN;
+
+    // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially
+    // don't support overlapping windows and it only makes sense for them and,
+    // presumably, gives the system some extra work (to manage more clipping
+    // regions), so avoid it alltogether
 
-    if ( flags & wxCLIP_SIBLINGS )
-        style |= WS_CLIPSIBLINGS;
 
     if ( flags & wxVSCROLL )
         style |= WS_VSCROLL;
@@ -1240,6 +1243,7 @@ bool wxWindowMSW::IsMouseInWindow() const
 
 void wxWindowMSW::OnInternalIdle()
 {
+#ifdef __WXWINCE__
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
@@ -1247,42 +1251,10 @@ void wxWindowMSW::OnInternalIdle()
         // or doesn't have mouse capture
         if ( !IsMouseInWindow() )
         {
-            // Generate a LEAVE event
-            m_mouseInWindow = false;
-
-            // Unfortunately the mouse button and keyboard state may have
-            // changed by the time the OnInternalIdle function is called, so 'state'
-            // may be meaningless.
-            int state = 0;
-            if ( wxIsShiftDown() )
-                state |= MK_SHIFT;
-            if ( wxIsCtrlDown() )
-                state |= MK_CONTROL;
-            if ( GetKeyState( VK_LBUTTON ) )
-                state |= MK_LBUTTON;
-            if ( GetKeyState( VK_MBUTTON ) )
-                state |= MK_MBUTTON;
-            if ( GetKeyState( VK_RBUTTON ) )
-                state |= MK_RBUTTON;
-
-            POINT pt;
-            if ( !::GetCursorPos(&pt) )
-            {
-                wxLogLastError(_T("GetCursorPos"));
-            }
-
-            // we need to have client coordinates here for symmetry with
-            // wxEVT_ENTER_WINDOW
-            RECT rect = wxGetWindowRect(GetHwnd());
-            pt.x -= rect.left;
-            pt.y -= rect.top;
-
-            wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-            InitMouseEvent(event2, pt.x, pt.y, state);
-
-            (void)GetEventHandler()->ProcessEvent(event2);
+            GenerateMouseLeave();
         }
     }
+#endif // !__WXWINCE__
 
     if (wxUpdateUIEvent::CanUpdate(this))
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
@@ -1526,9 +1498,31 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
         width = 0;
     if (height < 0)
         height = 0;
-    if ( !::MoveWindow(GetHwnd(), x, y, width, height, IsShown() /*Repaint?*/) )
+
+    // if our parent had prepared a defer window handle for us, use it
+    wxWindowMSW *parent = GetParent();
+    HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
+    if ( hdwp )
+    {
+        hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL,
+                                x, y, width, height,
+                                SWP_NOZORDER);
+        if ( !hdwp )
+        {
+            wxLogLastError(_T("DeferWindowPos"));
+        }
+
+        // hdwp must be updated as it may have been changed
+        parent->m_hDWP = (WXHANDLE)hdwp;
+    }
+
+    // otherwise (or if deferring failed) move the window in place immediately
+    if ( !hdwp )
     {
-        wxLogLastError(wxT("MoveWindow"));
+        if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+        {
+            wxLogLastError(wxT("MoveWindow"));
+        }
     }
 }
 
@@ -1871,8 +1865,21 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 case VK_ESCAPE:
                     {
 #if wxUSE_BUTTON
-                        wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),
-                                                      wxButton);
+                        wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),wxButton);
+
+                        // our own wxLogDialog should react to Esc
+                        // without Cancel button but this is a private class
+                        // so let's try recognize it by content
+    #if wxUSE_LOG_DIALOG
+                        if ( !btn &&
+                             wxDynamicCast(this,wxDialog) &&
+                             FindWindow(wxID_MORE) &&
+                             FindWindow(wxID_OK) &&
+                             !FindWindow(wxID_CANCEL) &&
+                             GetTitle().MakeLower().StartsWith(wxTheApp->GetAppName().c_str())
+                             )
+                            btn = wxDynamicCast(FindWindow(wxID_OK),wxButton);
+    #endif // wxUSE_LOG_DIALOG
                         if ( btn && btn->IsEnabled() )
                         {
                             // if we do have a cancel button, do press it
@@ -1913,7 +1920,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             bProcess = false;
                         }
                         // FIXME: this should be handled by
-                        //        wxNavigationKeyEvent handler and not here!!
+                        //        wxNavigationKeyEvent handler and not here!
                         else
                         {
 #if wxUSE_BUTTON
@@ -2222,11 +2229,59 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             (void)HandleDestroy();
             break;
 
+#ifndef __SMARTPHONE__ // or wxWinCE in general ?
+        case WM_WINDOWPOSCHANGING:
+            {
+                WINDOWPOS *wp = wx_reinterpret_cast(WINDOWPOS *, lParam);
+
+                if ( wp->flags & SWP_NOSIZE )
+                    break;
+
+                // when we resize this window, its children are probably going
+                // to be repositioned as well, prepare to use DeferWindowPos()
+                // for them
+                const int numChildren = GetChildren().GetCount();
+                if ( numChildren > 1 )
+                {
+                    m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
+                    if ( !m_hDWP )
+                    {
+                        wxLogLastError(_T("BeginDeferWindowPos"));
+                    }
+                }
+            }
+            break;
+
+        case WM_WINDOWPOSCHANGED:
+            // first let DefWindowProc() handle the message: it will generate
+            // WM_MOVE and WM_SIZE as needed
+            processed = MSWDefWindowProc(message, wParam, lParam) == 0;
+
+            // then change the positions of all child windows at once
+            if ( m_hDWP )
+            {
+                HDWP hDWP = (HDWP)m_hDWP;
+                m_hDWP = NULL;
+
+                // put all child controls in place at once now
+                if ( !::EndDeferWindowPos(hDWP) )
+                {
+                    wxLogLastError(_T("EndDeferWindowPos"));
+                }
+            }
+            break;
+#endif // __SMARTPHONE__
+
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
+
         case WM_MOVE:
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
 
 #if !defined(__WXWINCE__)
+        // TODO: move those in WM_WINDOWPOSCHANGING case above
         case WM_MOVING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2244,13 +2299,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
 
-        case WM_SIZE:
-            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
-            break;
-
-#if !defined(__WXWINCE__)
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2268,7 +2317,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
+#endif // !__WXWINCE__
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
@@ -2352,61 +2401,23 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                         wParam);
             break;
 
-            // Seems to be broken currently
-#if 0 // ndef __WXWINCE__
+#ifdef WM_MOUSELEAVE
         case WM_MOUSELEAVE:
-           {
-            wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
-
-            // only process this message if the mouse is not in the window,
-            // This can also check for children in composite windows.
-            // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
-            // if the mouse does not enter the window from it's child before
-            // leaving the scope of the window. ( perhaps this can be picked
-            // up in the OnIdle code as before, for this special case )
-            if ( /*IsComposite() && */ !IsMouseInWindow() )
             {
-                m_mouseInWindow = false;
-
-                // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
-                int state = 0;
-                if ( wxIsShiftDown() )
-                    state |= MK_SHIFT;
-                if ( wxIsCtrlDown() )
-                    state |= MK_CONTROL;
-                if ( GetKeyState( VK_LBUTTON ) )
-                    state |= MK_LBUTTON;
-                if ( GetKeyState( VK_MBUTTON ) )
-                    state |= MK_MBUTTON;
-                if ( GetKeyState( VK_RBUTTON ) )
-                    state |= MK_RBUTTON;
-
-                POINT pt;
-                if ( !::GetCursorPos(&pt) )
+                // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
+                if ( m_mouseInWindow )
                 {
-                    wxLogLastError(_T("GetCursorPos"));
+                    GenerateMouseLeave();
                 }
 
-                // we need to have client coordinates here for symmetry with
-                // wxEVT_ENTER_WINDOW
-                RECT rect = wxGetWindowRect(GetHwnd());
-                pt.x -= rect.left;
-                pt.y -= rect.top;
-
-                wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-                InitMouseEvent(event2, pt.x, pt.y, state);
-
-                (void)GetEventHandler()->ProcessEvent(event2);
+                // always pass processed back as false, this allows the window
+                // manager to process the message too.  This is needed to
+                // ensure windows XP themes work properly as the mouse moves
+                // over widgets like buttons.
+                processed = false;
             }
-            // always pass processed back as false, this allows the window
-            // manager to process the message too.  This is needed to ensure
-            // windows XP themes work properly as the mouse moves over widgets
-            // like buttons.
-            processed = false;
-           }
-           break;
-#endif
- // __WXWINCE__
+            break;
+#endif // WM_MOUSELEAVE
 
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
@@ -3463,7 +3474,7 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
 bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
 {
     wxShowEvent event(GetId(), show);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
 }
@@ -3471,7 +3482,7 @@ bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 {
     wxInitDialogEvent event(GetId());
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
 }
@@ -3506,7 +3517,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
     DragFinish (hFilesInfo);
 
     wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     POINT dropPoint;
     DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
@@ -3938,9 +3949,6 @@ extern wxCOLORMAP *wxGetStdColourMap()
 
 bool wxWindowMSW::HandlePaint()
 {
-//    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
-//        return false;
-
     HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
     if ( !hRegion )
         wxLogLastError(wxT("CreateRectRgn"));
@@ -3980,10 +3988,6 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 
 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 {
-    // Prevents flicker when dragging
-    if ( ::IsIconic(GetHwnd()) )
-        return true;
-
     wxDCTemp dc(hdc);
 
     dc.SetHDC(hdc);
@@ -4004,53 +4008,104 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
 void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 {
-    switch ( GetBackgroundStyle() )
+    // standard non top level controls (i.e. except the dialogs) always erase
+    // their background themselves in HandleCtlColor() or have some control-
+    // specific ways to set the colours (common controls)
+    if ( IsOfStandardClass() && !IsTopLevel() )
     {
-        default:
-            wxFAIL_MSG( _T("unexpected background style") );
-            // fall through
+        event.Skip();
+        return;
+    }
 
-        case wxBG_STYLE_CUSTOM:
-            // don't skip the event here, custom background means that the app
-            // is drawing it itself in its OnPaint()
-            break;
+    if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
+    {
+        // don't skip the event here, custom background means that the app
+        // is drawing it itself in its OnPaint(), so don't draw it at all
+        // now to avoid flicker
+        return;
+    }
 
-        case wxBG_STYLE_SYSTEM:
-#if wxUSE_NOTEBOOK && wxUSE_UXTHEME
-            // automatically apply the tab control theme background to any
-            // child panels to have the same look as the native property sheet
-            // dialogs
-            if ( !IsOfStandardClass() )
-            {
-                for ( wxWindow *win = this; win; win = win->GetParent() )
-                {
-                    wxNotebook *nbook = wxDynamicCast(win, wxNotebook);
-                    if ( nbook )
-                    {
-                        nbook->DoEraseBackground(event);
-                        return;
-                    }
-                }
-            }
-#endif // wxUSE_NOTEBOOK
-            event.Skip();
-            break;
 
-        case wxBG_STYLE_COLOUR:
-            // we have a fixed solid background colour, do use it
-            RECT rect;
-            ::GetClientRect(GetHwnd(), &rect);
+    // do default background painting
+    if ( !DoEraseBackground(*event.GetDC()) )
+    {
+        // let the system paint the background
+        event.Skip();
+    }
+}
+
+bool wxWindowMSW::DoEraseBackground(wxDC& dc)
+{
+    HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
+    if ( !hBrush )
+        return false;
+
+    RECT rc;
+    ::GetClientRect(GetHwnd(), &rc);
+    ::FillRect(GetHdcOf(dc), &rc, hBrush);
+
+    return true;
+}
+
+WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
+{
+    wxColour col = MSWGetBgColourForChild(child);
+    if ( col.Ok() )
+    {
+        // draw children with the same colour as the parent
+        wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
 
-            HBRUSH hBrush = ::CreateSolidBrush(
-                                    wxColourToPalRGB(GetBackgroundColour()));
-            if ( !hBrush )
-                wxLogLastError(wxT("CreateSolidBrush"));
+        return (WXHBRUSH)brush->GetResourceHandle();
+    }
 
-            HDC hdc = GetHdcOf((*event.GetDC()));
+    return 0;
+}
 
-            ::FillRect(hdc, &rect, hBrush);
-            ::DeleteObject(hBrush);
+wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child)
+{
+    if ( m_hasBgCol )
+    {
+        // our background colour applies to:
+        //  1. this window itself, always
+        //  2. all children unless the colour is "not inheritable"
+        //  3. immediate transparent children which should show the same
+        //     background as we do, but not for transparent grandchildren
+        //     which use the background of their immediate parent instead
+        if ( m_inheritBgCol ||
+                child == this ||
+                    (child->HasTransparentBackground() &&
+                        child->GetParent() == this) )
+        {
+            return GetBackgroundColour();
+        }
     }
+
+    return wxNullColour;
+}
+
+WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
+{
+    return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
+}
+
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
+{
+    for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() )
+    {
+        WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC);
+        if ( hBrush )
+            return hBrush;
+
+        // background is not inherited beyond the windows which have their own
+        // fixed background such as top level windows and notebooks and for
+        // windows for which a custom colour had been explicitly set with
+        // SetOwnBackgroundColour() and so shouldn't affect its children
+        if ( win->ProvidesBackground() ||
+                (win->m_hasBgCol && !win->m_inheritBgCol) )
+            break;
+    }
+
+    return 0;
 }
 
 // ---------------------------------------------------------------------------
@@ -4269,16 +4324,13 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.m_leftDown = (flags & MK_LBUTTON) != 0;
     event.m_middleDown = (flags & MK_MBUTTON) != 0;
     event.m_rightDown = (flags & MK_RBUTTON) != 0;
- //   event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
-    // Returns different negative values on WinME and WinNT,
-    // so simply test for negative value.
     event.m_altDown = ::GetKeyState(VK_MENU) < 0;
 
 #ifndef __WXWINCE__
     event.SetTimestamp(::GetMessageTime());
 #endif
 
-    event.m_eventObject = this;
+    event.SetEventObject(this);
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
@@ -4390,7 +4442,6 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         {
             // Generate an ENTER event
             m_mouseInWindow = true;
-#if _WIN32_WINNT >= 0x0400
 #ifndef __WXWINCE__
             TRACKMOUSEEVENT trackinfo;
 
@@ -4401,8 +4452,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             // appropriate TrackMouseEvent or emulate it ( win95 )
             // else we need _WIN32_WINNT >= 0x0400
             _TrackMouseEvent(&trackinfo);
-#endif
-#endif
+#endif // __WXWINCE__
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
@@ -4457,14 +4507,49 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
     event.m_linesPerAction = s_linesPerRotation;
     return GetEventHandler()->ProcessEvent(event);
 
-#else
-    (void) wParam;
-    (void) lParam;
+#else // !wxUSE_MOUSEWHEEL
+    wxUnusedVar(wParam);
+    wxUnusedVar(lParam);
 
     return false;
-#endif
+#endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL
 }
 
+void wxWindowMSW::GenerateMouseLeave()
+{
+    m_mouseInWindow = false;
+
+    int state = 0;
+    if ( wxIsShiftDown() )
+        state |= MK_SHIFT;
+    if ( wxIsCtrlDown() )
+        state |= MK_CONTROL;
+
+    // Only the high-order bit should be tested
+    if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
+        state |= MK_LBUTTON;
+    if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
+        state |= MK_MBUTTON;
+    if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
+        state |= MK_RBUTTON;
+
+    POINT pt;
+    if ( !::GetCursorPos(&pt) )
+    {
+        wxLogLastError(_T("GetCursorPos"));
+    }
+
+    // we need to have client coordinates here for symmetry with
+    // wxEVT_ENTER_WINDOW
+    RECT rect = wxGetWindowRect(GetHwnd());
+    pt.x -= rect.left;
+    pt.y -= rect.top;
+
+    wxMouseEvent event(wxEVT_LEAVE_WINDOW);
+    InitMouseEvent(event, pt.x, pt.y, state);
+
+    (void)GetEventHandler()->ProcessEvent(event);
+}
 
 // ---------------------------------------------------------------------------
 // keyboard handling
@@ -4483,7 +4568,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
     event.m_controlDown = wxIsCtrlDown();
     event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
 
-    event.m_eventObject = (wxWindow *)this; // const_cast
+    event.SetEventObject((wxWindow *)this); // const_cast
     event.m_keyCode = id;
 #if wxUSE_UNICODE
     event.m_uniChar = (wxChar) wParam;
@@ -4786,32 +4871,32 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
     wxScrollWinEvent event;
     event.SetPosition(pos);
     event.SetOrientation(orientation);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     switch ( wParam )
     {
     case SB_TOP:
-        event.m_eventType = wxEVT_SCROLLWIN_TOP;
+        event.SetEventType(wxEVT_SCROLLWIN_TOP);
         break;
 
     case SB_BOTTOM:
-        event.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
+        event.SetEventType(wxEVT_SCROLLWIN_BOTTOM);
         break;
 
     case SB_LINEUP:
-        event.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+        event.SetEventType(wxEVT_SCROLLWIN_LINEUP);
         break;
 
     case SB_LINEDOWN:
-        event.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+        event.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
         break;
 
     case SB_PAGEUP:
-        event.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+        event.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
         break;
 
     case SB_PAGEDOWN:
-        event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+        event.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
         break;
 
     case SB_THUMBPOSITION:
@@ -4837,9 +4922,9 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
             event.SetPosition(scrollInfo.nTrackPos);
         }
 
-        event.m_eventType = wParam == SB_THUMBPOSITION
+        event.SetEventType( wParam == SB_THUMBPOSITION
                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
-                                : wxEVT_SCROLLWIN_THUMBTRACK;
+                                : wxEVT_SCROLLWIN_THUMBTRACK );
         break;
 
     default:
@@ -4954,6 +5039,8 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
         case VK_NUMLOCK:    id = WXK_NUMLOCK; break;
         case VK_SCROLL:     id = WXK_SCROLL; break;
 
+        // the mapping for these keys may be incorrect on non-US keyboards so
+        // maybe we shouldn't map them to ASCII values at all
         case VK_OEM_1:      id = ';'; break;
         case VK_OEM_PLUS:   id = '+'; break;
         case VK_OEM_COMMA:  id = ','; break;
@@ -5070,7 +5157,7 @@ bool wxGetKeyState(wxKeyCode key)
     bool bVirtual;
 
 //High order with GetAsyncKeyState only available on WIN32
-#ifdef __WIN32__    
+#ifdef __WIN32__
     //If the requested key is a LED key, return
     //true if the led is pressed
     if (key == WXK_NUMLOCK ||
@@ -5078,12 +5165,12 @@ bool wxGetKeyState(wxKeyCode key)
         key == WXK_SCROLL)
     {
 #endif
-        //low order bit means LED is highlighted, 
+        //low order bit means LED is highlighted,
         //high order means key is down
         //Here, for compat with other ports we want both
         return GetKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) != 0;
 
-#ifdef __WIN32__    
+#ifdef __WIN32__
     }
     else
     {
@@ -5205,7 +5292,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
             if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
                 event.m_altDown = true;
 
-            event.m_eventObject = NULL;
+            event.SetEventObject(NULL);
             event.m_keyCode = id;
             event.m_shiftDown = wxIsShiftDown();
             event.m_controlDown = wxIsCtrlDown();
@@ -5815,7 +5902,11 @@ public:
     static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     {
         MSG *msg = (MSG*)lParam;
-        if ( msg->message == WM_NULL )
+
+        // only process the message if it is actually going to be removed from
+        // the message queue, this prevents that the same event from being
+        // processed multiple times if now someone just called PeekMessage()
+        if ( msg->message == WM_NULL && wParam == PM_REMOVE )
         {
             wxTheApp->ProcessPendingEvents();
         }