]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
clean up wxEvtHandler::m_eventsLocker weirdness: there is no need to allocate it...
[wxWidgets.git] / src / msw / window.cpp
index 99bb37b398eac7a24c7f5ee99c11676516df9fa1..2e534220387f94f1c2741797e2b4bd8b9ac4e7a4 100644 (file)
@@ -79,6 +79,7 @@
 #endif
 
 #include "wx/msw/private.h"
+#include "wx/msw/dcclient.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/tooltip.h"
     #define ETS_ASSIST          7
 #endif
 
+// define the constants used by AnimateWindow() if our SDK doesn't have them
+#ifndef AW_CENTER
+    #define AW_HOR_POSITIVE 0x00000001
+    #define AW_HOR_NEGATIVE 0x00000002
+    #define AW_VER_POSITIVE 0x00000004
+    #define AW_VER_NEGATIVE 0x00000008
+    #define AW_CENTER       0x00000010
+    #define AW_HIDE         0x00010000
+    #define AW_ACTIVATE     0x00020000
+    #define AW_SLIDE        0x00040000
+    #define AW_BLEND        0x00080000
+#endif
+
 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE) && wxUSE_DYNLIB_CLASS
     #define HAVE_TRACKMOUSEEVENT
 #endif // everything needed for TrackMouseEvent()
 // ---------------------------------------------------------------------------
 
 #if wxUSE_MENUS_NATIVE
-wxMenu *wxCurrentPopupMenu = NULL;
-#endif // wxUSE_MENUS_NATIVE
+extern wxMenu *wxCurrentPopupMenu;
+#endif
 
 #ifdef __WXWINCE__
 extern       wxChar *wxCanvasClassName;
@@ -510,8 +524,6 @@ void wxWindowMSW::Init()
     m_mouseInWindow = false;
     m_lastKeydownProcessed = false;
 
-    m_frozenness = 0;
-
     m_hWnd = 0;
     m_hDWP = 0;
 
@@ -701,6 +713,110 @@ bool wxWindowMSW::Show(bool show)
     return true;
 }
 
+bool
+wxWindowMSW::MSWShowWithEffect(bool show,
+                               wxShowEffect effect,
+                               unsigned timeout,
+                               wxDirection dir)
+{
+    typedef BOOL (WINAPI *AnimateWindow_t)(HWND, DWORD, DWORD);
+
+    static AnimateWindow_t s_pfnAnimateWindow = NULL;
+    static bool s_initDone = false;
+    if ( !s_initDone )
+    {
+        wxLogNull noLog;
+
+        wxDynamicLibrary dllUser32(_T("user32.dll"), wxDL_VERBATIM);
+        wxDL_INIT_FUNC(s_pfn, AnimateWindow, dllUser32);
+
+        s_initDone = true;
+
+        // notice that it's ok to unload user32.dll here as it won't be really
+        // unloaded, being still in use because we link to it statically too
+    }
+
+    if ( !s_pfnAnimateWindow )
+        return Show(show);
+
+    // prepare to use AnimateWindow()
+
+    if ( !timeout )
+        timeout = 200; // this is the default animation timeout, per MSDN
+
+    DWORD dwFlags = show ? 0 : AW_HIDE;
+    bool needsDir = false;
+    switch ( effect )
+    {
+        case wxSHOW_EFFECT_ROLL:
+            needsDir = true;
+            break;
+
+        case wxSHOW_EFFECT_SLIDE:
+            needsDir = true;
+            dwFlags |= AW_SLIDE;
+            break;
+
+        case wxSHOW_EFFECT_BLEND:
+            dwFlags |= AW_BLEND;
+            break;
+
+        case wxSHOW_EFFECT_EXPAND:
+            dwFlags |= AW_CENTER;
+            break;
+
+
+        case wxSHOW_EFFECT_MAX:
+            wxFAIL_MSG( _T("invalid window show effect") );
+            return false;
+
+        default:
+            wxFAIL_MSG( _T("unknown window show effect") );
+            return false;
+    }
+
+    if ( needsDir )
+    {
+        switch ( dir )
+        {
+            case wxTOP:
+                dwFlags |= AW_VER_NEGATIVE;
+                break;
+
+            case wxBOTTOM:
+                dwFlags |= AW_VER_POSITIVE;
+                break;
+
+            case wxLEFT:
+                dwFlags |= AW_HOR_NEGATIVE;
+                break;
+
+            case wxRIGHT:
+                dwFlags |= AW_HOR_POSITIVE;
+                break;
+
+            default:
+                wxFAIL_MSG( _T("unknown window effect direction") );
+                return false;
+        }
+    }
+    else // animation effect which doesn't need the direction
+    {
+        wxASSERT_MSG( dir == wxBOTTOM,
+                        _T("non-default direction used unnecessarily") );
+    }
+
+
+    if ( !(*s_pfnAnimateWindow)(GetHwnd(), timeout, dwFlags) )
+    {
+        wxLogLastError(_T("AnimateWindow"));
+
+        return false;
+    }
+
+    return true;
+}
+
 // Raise the window to the top of the Z order
 void wxWindowMSW::Raise()
 {
@@ -1094,7 +1210,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
 
     // we're officially created now, send the event
     wxWindowCreateEvent event((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(event);
+    (void)HandleWindowEvent(event);
 }
 
 void wxWindowMSW::UnsubclassWin()
@@ -1286,32 +1402,43 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
     }
 }
 
-wxBorder wxWindowMSW::GetDefaultBorder() const
+wxBorder wxWindowMSW::GetDefaultBorderForControl() const
 {
-       return GetDefaultBorderForControl();
+    return wxBORDER_THEME;
 }
 
-wxBorder wxWindowMSW::GetDefaultBorderForControl() const
+wxBorder wxWindowMSW::GetDefaultBorder() const
 {
-    // we want to automatically give controls a sunken style (confusingly,
-    // it may not really mean sunken at all as we map it to WS_EX_CLIENTEDGE
-    // which is not sunken at all under Windows XP -- rather, just the default)
+    return wxWindowBase::GetDefaultBorder();
+}
 
+// Translate wxBORDER_THEME (and other border styles if necessary) to the value
+// that makes most sense for this Windows environment
+wxBorder wxWindowMSW::TranslateBorder(wxBorder border) const
+{
 #if defined(__POCKETPC__) || defined(__SMARTPHONE__)
-    return wxBORDER_SIMPLE;
+    if (border == wxBORDER_THEME || border == wxBORDER_SUNKEN || border == wxBORDER_SIMPLE)
+        return wxBORDER_SIMPLE;
+    else
+        return wxBORDER_NONE;
 #else
 #if wxUSE_UXTHEME
-    if (CanApplyThemeBorder())
+    if (border == wxBORDER_THEME)
     {
-        wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
-        if (theme)
-            return wxBORDER_THEME;
+        if (CanApplyThemeBorder())
+        {
+            wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
+            if (theme)
+                return wxBORDER_THEME;
+        }
+        return wxBORDER_SUNKEN;
     }
 #endif
-    return wxBORDER_SUNKEN;
+    return border;
 #endif
 }
 
+
 WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 {
     // translate common wxWidgets styles to Windows ones
@@ -1341,7 +1468,10 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     if ( flags & wxHSCROLL )
         style |= WS_HSCROLL;
 
-    const wxBorder border = GetBorder(flags);
+    const wxBorder border = TranslateBorder(GetBorder(flags));
+
+    // After translation, border is now optimized for the specific version of Windows
+    // and theme engine presence.
 
     // WS_BORDER is only required for wxBORDER_SIMPLE
     if ( border == wxBORDER_SIMPLE )
@@ -1359,11 +1489,14 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 
         switch ( border )
         {
-            case wxBORDER_DEFAULT: // also wxBORDER_THEME
-                break;
+            default:
+            case wxBORDER_DEFAULT:
+                wxFAIL_MSG( _T("unknown border style") );
+                // fall through
 
             case wxBORDER_NONE:
             case wxBORDER_SIMPLE:
+            case wxBORDER_THEME:
                 break;
 
             case wxBORDER_STATIC:
@@ -1379,10 +1512,6 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
                 style &= ~WS_BORDER;
                 break;
 
-            default:
-                wxFAIL_MSG( _T("unknown border style") );
-                break;
-
 //            case wxBORDER_DOUBLE:
 //                *exstyle |= WS_EX_DLGMODALFRAME;
 //                break;
@@ -1443,7 +1572,7 @@ void wxWindowMSW::OnInternalIdle()
     }
 #endif // !HAVE_TRACKMOUSEEVENT
 
-    if (wxUpdateUIEvent::CanUpdate(this))
+    if (wxUpdateUIEvent::CanUpdate(this) && IsShown())
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
@@ -1475,29 +1604,21 @@ static inline void SendSetRedraw(HWND hwnd, bool on)
 #endif
 }
 
-void wxWindowMSW::Freeze()
+void wxWindowMSW::DoFreeze()
 {
-    if ( !m_frozenness++ )
-    {
-        if ( IsShown() )
-            SendSetRedraw(GetHwnd(), false);
-    }
+    if ( IsShown() )
+        SendSetRedraw(GetHwnd(), false);
 }
 
-void wxWindowMSW::Thaw()
+void wxWindowMSW::DoThaw()
 {
-    wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
-
-    if ( --m_frozenness == 0 )
+    if ( IsShown() )
     {
-        if ( IsShown() )
-        {
-            SendSetRedraw(GetHwnd(), true);
+        SendSetRedraw(GetHwnd(), true);
 
-            // we need to refresh everything or otherwise the invalidated area
-            // is not going to be repainted
-            Refresh();
-        }
+        // we need to refresh everything or otherwise the invalidated area
+        // is not going to be repainted
+        Refresh();
     }
 }
 
@@ -2088,7 +2209,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     point.x = x;
     point.y = y;
     ::ClientToScreen(hWnd, &point);
-    wxCurrentPopupMenu = menu;
 #if defined(__WXWINCE__)
     static const UINT flags = 0;
 #else // !__WXWINCE__
@@ -2117,8 +2237,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     // for example) and so we do need to process the event immediately
     wxYieldForCommandsOnly();
 
-    wxCurrentPopupMenu = NULL;
-
     menu->SetInvokingWindow(NULL);
 
     return true;
@@ -2220,13 +2338,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                 case VK_RETURN:
                     {
-                        if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown )
-                        {
-                            // control wants to process Enter itself, don't
-                            // call IsDialogMessage() which would consume it
-                            return false;
-                        }
-
 #if wxUSE_BUTTON
                         // currently active button should get enter press even
                         // if there is a default button elsewhere so check if
@@ -2248,9 +2359,49 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         }
                         else // not a button itself, do we have default button?
                         {
-                            wxTopLevelWindow *
-                                tlw = wxDynamicCast(wxGetTopLevelParent(this),
-                                                    wxTopLevelWindow);
+                            // check if this window or any of its ancestors
+                            // wants the message for itself (we always reserve
+                            // Ctrl-Enter for dialog navigation though)
+                            wxWindow *win = this;
+                            if ( !bCtrlDown )
+                            {
+                                // this will contain the dialog code of this
+                                // window and all of its parent windows in turn
+                                LONG lDlgCode2 = lDlgCode;
+
+                                while ( win )
+                                {
+                                    if ( lDlgCode2 & DLGC_WANTMESSAGE )
+                                    {
+                                        // as it wants to process Enter itself,
+                                        // don't call IsDialogMessage() which
+                                        // would consume it
+                                        return false;
+                                    }
+
+                                    // don't propagate keyboard messages beyond
+                                    // the first top level window parent
+                                    if ( win->IsTopLevel() )
+                                        break;
+
+                                    win = win->GetParent();
+
+                                    lDlgCode2 = ::SendMessage
+                                                  (
+                                                    GetHwndOf(win),
+                                                    WM_GETDLGCODE,
+                                                    0,
+                                                    0
+                                                  );
+                                }
+                            }
+                            else // bCtrlDown
+                            {
+                                win = wxGetTopLevelParent(win);
+                            }
+
+                            wxTopLevelWindow * const
+                                tlw = wxDynamicCast(win, wxTopLevelWindow);
                             if ( tlw )
                             {
                                 btn = wxDynamicCast(tlw->GetDefaultItem(),
@@ -2270,7 +2421,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         // map Enter presses into button presses on PDAs
                         wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN);
                         event.SetEventObject(this);
-                        if ( GetEventHandler()->ProcessEvent(event) )
+                        if ( HandleWindowEvent(event) )
                             return true;
 #endif // __WXWINCE__
                     }
@@ -2288,7 +2439,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 event.SetFromTab(bFromTab);
                 event.SetEventObject(this);
 
-                if ( GetEventHandler()->ProcessEvent(event) )
+                if ( HandleWindowEvent(event) )
                 {
                     // as we don't call IsDialogMessage(), which would take of
                     // this by default, we need to manually send this message
@@ -2781,7 +2932,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                         wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
 
                         evtCtx.SetEventObject(this);
-                        if (GetEventHandler()->ProcessEvent(evtCtx))
+                        if (HandleWindowEvent(evtCtx))
                         {
                             processed = true;
                             return true;
@@ -3169,14 +3320,14 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                 );
 
                     helpEvent.SetEventObject(this);
-                    GetEventHandler()->ProcessEvent(helpEvent);
+                    HandleWindowEvent(helpEvent);
 #ifndef __WXWINCE__
                 }
                 else if ( info->iContextType == HELPINFO_MENUITEM )
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
-                    GetEventHandler()->ProcessEvent(helpEvent);
+                    HandleWindowEvent(helpEvent);
 
                 }
                 else // unknown help event?
@@ -3209,7 +3360,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     win = this;
 
                 evtCtx.SetEventObject(win);
-                processed = win->GetEventHandler()->ProcessEvent(evtCtx);
+                processed = win->HandleWindowEvent(evtCtx);
             }
             break;
 #endif
@@ -3245,7 +3396,8 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
         case WM_NCCALCSIZE:
             {
                 wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
-                if (theme && GetBorder() == wxBORDER_THEME)
+                const wxBorder border = TranslateBorder(GetBorder());
+                if (theme && border == wxBORDER_THEME)
                 {
                     // first ask the widget to calculate the border size
                     rc.result = MSWDefWindowProc(message, wParam, lParam);
@@ -3263,12 +3415,13 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     {
                         rect = *((RECT*)lParam);
                     }
-                    wxUxThemeHandle hTheme(this, L"EDIT");
+                    wxUxThemeHandle hTheme((wxWindow *)this, L"EDIT");
                     RECT rcClient = { 0, 0, 0, 0 };
-                    wxClientDC dc(this);
+                    wxClientDC dc((wxWindow *)this);
+                    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
 
                     if (theme->GetThemeBackgroundContentRect(
-                            hTheme, GetHdcOf(dc), EP_EDITTEXT, ETS_NORMAL,
+                            hTheme, GetHdcOf(*impl), EP_EDITTEXT, ETS_NORMAL,
                             &rect, &rcClient) == S_OK)
                     {
                         InflateRect(&rcClient, -1, -1);
@@ -3285,14 +3438,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
         case WM_NCPAINT:
             {
                 wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
-                if (theme && GetBorder() == wxBORDER_THEME)
+                const wxBorder border = TranslateBorder(GetBorder());
+                if (theme && border == wxBORDER_THEME)
                 {
                     // first ask the widget to paint its non-client area, such as scrollbars, etc.
                     rc.result = MSWDefWindowProc(message, wParam, lParam);
                     processed = true;
 
-                    wxUxThemeHandle hTheme(this, L"EDIT");
-                    wxWindowDC dc(this);
+                    wxUxThemeHandle hTheme((wxWindow *)this, L"EDIT");
+                    wxWindowDC dc((wxWindow *)this);
+                    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
 
                     // Clip the DC so that you only draw on the non-client area
                     RECT rcBorder;
@@ -3300,16 +3455,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 
                     RECT rcClient;
                     theme->GetThemeBackgroundContentRect(
-                        hTheme, GetHdcOf(dc), EP_EDITTEXT, ETS_NORMAL, &rcBorder, &rcClient);
+                        hTheme, GetHdcOf(*impl), EP_EDITTEXT, ETS_NORMAL, &rcBorder, &rcClient);
                     InflateRect(&rcClient, -1, -1);
 
-                    ::ExcludeClipRect(GetHdcOf(dc), rcClient.left, rcClient.top,
+                    ::ExcludeClipRect(GetHdcOf(*impl), rcClient.left, rcClient.top,
                                       rcClient.right, rcClient.bottom);
 
                     // Make sure the background is in a proper state
                     if (theme->IsThemeBackgroundPartiallyTransparent(hTheme, EP_EDITTEXT, ETS_NORMAL))
                     {
-                        theme->DrawThemeParentBackground(GetHwnd(), GetHdcOf(dc), &rcBorder);
+                        theme->DrawThemeParentBackground(GetHwnd(), GetHdcOf(*impl), &rcBorder);
                     }
 
                     // Draw the border
@@ -3321,7 +3476,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     //    nState = ETS_READONLY;
                     else
                         nState = ETS_NORMAL;
-                    theme->DrawThemeBackground(hTheme, GetHdcOf(dc), EP_EDITTEXT, nState, &rcBorder, NULL);
+                    theme->DrawThemeBackground(hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, NULL);
                 }
             }
             break;
@@ -3800,7 +3955,7 @@ bool wxWindowMSW::HandleActivate(int state,
                           m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
@@ -3815,7 +3970,7 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
     // notify the parent keeping track of focus for the kbd navigation
     // purposes that we got it
     wxChildFocusEvent eventFocus((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(eventFocus);
+    (void)HandleWindowEvent(eventFocus);
 
 #if wxUSE_CARET
     // Deal with caret
@@ -3840,7 +3995,7 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
     // wxFindWinFromHandle() may return NULL, it is ok
     event.SetWindow(wxFindWinFromHandle(hwnd));
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
@@ -3876,7 +4031,7 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     // wxFindWinFromHandle() may return NULL, it is ok
     event.SetWindow(wxFindWinFromHandle(hwnd));
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 // ---------------------------------------------------------------------------
@@ -3902,7 +4057,7 @@ bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
     wxShowEvent event(GetId(), show);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
@@ -3910,7 +4065,7 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
     wxInitDialogEvent event(GetId());
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
@@ -3950,7 +4105,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
     event.m_pos.x = dropPoint.x;
     event.m_pos.y = dropPoint.y;
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 #endif
 }
 
@@ -3993,7 +4148,7 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
         ScreenToClient(&x, &y);
         wxSetCursorEvent event(x, y);
 
-        bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
+        bool processedEvtSetCursor = HandleWindowEvent(event);
         if ( processedEvtSetCursor && event.HasCursor() )
         {
             hcursor = GetHcursorOf(event.GetCursor());
@@ -4089,7 +4244,7 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
     // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events?
 
     wxPowerEvent event(evtType);
-    if ( !GetEventHandler()->ProcessEvent(event) )
+    if ( !HandleWindowEvent(event) )
         return false;
 
     *vetoed = event.IsVetoed();
@@ -4239,7 +4394,7 @@ bool wxWindowMSW::HandleSysColorChange()
     wxSysColourChangedEvent event;
     event.SetEventObject(this);
 
-    (void)GetEventHandler()->ProcessEvent(event);
+    (void)HandleWindowEvent(event);
 
     // always let the system carry on the default processing to allow the
     // native controls to react to the colours update
@@ -4251,7 +4406,7 @@ bool wxWindowMSW::HandleDisplayChange()
     wxDisplayChangedEvent event;
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 #ifndef __WXMICROWIN__
@@ -4315,7 +4470,7 @@ bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
     event.SetEventObject(this);
     event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
@@ -4327,7 +4482,7 @@ bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
     wxWindow *win = wxFindWinFromHandle(hWndGainedCapture);
     wxMouseCaptureChangedEvent event(GetId(), win);
     event.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam)
@@ -4382,7 +4537,7 @@ bool wxWindowMSW::HandleQueryNewPalette()
     wxQueryNewPaletteEvent event(GetId());
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event) && event.GetPaletteRealized();
+    return HandleWindowEvent(event) && event.GetPaletteRealized();
 }
 
 // Responds to colour changes: passes event on to children.
@@ -4498,14 +4653,18 @@ bool wxWindowMSW::HandlePaint()
     wxPaintEvent event(m_windowId);
     event.SetEventObject(this);
 
-    bool processed = GetEventHandler()->ProcessEvent(event);
+    bool processed = HandleWindowEvent(event);
 
     // note that we must generate NC event after the normal one as otherwise
     // BeginPaint() will happily overwrite our decorations with the background
     // colour
     wxNcPaintEvent eventNc(m_windowId);
     eventNc.SetEventObject(this);
-    GetEventHandler()->ProcessEvent(eventNc);
+    HandleWindowEvent(eventNc);
+
+    // don't keep an HRGN we don't need any longer (GetUpdateRegion() can only
+    // be called from inside the event handlers called above)
+    m_updateRegion.Clear();
 
     return processed;
 }
@@ -4516,7 +4675,7 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 #ifdef __WXUNIVERSAL__
     event.Skip();
 #else
-    HDC hDC = (HDC) wxPaintDC::FindDCInCache((wxWindow*) event.GetEventObject());
+    HDC hDC = (HDC) wxPaintDCImpl::FindDCInCache((wxWindow*) event.GetEventObject());
     if (hDC != 0)
     {
         MSWDefWindowProc(WM_PAINT, (WPARAM) hDC, 0);
@@ -4527,16 +4686,17 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 {
     wxDCTemp dc(hdc, GetClientSize());
+    wxDCTempImpl *impl = (wxDCTempImpl*) dc.GetImpl();
 
-    dc.SetHDC(hdc);
-    dc.SetWindow((wxWindow *)this);
+    impl->SetHDC(hdc);
+    impl->SetWindow((wxWindow *)this);
 
     wxEraseEvent event(m_windowId, &dc);
     event.SetEventObject(this);
-    bool rc = GetEventHandler()->ProcessEvent(event);
+    bool rc = HandleWindowEvent(event);
 
     // must be called manually as ~wxDC doesn't do anything for wxDCTemp
-    dc.SelectOldObjects(hdc);
+    impl->SelectOldObjects(hdc);
 
     return rc;
 }
@@ -4560,9 +4720,12 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
         return;
     }
 
+    wxDC *dc = event.GetDC();
+    if (!dc) return;
+    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl();
 
     // do default background painting
-    if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) )
+    if ( !DoEraseBackground(GetHdcOf(*impl)) )
     {
         // let the system paint the background
         event.Skip();
@@ -4672,7 +4835,7 @@ bool wxWindowMSW::HandleMinimize()
     wxIconizeEvent event(m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMaximize()
@@ -4680,7 +4843,7 @@ bool wxWindowMSW::HandleMaximize()
     wxMaximizeEvent event(m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMove(int x, int y)
@@ -4689,7 +4852,7 @@ bool wxWindowMSW::HandleMove(int x, int y)
     wxMoveEvent event(point, m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMoving(wxRect& rect)
@@ -4697,7 +4860,7 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
     wxMoveEvent event(rect, m_windowId);
     event.SetEventObject(this);
 
-    bool rc = GetEventHandler()->ProcessEvent(event);
+    bool rc = HandleWindowEvent(event);
     if (rc)
         rect = event.GetRect();
     return rc;
@@ -4705,20 +4868,20 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
 
 bool wxWindowMSW::HandleEnterSizeMove()
 {
-    wxMoveEvent event(wxPoint(), m_windowId);
+    wxMoveEvent event(wxPoint(0,0), m_windowId);
     event.SetEventType(wxEVT_MOVE_START);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleExitSizeMove()
 {
-    wxMoveEvent event(wxPoint(), m_windowId);
+    wxMoveEvent event(wxPoint(0,0), m_windowId);
     event.SetEventType(wxEVT_MOVE_END);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
@@ -4780,7 +4943,7 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
             wxSizeEvent event(GetSize(), m_windowId);
             event.SetEventObject(this);
 
-            processed = GetEventHandler()->ProcessEvent(event);
+            processed = HandleWindowEvent(event);
     }
 
 #if USE_DEFERRED_SIZING
@@ -4820,7 +4983,7 @@ bool wxWindowMSW::HandleSizing(wxRect& rect)
     wxSizeEvent event(rect, m_windowId);
     event.SetEventObject(this);
 
-    bool rc = GetEventHandler()->ProcessEvent(event);
+    bool rc = HandleWindowEvent(event);
     if (rc)
         rect = event.GetRect();
     return rc;
@@ -4872,8 +5035,11 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo))
 // command messages
 // ---------------------------------------------------------------------------
 
-bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
+bool wxWindowMSW::HandleCommand(WXWORD id_, WXWORD cmd, WXHWND control)
 {
+    // sign extend to int from short before comparing with the other int ids
+    int id = (signed short)id_;
+
 #if wxUSE_MENUS_NATIVE
     if ( !cmd && wxCurrentPopupMenu )
     {
@@ -4896,8 +5062,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
     // try the id
     if ( !win )
     {
-        // must cast to a signed type before comparing with other ids!
-        win = FindItem((signed short)id);
+        win = FindItem(id);
     }
 
     if ( win )
@@ -4919,7 +5084,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
         event.SetId(id);
         event.SetInt(id);
 
-        return GetEventHandler()->ProcessEvent(event);
+        return HandleWindowEvent(event);
     }
     else
     {
@@ -4967,7 +5132,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.m_aux1Down = (flags & MK_XBUTTON1) != 0;
     event.m_aux2Down = (flags & MK_XBUTTON2) != 0;
 #endif // wxHAS_XBUTTON
-    event.m_altDown = ::GetKeyState(VK_MENU) < 0;
+    event.m_altDown = ::wxIsAltDown();
 
 #ifndef __WXWINCE__
     event.SetTimestamp(::GetMessageTime());
@@ -5091,7 +5256,7 @@ bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
     wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]);
     InitMouseEvent(event, x, y, flags);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
@@ -5148,7 +5313,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
-            (void)GetEventHandler()->ProcessEvent(event);
+            (void)HandleWindowEvent(event);
         }
     }
 #ifdef HAVE_TRACKMOUSEEVENT
@@ -5217,7 +5382,7 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
     }
 
     event.m_linesPerAction = s_linesPerRotation;
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 
 #else // !wxUSE_MOUSEWHEEL
     wxUnusedVar(wParam);
@@ -5264,7 +5429,7 @@ void wxWindowMSW::GenerateMouseLeave()
     wxMouseEvent event(wxEVT_LEAVE_WINDOW);
     InitMouseEvent(event, pt.x, pt.y, state);
 
-    (void)GetEventHandler()->ProcessEvent(event);
+    (void)HandleWindowEvent(event);
 }
 
 // ---------------------------------------------------------------------------
@@ -5351,7 +5516,7 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
         event.m_altDown = false;
     }
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
@@ -5365,7 +5530,7 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
     }
 
     wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
@@ -5379,7 +5544,7 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
     }
 
     wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 #if wxUSE_MENUS
@@ -5417,7 +5582,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
                 //  menu creation code
                 wxMenuItem *item = (wxMenuItem*)mii.dwItemData;
 
-                const wxChar *p = wxStrchr(item->GetText().wx_str(), _T('&'));
+                const wxChar *p = wxStrchr(item->GetItemLabel().wx_str(), _T('&'));
                 while ( p++ )
                 {
                     if ( *p == _T('&') )
@@ -5462,7 +5627,7 @@ bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg )
 
     evt.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(evt);
+    return HandleWindowEvent(evt);
 }
 #endif // wxUSE_MENUS
 
@@ -5548,7 +5713,7 @@ bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags)
     event.SetPosition(wxPoint(x, y));
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 #else
     wxUnusedVar(msg);
     wxUnusedVar(x);
@@ -5635,7 +5800,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
         return false;
     }
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 // ----------------------------------------------------------------------------
@@ -5934,10 +6099,18 @@ WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual)
             break;
 
         default:
-            if ( isVirtual )
-                *isVirtual = false;
-            vk = (WXWORD)wxk;
-            break;
+            // check to see if its one of the OEM key codes.
+            BYTE vks = LOBYTE(VkKeyScan(wxk));
+            if ( vks != -1 )
+            {
+                vk = vks;
+            }
+            else
+            {
+                if ( isVirtual )
+                    *isVirtual = false;
+                vk = (WXWORD)wxk;
+            }
     }
 
     return vk;
@@ -6008,9 +6181,9 @@ wxMouseState wxGetMouseState()
     ms.SetAux2Down(wxIsKeyDown(VK_XBUTTON2));
 #endif // wxHAS_XBUTTON
 
-    ms.SetControlDown(wxIsKeyDown(VK_CONTROL));
-    ms.SetShiftDown(wxIsKeyDown(VK_SHIFT));
-    ms.SetAltDown(wxIsKeyDown(VK_MENU));
+    ms.SetControlDown(wxIsCtrlDown ());
+    ms.SetShiftDown  (wxIsShiftDown());
+    ms.SetAltDown    (wxIsAltDown  ());
 //    ms.SetMetaDown();
 
     return ms;
@@ -6774,7 +6947,7 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
     event.m_altDown = (win_modifiers & MOD_ALT) != 0;
     event.m_metaDown = (win_modifiers & MOD_WIN) != 0;
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 #endif // wxUSE_ACCEL