]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Eliminate a warning
[wxWidgets.git] / src / msw / window.cpp
index cc71fb2735d7853cdc081bfce8cce04c3b7b5798..5ddf3d7a8cc966f7d19b942d1868ff3d3d31d08b 100644 (file)
@@ -79,6 +79,7 @@
 #endif
 
 #include "wx/msw/private.h"
 #endif
 
 #include "wx/msw/private.h"
+#include "wx/msw/dcclient.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/tooltip.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/tooltip.h"
 #endif
 #endif
 
 #endif
 #endif
 
+#if wxUSE_UXTHEME
+    #include "wx/msw/uxtheme.h"
+    #define EP_EDITTEXT         1
+    #define ETS_NORMAL          1
+    #define ETS_HOT             2
+    #define ETS_SELECTED        3
+    #define ETS_DISABLED        4
+    #define ETS_FOCUSED         5
+    #define ETS_READONLY        6
+    #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 defined(TME_LEAVE) && defined(WM_MOUSELEAVE) && wxUSE_DYNLIB_CLASS
     #define HAVE_TRACKMOUSEEVENT
 #endif // everything needed for TrackMouseEvent()
     #define wxUSE_MOUSEEVENT_HACK 1
 #endif
 
     #define wxUSE_MOUSEEVENT_HACK 1
 #endif
 
+// not all compilers/platforms have X button related declarations (notably
+// Windows CE doesn't, and probably some old SDKs don't neither)
+#ifdef WM_XBUTTONDOWN
+    #define wxHAS_XBUTTON
+#endif
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
 
 #if wxUSE_MENUS_NATIVE
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
 
 #if wxUSE_MENUS_NATIVE
-wxMenu *wxCurrentPopupMenu = NULL;
-#endif // wxUSE_MENUS_NATIVE
+extern wxMenu *wxCurrentPopupMenu;
+#endif
 
 #ifdef __WXWINCE__
 extern       wxChar *wxCanvasClassName;
 
 #ifdef __WXWINCE__
 extern       wxChar *wxCanvasClassName;
@@ -180,6 +212,13 @@ WX_DECLARE_HASH_MAP(int, wxWindow::MSWMessageHandler,
 
 static MSWMessageHandlers gs_messageHandlers;
 
 
 static MSWMessageHandlers gs_messageHandlers;
 
+// hash containing all our windows, it uses HWND keys and wxWindow* values
+WX_DECLARE_HASH_MAP(HWND, wxWindow *,
+                    wxPointerHash, wxPointerEqual,
+                    WindowHandles);
+
+static WindowHandles gs_windowHandles;
+
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
@@ -195,7 +234,6 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
-wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
@@ -243,12 +281,11 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
      */
     while ( parent && !parent->IsTopLevel() )
     {
      */
     while ( parent && !parent->IsTopLevel() )
     {
-        LONG exStyle = ::GetWindowLong(GetHwndOf(parent), GWL_EXSTYLE);
+        LONG exStyle = wxGetWindowExStyle(parent);
         if ( !(exStyle & WS_EX_CONTROLPARENT) )
         {
             // force the parent to have this style
         if ( !(exStyle & WS_EX_CONTROLPARENT) )
         {
             // force the parent to have this style
-            ::SetWindowLong(GetHwndOf(parent), GWL_EXSTYLE,
-                            exStyle | WS_EX_CONTROLPARENT);
+            wxSetWindowExStyle(parent, exStyle | WS_EX_CONTROLPARENT);
         }
 
         parent = parent->GetParent();
         }
 
         parent = parent->GetParent();
@@ -492,8 +529,6 @@ void wxWindowMSW::Init()
     m_mouseInWindow = false;
     m_lastKeydownProcessed = false;
 
     m_mouseInWindow = false;
     m_lastKeydownProcessed = false;
 
-    m_frozenness = 0;
-
     m_hWnd = 0;
     m_hDWP = 0;
 
     m_hWnd = 0;
     m_hDWP = 0;
 
@@ -680,6 +715,116 @@ bool wxWindowMSW::Show(bool show)
         ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
     }
 
         ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
     }
 
+    if ( IsFrozen() )
+    {
+        // DoFreeze/DoThaw don't do anything if the window is not shown, so
+        // we have to call them from here now
+        if ( show )
+            DoFreeze();
+        else
+            DoThaw();
+    }
+
+    return true;
+}
+
+bool
+wxWindowMSW::MSWShowWithEffect(bool show,
+                               wxShowEffect effect,
+                               unsigned timeout)
+{
+    if ( !wxWindowBase::Show(show) )
+        return false;
+
+    typedef BOOL (WINAPI *AnimateWindow_t)(HWND, DWORD, DWORD);
+
+    static AnimateWindow_t s_pfnAnimateWindow = NULL;
+    static bool s_initDone = false;
+    if ( !s_initDone )
+    {
+        wxDynamicLibrary dllUser32(_T("user32.dll"), wxDL_VERBATIM | wxDL_QUIET);
+        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);
+
+    // Show() has a side effect of sending a WM_SIZE to the window, which helps
+    // ensuring that it's laid out correctly, but AnimateWindow() doesn't do
+    // this so send the event ourselves
+    SendSizeEvent();
+
+    // prepare to use AnimateWindow()
+
+    if ( !timeout )
+        timeout = 200; // this is the default animation timeout, per MSDN
+
+    DWORD dwFlags = show ? 0 : AW_HIDE;
+
+    switch ( effect )
+    {
+        case wxSHOW_EFFECT_ROLL_TO_LEFT:
+            dwFlags |= AW_HOR_NEGATIVE;
+            break;
+
+        case wxSHOW_EFFECT_ROLL_TO_RIGHT:
+            dwFlags |= AW_HOR_POSITIVE;
+            break;
+
+        case wxSHOW_EFFECT_ROLL_TO_TOP:
+            dwFlags |= AW_VER_NEGATIVE;
+            break;
+
+        case wxSHOW_EFFECT_ROLL_TO_BOTTOM:
+            dwFlags |= AW_VER_POSITIVE;
+            break;
+
+        case wxSHOW_EFFECT_SLIDE_TO_LEFT:
+            dwFlags |= AW_SLIDE | AW_HOR_NEGATIVE;
+            break;
+
+        case wxSHOW_EFFECT_SLIDE_TO_RIGHT:
+            dwFlags |= AW_SLIDE | AW_HOR_POSITIVE;
+            break;
+
+        case wxSHOW_EFFECT_SLIDE_TO_TOP:
+            dwFlags |= AW_SLIDE | AW_VER_NEGATIVE;
+            break;
+
+        case wxSHOW_EFFECT_SLIDE_TO_BOTTOM:
+            dwFlags |= AW_SLIDE | AW_VER_POSITIVE;
+            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 ( !(*s_pfnAnimateWindow)(GetHwnd(), timeout, dwFlags) )
+    {
+        wxLogLastError(_T("AnimateWindow"));
+
+        return false;
+    }
+
     return true;
 }
 
     return true;
 }
 
@@ -716,7 +861,7 @@ void wxWindowMSW::DoReleaseMouse()
 /* static */ wxWindow *wxWindowBase::GetCapture()
 {
     HWND hwnd = ::GetCapture();
 /* static */ wxWindow *wxWindowBase::GetCapture()
 {
     HWND hwnd = ::GetCapture();
-    return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
+    return hwnd ? wxFindWinFromHandle(hwnd) : NULL;
 }
 
 bool wxWindowMSW::SetFont(const wxFont& font)
 }
 
 bool wxWindowMSW::SetFont(const wxFont& font)
@@ -730,7 +875,11 @@ bool wxWindowMSW::SetFont(const wxFont& font)
     HWND hWnd = GetHwnd();
     if ( hWnd != 0 )
     {
     HWND hWnd = GetHwnd();
     if ( hWnd != 0 )
     {
-        WXHANDLE hFont = m_font.GetResourceHandle();
+        // note the use of GetFont() instead of m_font: our own font could have
+        // just been reset and in this case we need to change the font used by
+        // the native window to the default for this class, i.e. exactly what
+        // GetFont() returns
+        WXHANDLE hFont = GetFont().GetResourceHandle();
 
         wxASSERT_MSG( hFont, wxT("should have valid font") );
 
 
         wxASSERT_MSG( hFont, wxT("should have valid font") );
 
@@ -992,10 +1141,10 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir)
 #ifdef __WXWINCE__
     wxUnusedVar(dir);
 #else
 #ifdef __WXWINCE__
     wxUnusedVar(dir);
 #else
-    const HWND hwnd = GetHwnd();
-    wxCHECK_RET( hwnd, _T("layout direction must be set after window creation") );
+    wxCHECK_RET( GetHwnd(),
+                 _T("layout direction must be set after window creation") );
 
 
-    LONG styleOld = ::GetWindowLong(hwnd, GWL_EXSTYLE);
+    LONG styleOld = wxGetWindowExStyle(this);
 
     LONG styleNew = styleOld;
     switch ( dir )
 
     LONG styleNew = styleOld;
     switch ( dir )
@@ -1015,7 +1164,7 @@ void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir)
 
     if ( styleNew != styleOld )
     {
 
     if ( styleNew != styleOld )
     {
-        ::SetWindowLong(hwnd, GWL_EXSTYLE, styleNew);
+        wxSetWindowExStyle(this, styleNew);
     }
 #endif
 }
     }
 #endif
 }
@@ -1025,12 +1174,10 @@ wxLayoutDirection wxWindowMSW::GetLayoutDirection() const
 #ifdef __WXWINCE__
     return wxLayout_Default;
 #else
 #ifdef __WXWINCE__
     return wxLayout_Default;
 #else
-    const HWND hwnd = GetHwnd();
-    wxCHECK_MSG( hwnd, wxLayout_Default, _T("invalid window") );
+    wxCHECK_MSG( GetHwnd(), wxLayout_Default, _T("invalid window") );
 
 
-    return ::GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL
-                ? wxLayout_RightToLeft
-                : wxLayout_LeftToRight;
+    return wxHasWindowExStyle(this, WS_EX_LAYOUTRTL) ? wxLayout_RightToLeft
+                                                     : wxLayout_LeftToRight;
 #endif
 }
 
 #endif
 }
 
@@ -1055,6 +1202,8 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     HWND hwnd = (HWND)hWnd;
     wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in SubclassWin") );
 
     HWND hwnd = (HWND)hWnd;
     wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in SubclassWin") );
 
+    SetHWND(hWnd);
+
     wxAssociateWinWithHandle(hwnd, this);
 
     m_oldWndProc = (WXFARPROC)wxGetWindowProc((HWND)hWnd);
     wxAssociateWinWithHandle(hwnd, this);
 
     m_oldWndProc = (WXFARPROC)wxGetWindowProc((HWND)hWnd);
@@ -1076,7 +1225,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
 
     // we're officially created now, send the event
     wxWindowCreateEvent event((wxWindow *)this);
 
     // we're officially created now, send the event
     wxWindowCreateEvent event((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(event);
+    (void)HandleWindowEvent(event);
 }
 
 void wxWindowMSW::UnsubclassWin()
 }
 
 void wxWindowMSW::UnsubclassWin()
@@ -1113,7 +1262,7 @@ void wxWindowMSW::AssociateHandle(WXWidget handle)
 
     WXHWND wxhwnd = (WXHWND)handle;
 
 
     WXHWND wxhwnd = (WXHWND)handle;
 
-    SetHWND(wxhwnd);
+    // this also calls SetHWND(wxhwnd)
     SubclassWin(wxhwnd);
 }
 
     SubclassWin(wxhwnd);
 }
 
@@ -1239,14 +1388,14 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
     }
 
     // and the extended style
     }
 
     // and the extended style
-    long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+    long exstyleReal = wxGetWindowExStyle(this);
 
     if ( exstyle != exstyleOld )
     {
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
 
     if ( exstyle != exstyleOld )
     {
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
-        ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
+        wxSetWindowExStyle(this, exstyleReal);
 
         // ex style changes don't take effect without calling SetWindowPos
         callSWP = true;
 
         // ex style changes don't take effect without calling SetWindowPos
         callSWP = true;
@@ -1268,6 +1417,43 @@ void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
     }
 }
 
     }
 }
 
+wxBorder wxWindowMSW::GetDefaultBorderForControl() const
+{
+    return wxBORDER_THEME;
+}
+
+wxBorder wxWindowMSW::GetDefaultBorder() const
+{
+    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__)
+    if (border == wxBORDER_THEME || border == wxBORDER_SUNKEN || border == wxBORDER_SIMPLE)
+        return wxBORDER_SIMPLE;
+    else
+        return wxBORDER_NONE;
+#else
+#if wxUSE_UXTHEME
+    if (border == wxBORDER_THEME)
+    {
+        if (CanApplyThemeBorder())
+        {
+            wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
+            if (theme)
+                return wxBORDER_THEME;
+        }
+        return wxBORDER_SUNKEN;
+    }
+#endif
+    return border;
+#endif
+}
+
+
 WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 {
     // translate common wxWidgets styles to Windows ones
 WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 {
     // translate common wxWidgets styles to Windows ones
@@ -1297,7 +1483,10 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     if ( flags & wxHSCROLL )
         style |= WS_HSCROLL;
 
     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 )
 
     // WS_BORDER is only required for wxBORDER_SIMPLE
     if ( border == wxBORDER_SIMPLE )
@@ -1322,6 +1511,7 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 
             case wxBORDER_NONE:
             case wxBORDER_SIMPLE:
 
             case wxBORDER_NONE:
             case wxBORDER_SIMPLE:
+            case wxBORDER_THEME:
                 break;
 
             case wxBORDER_STATIC:
                 break;
 
             case wxBORDER_STATIC:
@@ -1337,9 +1527,9 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
                 style &= ~WS_BORDER;
                 break;
 
                 style &= ~WS_BORDER;
                 break;
 
-            case wxBORDER_DOUBLE:
-                *exstyle |= WS_EX_DLGMODALFRAME;
-                break;
+//            case wxBORDER_DOUBLE:
+//                *exstyle |= WS_EX_DLGMODALFRAME;
+//                break;
         }
 
         // wxUniv doesn't use Windows dialog navigation functions at all
         }
 
         // wxUniv doesn't use Windows dialog navigation functions at all
@@ -1397,7 +1587,7 @@ void wxWindowMSW::OnInternalIdle()
     }
 #endif // !HAVE_TRACKMOUSEEVENT
 
     }
 #endif // !HAVE_TRACKMOUSEEVENT
 
-    if (wxUpdateUIEvent::CanUpdate(this))
+    if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
@@ -1413,7 +1603,7 @@ bool wxWindowMSW::Reparent(wxWindowBase *parent)
     ::SetParent(hWndChild, hWndParent);
 
 #ifndef __WXWINCE__
     ::SetParent(hWndChild, hWndParent);
 
 #ifndef __WXWINCE__
-    if ( ::GetWindowLong(hWndChild, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
+    if ( wxHasWindowExStyle(this, WS_EX_CONTROLPARENT) )
     {
         EnsureParentHasControlParentStyle(GetParent());
     }
     {
         EnsureParentHasControlParentStyle(GetParent());
     }
@@ -1429,30 +1619,24 @@ static inline void SendSetRedraw(HWND hwnd, bool on)
 #endif
 }
 
 #endif
 }
 
-void wxWindowMSW::Freeze()
+void wxWindowMSW::DoFreeze()
 {
 {
-    if ( !m_frozenness++ )
-    {
-        if ( IsShown() )
-            SendSetRedraw(GetHwnd(), false);
-    }
+    if ( !IsShown() )
+        return; // no point in freezing hidden window
+
+    SendSetRedraw(GetHwnd(), false);
 }
 
 }
 
-void wxWindowMSW::Thaw()
+void wxWindowMSW::DoThaw()
 {
 {
-    wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
+    if ( !IsShown() )
+        return; // hidden windows aren't frozen by DoFreeze
 
 
-    if ( --m_frozenness == 0 )
-    {
-        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();
 }
 
 void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
 }
 
 void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
@@ -1963,23 +2147,23 @@ int wxWindowMSW::GetCharWidth() const
 void wxWindowMSW::GetTextExtent(const wxString& string,
                              int *x, int *y,
                              int *descent, int *externalLeading,
 void wxWindowMSW::GetTextExtent(const wxString& string,
                              int *x, int *y,
                              int *descent, int *externalLeading,
-                             const wxFont *theFont) const
+                             const wxFont *fontToUse) const
 {
 {
-    wxASSERT_MSG( !theFont || theFont->Ok(),
+    wxASSERT_MSG( !fontToUse || fontToUse->Ok(),
                     _T("invalid font in GetTextExtent()") );
 
                     _T("invalid font in GetTextExtent()") );
 
-    wxFont fontToUse;
-    if (theFont)
-        fontToUse = *theFont;
+    HFONT hfontToUse;
+    if ( fontToUse )
+        hfontToUse = GetHfontOf(*fontToUse);
     else
     else
-        fontToUse = GetFont();
+        hfontToUse = GetHfontOf(GetFont());
 
     WindowHDC hdc(GetHwnd());
 
     WindowHDC hdc(GetHwnd());
-    SelectInHDC selectFont(hdc, GetHfontOf(fontToUse));
+    SelectInHDC selectFont(hdc, hfontToUse);
 
     SIZE sizeRect;
     TEXTMETRIC tm;
 
     SIZE sizeRect;
     TEXTMETRIC tm;
-    ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect);
+    ::GetTextExtentPoint32(hdc, string.wx_str(), string.length(), &sizeRect);
     GetTextMetrics(hdc, &tm);
 
     if ( x )
     GetTextMetrics(hdc, &tm);
 
     if ( x )
@@ -2042,7 +2226,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     point.x = x;
     point.y = y;
     ::ClientToScreen(hWnd, &point);
     point.x = x;
     point.y = y;
     ::ClientToScreen(hWnd, &point);
-    wxCurrentPopupMenu = menu;
 #if defined(__WXWINCE__)
     static const UINT flags = 0;
 #else // !__WXWINCE__
 #if defined(__WXWINCE__)
     static const UINT flags = 0;
 #else // !__WXWINCE__
@@ -2071,8 +2254,6 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     // for example) and so we do need to process the event immediately
     wxYieldForCommandsOnly();
 
     // for example) and so we do need to process the event immediately
     wxYieldForCommandsOnly();
 
-    wxCurrentPopupMenu = NULL;
-
     menu->SetInvokingWindow(NULL);
 
     return true;
     menu->SetInvokingWindow(NULL);
 
     return true;
@@ -2174,13 +2355,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                 case VK_RETURN:
                     {
 
                 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
 #if wxUSE_BUTTON
                         // currently active button should get enter press even
                         // if there is a default button elsewhere so check if
@@ -2195,16 +2369,56 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW )
                             {
                                 // emulate the button click
                             if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW )
                             {
                                 // emulate the button click
-                                btn = wxFindWinFromHandle((WXHWND)msg->hwnd);
+                                btn = wxFindWinFromHandle(msg->hwnd);
                             }
 
                             bProcess = false;
                         }
                         else // not a button itself, do we have default button?
                         {
                             }
 
                             bProcess = false;
                         }
                         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(),
                             if ( tlw )
                             {
                                 btn = wxDynamicCast(tlw->GetDefaultItem(),
@@ -2224,7 +2438,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         // map Enter presses into button presses on PDAs
                         wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN);
                         event.SetEventObject(this);
                         // 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__
                     }
                             return true;
 #endif // __WXWINCE__
                     }
@@ -2242,7 +2456,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 event.SetFromTab(bFromTab);
                 event.SetEventObject(this);
 
                 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
                 {
                     // as we don't call IsDialogMessage(), which would take of
                     // this by default, we need to manually send this message
@@ -2333,8 +2547,7 @@ bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* msg)
         {
             wxWindow * const win = node->GetData();
             if ( win->CanAcceptFocus() &&
         {
             wxWindow * const win = node->GetData();
             if ( win->CanAcceptFocus() &&
-                    !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) &
-                        WS_EX_CONTROLPARENT) )
+                    !wxHasWindowExStyle(win, WS_EX_CONTROLPARENT) )
             {
                 // it shouldn't hang...
                 canSafelyCallIsDlgMsg = true;
             {
                 // it shouldn't hang...
                 canSafelyCallIsDlgMsg = true;
@@ -2446,11 +2659,11 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w
     // trace all messages - useful for the debugging
 #ifdef __WXDEBUG__
     wxLogTrace(wxTraceMessages,
     // trace all messages - useful for the debugging
 #ifdef __WXDEBUG__
     wxLogTrace(wxTraceMessages,
-               wxT("Processing %s(hWnd=%08lx, wParam=%8lx, lParam=%8lx)"),
-               wxGetMessageName(message), (long)hWnd, (long)wParam, lParam);
+               wxT("Processing %s(hWnd=%p, wParam=%08lx, lParam=%08lx)"),
+               wxGetMessageName(message), hWnd, (long)wParam, lParam);
 #endif // __WXDEBUG__
 
 #endif // __WXDEBUG__
 
-    wxWindowMSW *wnd = wxFindWinFromHandle((WXHWND) hWnd);
+    wxWindowMSW *wnd = wxFindWinFromHandle(hWnd);
 
     // when we get the first message for the HWND we just created, we associate
     // it with wxWindow stored in gs_winBeingCreated
 
     // when we get the first message for the HWND we just created, we associate
     // it with wxWindow stored in gs_winBeingCreated
@@ -2536,7 +2749,19 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
                 }
             }
             break;
+#if 0
+        case WM_ENTERSIZEMOVE:
+            {
+                processed = HandleEnterSizeMove();
+            }
+            break;
 
 
+        case WM_EXITSIZEMOVE:
+            {
+                processed = HandleExitSizeMove();
+            }
+            break;
+#endif
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2574,11 +2799,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 
         case WM_SETFOCUS:
             break;
 
         case WM_SETFOCUS:
-            processed = HandleSetFocus((WXHWND)(HWND)wParam);
+            processed = HandleSetFocus((WXHWND)wParam);
             break;
 
         case WM_KILLFOCUS:
             break;
 
         case WM_KILLFOCUS:
-            processed = HandleKillFocus((WXHWND)(HWND)wParam);
+            processed = HandleKillFocus((WXHWND)wParam);
             break;
 
         case WM_PRINTCLIENT:
             break;
 
         case WM_PRINTCLIENT:
@@ -2652,6 +2877,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
         case WM_MBUTTONDOWN:
         case WM_MBUTTONUP:
         case WM_MBUTTONDBLCLK:
         case WM_MBUTTONDOWN:
         case WM_MBUTTONUP:
         case WM_MBUTTONDBLCLK:
+#ifdef wxHAS_XBUTTON
+        case WM_XBUTTONDOWN:
+        case WM_XBUTTONUP:
+        case WM_XBUTTONDBLCLK:
+#endif // wxHAS_XBUTTON
             {
 #ifdef __WXMICROWIN__
                 // MicroWindows seems to ignore the fact that a window is
             {
 #ifdef __WXMICROWIN__
                 // MicroWindows seems to ignore the fact that a window is
@@ -2718,7 +2948,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                         wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
 
                         evtCtx.SetEventObject(this);
                         wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
 
                         evtCtx.SetEventObject(this);
-                        if (GetEventHandler()->ProcessEvent(evtCtx))
+                        if (HandleWindowEvent(evtCtx))
                         {
                             processed = true;
                             return true;
                         {
                             processed = true;
                             return true;
@@ -2742,7 +2972,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // problems, so don't do it for them (unnecessary anyhow)
                     if ( !win->IsOfStandardClass() )
                     {
                     // problems, so don't do it for them (unnecessary anyhow)
                     if ( !win->IsOfStandardClass() )
                     {
-                        if ( message == WM_LBUTTONDOWN && win->CanAcceptFocus() )
+                        if ( message == WM_LBUTTONDOWN && win->IsFocusable() )
                             win->SetFocus();
                     }
                 }
                             win->SetFocus();
                     }
                 }
@@ -2795,23 +3025,15 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             // for these messages we must return true if process the message
 #ifdef WM_DRAWITEM
         case WM_DRAWITEM:
             // for these messages we must return true if process the message
 #ifdef WM_DRAWITEM
         case WM_DRAWITEM:
-        case WM_MEASUREITEM:
-            {
-                int idCtrl = (UINT)wParam;
-                if ( message == WM_DRAWITEM )
-                {
-                    processed = MSWOnDrawItem(idCtrl,
-                                              (WXDRAWITEMSTRUCT *)lParam);
-                }
-                else
-                {
-                    processed = MSWOnMeasureItem(idCtrl,
-                                                 (WXMEASUREITEMSTRUCT *)lParam);
-                }
+            processed = MSWOnDrawItem(wParam, (WXDRAWITEMSTRUCT *)lParam);
+            if ( processed )
+                rc.result = TRUE;
+            break;
 
 
-                if ( processed )
-                    rc.result = TRUE;
-            }
+        case WM_MEASUREITEM:
+            processed = MSWOnMeasureItem(wParam, (WXMEASUREITEMSTRUCT *)lParam);
+            if ( processed )
+                rc.result = TRUE;
             break;
 #endif // defined(WM_DRAWITEM)
 
             break;
 #endif // defined(WM_DRAWITEM)
 
@@ -2952,6 +3174,12 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 #endif // wxUSE_HOTKEY
 
             break;
 #endif // wxUSE_HOTKEY
 
+        case WM_CUT:
+        case WM_COPY:
+        case WM_PASTE:
+            processed = HandleClipboardEvent(message);
+            break;
+
         case WM_HSCROLL:
         case WM_VSCROLL:
             {
         case WM_HSCROLL:
         case WM_VSCROLL:
             {
@@ -2997,11 +3225,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #endif
 
         case WM_PALETTECHANGED:
 #endif
 
         case WM_PALETTECHANGED:
-            processed = HandlePaletteChanged((WXHWND) (HWND) wParam);
+            processed = HandlePaletteChanged((WXHWND)wParam);
             break;
 
         case WM_CAPTURECHANGED:
             break;
 
         case WM_CAPTURECHANGED:
-            processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
+            processed = HandleCaptureChanged((WXHWND)lParam);
             break;
 
         case WM_SETTINGCHANGE:
             break;
 
         case WM_SETTINGCHANGE:
@@ -3013,7 +3241,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 
         case WM_ERASEBKGND:
             break;
 
         case WM_ERASEBKGND:
-            processed = HandleEraseBkgnd((WXHDC)(HDC)wParam);
+            processed = HandleEraseBkgnd((WXHDC)wParam);
             if ( processed )
             {
                 // we processed the message, i.e. erased the background
             if ( processed )
             {
                 // we processed the message, i.e. erased the background
@@ -3028,7 +3256,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #endif
 
         case WM_INITDIALOG:
 #endif
 
         case WM_INITDIALOG:
-            processed = HandleInitDialog((WXHWND)(HWND)wParam);
+            processed = HandleInitDialog((WXHWND)wParam);
 
             if ( processed )
             {
 
             if ( processed )
             {
@@ -3052,7 +3280,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #endif
 
         case WM_SETCURSOR:
 #endif
 
         case WM_SETCURSOR:
-            processed = HandleSetCursor((WXHWND)(HWND)wParam,
+            processed = HandleSetCursor((WXHWND)wParam,
                                         LOWORD(lParam),     // hit test
                                         HIWORD(lParam));    // mouse msg
 
                                         LOWORD(lParam),     // hit test
                                         HIWORD(lParam));    // mouse msg
 
@@ -3106,14 +3334,14 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                 );
 
                     helpEvent.SetEventObject(this);
                                 );
 
                     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);
 #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?
 
                 }
                 else // unknown help event?
@@ -3137,20 +3365,22 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 // we could have got an event from our child, reflect it back
                 // to it if this is the case
                 wxWindowMSW *win = NULL;
                 // we could have got an event from our child, reflect it back
                 // to it if this is the case
                 wxWindowMSW *win = NULL;
-                if ( (WXHWND)wParam != m_hWnd )
+                WXHWND hWnd = (WXHWND)wParam;
+                if ( hWnd != m_hWnd )
                 {
                 {
-                    win = FindItemByHWND((WXHWND)wParam);
+                    win = FindItemByHWND(hWnd);
                 }
 
                 if ( !win )
                     win = this;
 
                 evtCtx.SetEventObject(win);
                 }
 
                 if ( !win )
                     win = this;
 
                 evtCtx.SetEventObject(win);
-                processed = win->GetEventHandler()->ProcessEvent(evtCtx);
+                processed = win->HandleWindowEvent(evtCtx);
             }
             break;
 #endif
 
             }
             break;
 #endif
 
+#if wxUSE_MENUS
         case WM_MENUCHAR:
             // we're only interested in our own menus, not MF_SYSMENU
             if ( HIWORD(wParam) == MF_POPUP )
         case WM_MENUCHAR:
             // we're only interested in our own menus, not MF_SYSMENU
             if ( HIWORD(wParam) == MF_POPUP )
@@ -3164,6 +3394,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
                 }
             }
             break;
+#endif // wxUSE_MENUS
 
 #ifndef __WXWINCE__
         case WM_POWERBROADCAST:
 
 #ifndef __WXWINCE__
         case WM_POWERBROADCAST:
@@ -3175,6 +3406,101 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 #endif // __WXWINCE__
 
             break;
 #endif // __WXWINCE__
 
+#if wxUSE_UXTHEME
+        // If we want the default themed border then we need to draw it ourselves
+        case WM_NCCALCSIZE:
+            {
+                wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
+                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);
+                    processed = true;
+
+                    // now alter the client size making room for drawing a themed border
+                    NCCALCSIZE_PARAMS *csparam = NULL;
+                    RECT *rect;
+                    if ( wParam )
+                    {
+                        csparam = (NCCALCSIZE_PARAMS *)lParam;
+                        rect = &csparam->rgrc[0];
+                    }
+                    else
+                    {
+                        rect = (RECT *)lParam;
+                    }
+
+                    wxUxThemeHandle hTheme((const wxWindow *)this, L"EDIT");
+                    RECT rcClient = { 0, 0, 0, 0 };
+                    wxClientDC dc((wxWindow *)this);
+                    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl();
+
+                    if ( theme->GetThemeBackgroundContentRect
+                                (
+                                 hTheme,
+                                 GetHdcOf(*impl),
+                                 EP_EDITTEXT,
+                                 ETS_NORMAL,
+                                 rect,
+                                 &rcClient) == S_OK )
+                    {
+                        InflateRect(&rcClient, -1, -1);
+                        *rect = rcClient;
+                        rc.result = WVR_REDRAW;
+                    }
+                }
+            }
+            break;
+
+        case WM_NCPAINT:
+            {
+                wxUxThemeEngine* theme = wxUxThemeEngine::GetIfActive();
+                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((const 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;
+                    wxCopyRectToRECT(GetSize(), rcBorder);
+
+                    RECT rcClient;
+                    theme->GetThemeBackgroundContentRect(
+                        hTheme, GetHdcOf(*impl), EP_EDITTEXT, ETS_NORMAL, &rcBorder, &rcClient);
+                    InflateRect(&rcClient, -1, -1);
+
+                    ::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(*impl), &rcBorder);
+                    }
+
+                    // Draw the border
+                    int nState;
+                    if ( !IsEnabled() )
+                        nState = ETS_DISABLED;
+                    // should we check this?
+                    //else if ( ::GetWindowLong(GetHwnd(), GWL_STYLE) & ES_READONLY)
+                    //    nState = ETS_READONLY;
+                    else
+                        nState = ETS_NORMAL;
+                    theme->DrawThemeBackground(hTheme, GetHdcOf(*impl), EP_EDITTEXT, nState, &rcBorder, NULL);
+                }
+            }
+            break;
+
+#endif // wxUSE_UXTHEME
+
         default:
             // try a custom message handler
             const MSWMessageHandlers::const_iterator
         default:
             // try a custom message handler
             const MSWMessageHandlers::const_iterator
@@ -3201,38 +3527,40 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 // wxWindow <-> HWND map
 // ----------------------------------------------------------------------------
 
 // wxWindow <-> HWND map
 // ----------------------------------------------------------------------------
 
-wxWinHashTable *wxWinHandleHash = NULL;
-
-wxWindow *wxFindWinFromHandle(WXHWND hWnd)
+wxWindow *wxFindWinFromHandle(HWND hwnd)
 {
 {
-    return (wxWindow*)wxWinHandleHash->Get((long)hWnd);
+    WindowHandles::const_iterator i = gs_windowHandles.find(hwnd);
+    return i == gs_windowHandles.end() ? NULL : i->second;
 }
 
 }
 
-void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win)
+void wxAssociateWinWithHandle(HWND hwnd, wxWindowMSW *win)
 {
 {
-    // adding NULL hWnd is (first) surely a result of an error and
+    // adding NULL hwnd is (first) surely a result of an error and
     // (secondly) breaks menu command processing
     // (secondly) breaks menu command processing
-    wxCHECK_RET( hWnd != (HWND)NULL,
-                 wxT("attempt to add a NULL hWnd to window list ignored") );
+    wxCHECK_RET( hwnd != (HWND)NULL,
+                 wxT("attempt to add a NULL hwnd to window list ignored") );
 
 
-    wxWindow *oldWin = wxFindWinFromHandle((WXHWND) hWnd);
 #ifdef __WXDEBUG__
 #ifdef __WXDEBUG__
-    if ( oldWin && (oldWin != win) )
+    WindowHandles::const_iterator i = gs_windowHandles.find(hwnd);
+    if ( i != gs_windowHandles.end() )
     {
     {
-        wxLogDebug(wxT("HWND %X already associated with another window (%s)"),
-                   (int) hWnd, win->GetClassInfo()->GetClassName());
+        if ( i->second != win )
+        {
+            wxLogDebug(wxT("HWND %p already associated with another window (%s)"),
+                       hwnd, win->GetClassInfo()->GetClassName());
+        }
+        //else: this actually happens currently because we associate the window
+        //      with its HWND during creation (if we create it) and also when
+        //      SubclassWin() is called later, this is ok
     }
     }
-    else
 #endif // __WXDEBUG__
 #endif // __WXDEBUG__
-    if (!oldWin)
-    {
-        wxWinHandleHash->Put((long)hWnd, (wxWindow *)win);
-    }
+
+    gs_windowHandles[hwnd] = (wxWindow *)win;
 }
 
 void wxRemoveHandleAssociation(wxWindowMSW *win)
 {
 }
 
 void wxRemoveHandleAssociation(wxWindowMSW *win)
 {
-    wxWinHandleHash->Delete((long)win->GetHWND());
+    gs_windowHandles.erase(GetHwndOf(win));
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -3346,6 +3674,12 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
                             WXDWORD style,
                             WXDWORD extendedStyle)
 {
                             WXDWORD style,
                             WXDWORD extendedStyle)
 {
+    // check a common bug in the user code: if the window is created with a
+    // non-default ctor and Create() is called too, we'd create 2 HWND for a
+    // single wxWindow object and this results in all sorts of trouble,
+    // especially for wxTLWs
+    wxCHECK_MSG( !m_hWnd, true, "window can't be recreated" );
+
     // choose the position/size for the new window
     int x, y, w, h;
     (void)MSWGetCreateWindowCoords(pos, size, x, y, w, h);
     // choose the position/size for the new window
     int x, y, w, h;
     (void)MSWGetCreateWindowCoords(pos, size, x, y, w, h);
@@ -3369,12 +3703,12 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     m_hWnd = (WXHWND)::CreateWindowEx
                        (
                         extendedStyle,
     m_hWnd = (WXHWND)::CreateWindowEx
                        (
                         extendedStyle,
-                        className,
-                        title ? title : (const wxChar*)m_windowName.c_str(),
+                        className.wx_str(),
+                        title ? title : m_windowName.wx_str(),
                         style,
                         x, y, w, h,
                         (HWND)MSWGetParent(),
                         style,
                         x, y, w, h,
                         (HWND)MSWGetParent(),
-                        (HMENU)controlId,
+                        (HMENU)wxUIntToPtr(controlId),
                         wxGetInstance(),
                         NULL                        // no extra data
                        );
                         wxGetInstance(),
                         NULL                        // no extra data
                        );
@@ -3404,7 +3738,7 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 #ifndef __WXMICROWIN__
     LPNMHDR hdr = (LPNMHDR)lParam;
     HWND hWnd = hdr->hwndFrom;
 #ifndef __WXMICROWIN__
     LPNMHDR hdr = (LPNMHDR)lParam;
     HWND hWnd = hdr->hwndFrom;
-    wxWindow *win = wxFindWinFromHandle((WXHWND)hWnd);
+    wxWindow *win = wxFindWinFromHandle(hWnd);
 
     // if the control is one of our windows, let it handle the message itself
     if ( win )
 
     // if the control is one of our windows, let it handle the message itself
     if ( win )
@@ -3490,7 +3824,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
                     (
                         CP_ACP,
                         0,                      // no flags
                     (
                         CP_ACP,
                         0,                      // no flags
-                        ttip,
+                        ttip.wx_str(),
                         tipLength,
                         buf,
                         WXSIZEOF(buf) - 1
                         tipLength,
                         buf,
                         WXSIZEOF(buf) - 1
@@ -3585,7 +3919,7 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
     wxCloseEvent event(wxEVT_END_SESSION, wxID_ANY);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(false);
     wxCloseEvent event(wxEVT_END_SESSION, wxID_ANY);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(false);
-    event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
+    event.SetLoggingOff((logOff & ENDSESSION_LOGOFF) != 0);
 
     return wxTheApp->ProcessEvent(event);
 #else
 
     return wxTheApp->ProcessEvent(event);
 #else
@@ -3647,7 +3981,7 @@ bool wxWindowMSW::HandleActivate(int state,
                           m_windowId);
     event.SetEventObject(this);
 
                           m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
 }
 
 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
@@ -3662,7 +3996,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);
     // 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
 
 #if wxUSE_CARET
     // Deal with caret
@@ -3672,22 +4006,13 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
     }
 #endif // wxUSE_CARET
 
     }
 #endif // wxUSE_CARET
 
-#if wxUSE_TEXTCTRL
-    // If it's a wxTextCtrl don't send the event as it will be done
-    // after the control gets to process it from EN_FOCUS handler
-    if ( wxDynamicCastThis(wxTextCtrl) )
-    {
-        return false;
-    }
-#endif // wxUSE_TEXTCTRL
-
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
 
     // wxFindWinFromHandle() may return NULL, it is ok
     event.SetWindow(wxFindWinFromHandle(hwnd));
 
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
 
     // wxFindWinFromHandle() may return NULL, it is ok
     event.SetWindow(wxFindWinFromHandle(hwnd));
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
 }
 
 bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
@@ -3700,16 +4025,6 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     }
 #endif // wxUSE_CARET
 
     }
 #endif // wxUSE_CARET
 
-#if wxUSE_TEXTCTRL
-    // If it's a wxTextCtrl don't send the event as it will be done
-    // after the control gets to process it.
-    wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl);
-    if ( ctrl )
-    {
-        return false;
-    }
-#endif
-
     // Don't send the event when in the process of being deleted.  This can
     // only cause problems if the event handler tries to access the object.
     if ( m_isBeingDeleted )
     // Don't send the event when in the process of being deleted.  This can
     // only cause problems if the event handler tries to access the object.
     if ( m_isBeingDeleted )
@@ -3723,7 +4038,7 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     // wxFindWinFromHandle() may return NULL, it is ok
     event.SetWindow(wxFindWinFromHandle(hwnd));
 
     // wxFindWinFromHandle() may return NULL, it is ok
     event.SetWindow(wxFindWinFromHandle(hwnd));
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -3749,7 +4064,7 @@ bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
     wxShowEvent event(GetId(), show);
     event.SetEventObject(this);
 
     wxShowEvent event(GetId(), show);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 }
 
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
@@ -3757,7 +4072,7 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
     wxInitDialogEvent event(GetId());
     event.SetEventObject(this);
 
     wxInitDialogEvent event(GetId());
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
 }
 
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
@@ -3797,7 +4112,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
     event.m_pos.x = dropPoint.x;
     event.m_pos.y = dropPoint.y;
 
     event.m_pos.x = dropPoint.x;
     event.m_pos.y = dropPoint.y;
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 #endif
 }
 
 #endif
 }
 
@@ -3808,63 +4123,56 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
 {
 #ifndef __WXMICROWIN__
     // the logic is as follows:
 {
 #ifndef __WXMICROWIN__
     // the logic is as follows:
-    // -1. don't set cursor for non client area, including but not limited to
-    //     the title bar, scrollbars, &c
-    //  0. allow the user to override default behaviour by using EVT_SET_CURSOR
-    //  1. if we have the cursor set it unless wxIsBusy()
-    //  2. if we're a top level window, set some cursor anyhow
-    //  3. if wxIsBusy(), set the busy cursor, otherwise the global one
+    //  0. if we're busy, set the busy cursor (even for non client elements)
+    //  1. don't set custom cursor for non client area of enabled windows
+    //  2. ask user EVT_SET_CURSOR handler for the cursor
+    //  3. if still no cursor but we're in a TLW, set the global cursor
 
 
-    if ( nHitTest != HTCLIENT )
+    HCURSOR hcursor = 0;
+    if ( wxIsBusy() )
     {
     {
-        return false;
+        hcursor = wxGetCurrentBusyCursor();
     }
     }
+    else // not busy
+    {
+        if ( nHitTest != HTCLIENT )
+            return false;
 
 
-    HCURSOR hcursor = 0;
-
-    // first ask the user code - it may wish to set the cursor in some very
-    // specific way (for example, depending on the current position)
-    POINT pt;
+        // first ask the user code - it may wish to set the cursor in some very
+        // specific way (for example, depending on the current position)
+        POINT pt;
 #ifdef __WXWINCE__
 #ifdef __WXWINCE__
-    if ( !::GetCursorPosWinCE(&pt))
+        if ( !::GetCursorPosWinCE(&pt))
 #else
 #else
-    if ( !::GetCursorPos(&pt) )
+        if ( !::GetCursorPos(&pt) )
 #endif
 #endif
-    {
-        wxLogLastError(wxT("GetCursorPos"));
-    }
-
-    int x = pt.x,
-        y = pt.y;
-    ScreenToClient(&x, &y);
-    wxSetCursorEvent event(x, y);
-
-    bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
-    if ( processedEvtSetCursor && event.HasCursor() )
-    {
-        hcursor = GetHcursorOf(event.GetCursor());
-    }
+        {
+            wxLogLastError(wxT("GetCursorPos"));
+        }
 
 
-    if ( !hcursor )
-    {
-        bool isBusy = wxIsBusy();
+        int x = pt.x,
+            y = pt.y;
+        ScreenToClient(&x, &y);
+        wxSetCursorEvent event(x, y);
 
 
-        // the test for processedEvtSetCursor is here to prevent using m_cursor
-        // if the user code caught EVT_SET_CURSOR() and returned nothing from
-        // it - this is a way to say that our cursor shouldn't be used for this
-        // point
-        if ( !processedEvtSetCursor && m_cursor.Ok() )
+        bool processedEvtSetCursor = HandleWindowEvent(event);
+        if ( processedEvtSetCursor && event.HasCursor() )
         {
         {
-            hcursor = GetHcursorOf(m_cursor);
+            hcursor = GetHcursorOf(event.GetCursor());
         }
 
         }
 
-        if ( !GetParent() )
+        if ( !hcursor )
         {
         {
-            if ( isBusy )
+            // the test for processedEvtSetCursor is here to prevent using
+            // m_cursor if the user code caught EVT_SET_CURSOR() and returned
+            // nothing from it - this is a way to say that our cursor shouldn't
+            // be used for this point
+            if ( !processedEvtSetCursor && m_cursor.Ok() )
             {
             {
-                hcursor = wxGetCurrentBusyCursor();
+                hcursor = GetHcursorOf(m_cursor);
             }
             }
-            else if ( !hcursor )
+
+            if ( !hcursor && !GetParent() )
             {
                 const wxCursor *cursor = wxGetGlobalCursor();
                 if ( cursor && cursor->Ok() )
             {
                 const wxCursor *cursor = wxGetGlobalCursor();
                 if ( cursor && cursor->Ok() )
@@ -3875,10 +4183,9 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
         }
     }
 
         }
     }
 
+
     if ( hcursor )
     {
     if ( hcursor )
     {
-//        wxLogDebug("HandleSetCursor: Setting cursor %ld", (long) hcursor);
-
         ::SetCursor(hcursor);
 
         // cursor set, stop here
         ::SetCursor(hcursor);
 
         // cursor set, stop here
@@ -3914,9 +4221,6 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
             break;
 
         case PBT_APMRESUMESUSPEND:
             break;
 
         case PBT_APMRESUMESUSPEND:
-#ifdef PBT_APMRESUMEAUTOMATIC
-        case PBT_APMRESUMEAUTOMATIC:
-#endif
             evtType = wxEVT_POWER_RESUME;
             break;
 
             evtType = wxEVT_POWER_RESUME;
             break;
 
@@ -3933,6 +4237,9 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
         case PBT_APMPOWERSTATUSCHANGE:
         case PBT_APMOEMEVENT:
         case PBT_APMRESUMECRITICAL:
         case PBT_APMPOWERSTATUSCHANGE:
         case PBT_APMOEMEVENT:
         case PBT_APMRESUMECRITICAL:
+#ifdef PBT_APMRESUMEAUTOMATIC
+        case PBT_APMRESUMEAUTOMATIC:
+#endif
             evtType = wxEVT_NULL;
             break;
     }
             evtType = wxEVT_NULL;
             break;
     }
@@ -3944,7 +4251,7 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
     // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events?
 
     wxPowerEvent event(evtType);
     // 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();
         return false;
 
     *vetoed = event.IsVetoed();
@@ -3955,17 +4262,33 @@ bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
 
 bool wxWindowMSW::IsDoubleBuffered() const
 {
 
 bool wxWindowMSW::IsDoubleBuffered() const
 {
-    for ( const wxWindowMSW *wnd = this;
-          wnd && !wnd->IsTopLevel(); wnd =
-          wnd->GetParent() )
+    for ( const wxWindowMSW *win = this; win; win = win->GetParent() )
     {
     {
-        if ( ::GetWindowLong(GetHwndOf(wnd), GWL_EXSTYLE) & WS_EX_COMPOSITED )
+        if ( wxHasWindowExStyle(win, WS_EX_COMPOSITED) )
             return true;
             return true;
+
+        if ( win->IsTopLevel() )
+            break;
     }
 
     return false;
 }
 
     }
 
     return false;
 }
 
+void wxWindowMSW::SetDoubleBuffered(bool on)
+{
+    // Get the current extended style bits
+    long exstyle = wxGetWindowExStyle(this);
+
+    // Twiddle the bit as needed
+    if ( on )
+        exstyle |= WS_EX_COMPOSITED;
+    else
+        exstyle &= ~WS_EX_COMPOSITED;
+
+    // put it back
+    wxSetWindowExStyle(this, exstyle);
+}
+
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
@@ -4094,7 +4417,7 @@ bool wxWindowMSW::HandleSysColorChange()
     wxSysColourChangedEvent event;
     event.SetEventObject(this);
 
     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
 
     // always let the system carry on the default processing to allow the
     // native controls to react to the colours update
@@ -4106,7 +4429,7 @@ bool wxWindowMSW::HandleDisplayChange()
     wxDisplayChangedEvent event;
     event.SetEventObject(this);
 
     wxDisplayChangedEvent event;
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 #ifndef __WXMICROWIN__
 }
 
 #ifndef __WXMICROWIN__
@@ -4170,7 +4493,7 @@ bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
     event.SetEventObject(this);
     event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
 
     event.SetEventObject(this);
     event.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
 }
 
 bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
@@ -4182,7 +4505,7 @@ bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
     wxWindow *win = wxFindWinFromHandle(hWndGainedCapture);
     wxMouseCaptureChangedEvent event(GetId(), win);
     event.SetEventObject(this);
     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)
 }
 
 bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam)
@@ -4237,7 +4560,7 @@ bool wxWindowMSW::HandleQueryNewPalette()
     wxQueryNewPaletteEvent event(GetId());
     event.SetEventObject(this);
 
     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.
 }
 
 // Responds to colour changes: passes event on to children.
@@ -4353,14 +4676,18 @@ bool wxWindowMSW::HandlePaint()
     wxPaintEvent event(m_windowId);
     event.SetEventObject(this);
 
     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);
 
     // 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;
 }
 
     return processed;
 }
@@ -4371,7 +4698,7 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 #ifdef __WXUNIVERSAL__
     event.Skip();
 #else
 #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);
     if (hDC != 0)
     {
         MSWDefWindowProc(WM_PAINT, (WPARAM) hDC, 0);
@@ -4382,16 +4709,17 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 {
     wxDCTemp dc(hdc, GetClientSize());
 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);
 
     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
 
     // must be called manually as ~wxDC doesn't do anything for wxDCTemp
-    dc.SelectOldObjects(hdc);
+    impl->SelectOldObjects(hdc);
 
     return rc;
 }
 
     return rc;
 }
@@ -4415,9 +4743,12 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
         return;
     }
 
         return;
     }
 
+    wxDC *dc = event.GetDC();
+    if (!dc) return;
+    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl();
 
     // do default background painting
 
     // do default background painting
-    if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) )
+    if ( !DoEraseBackground(GetHdcOf(*impl)) )
     {
         // let the system paint the background
         event.Skip();
     {
         // let the system paint the background
         event.Skip();
@@ -4527,7 +4858,7 @@ bool wxWindowMSW::HandleMinimize()
     wxIconizeEvent event(m_windowId);
     event.SetEventObject(this);
 
     wxIconizeEvent event(m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMaximize()
 }
 
 bool wxWindowMSW::HandleMaximize()
@@ -4535,7 +4866,7 @@ bool wxWindowMSW::HandleMaximize()
     wxMaximizeEvent event(m_windowId);
     event.SetEventObject(this);
 
     wxMaximizeEvent event(m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMove(int x, int y)
 }
 
 bool wxWindowMSW::HandleMove(int x, int y)
@@ -4544,7 +4875,7 @@ bool wxWindowMSW::HandleMove(int x, int y)
     wxMoveEvent event(point, m_windowId);
     event.SetEventObject(this);
 
     wxMoveEvent event(point, m_windowId);
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMoving(wxRect& rect)
 }
 
 bool wxWindowMSW::HandleMoving(wxRect& rect)
@@ -4552,12 +4883,30 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
     wxMoveEvent event(rect, m_windowId);
     event.SetEventObject(this);
 
     wxMoveEvent event(rect, m_windowId);
     event.SetEventObject(this);
 
-    bool rc = GetEventHandler()->ProcessEvent(event);
+    bool rc = HandleWindowEvent(event);
     if (rc)
         rect = event.GetRect();
     return rc;
 }
 
     if (rc)
         rect = event.GetRect();
     return rc;
 }
 
+bool wxWindowMSW::HandleEnterSizeMove()
+{
+    wxMoveEvent event(wxPoint(0,0), m_windowId);
+    event.SetEventType(wxEVT_MOVE_START);
+    event.SetEventObject(this);
+
+    return HandleWindowEvent(event);
+}
+
+bool wxWindowMSW::HandleExitSizeMove()
+{
+    wxMoveEvent event(wxPoint(0,0), m_windowId);
+    event.SetEventType(wxEVT_MOVE_END);
+    event.SetEventObject(this);
+
+    return HandleWindowEvent(event);
+}
+
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
 #if USE_DEFERRED_SIZING
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
 #if USE_DEFERRED_SIZING
@@ -4617,7 +4966,7 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
             wxSizeEvent event(GetSize(), m_windowId);
             event.SetEventObject(this);
 
             wxSizeEvent event(GetSize(), m_windowId);
             event.SetEventObject(this);
 
-            processed = GetEventHandler()->ProcessEvent(event);
+            processed = HandleWindowEvent(event);
     }
 
 #if USE_DEFERRED_SIZING
     }
 
 #if USE_DEFERRED_SIZING
@@ -4657,7 +5006,7 @@ bool wxWindowMSW::HandleSizing(wxRect& rect)
     wxSizeEvent event(rect, m_windowId);
     event.SetEventObject(this);
 
     wxSizeEvent event(rect, m_windowId);
     event.SetEventObject(this);
 
-    bool rc = GetEventHandler()->ProcessEvent(event);
+    bool rc = HandleWindowEvent(event);
     if (rc)
         rect = event.GetRect();
     return rc;
     if (rc)
         rect = event.GetRect();
     return rc;
@@ -4709,8 +5058,11 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo))
 // command messages
 // ---------------------------------------------------------------------------
 
 // 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 )
     {
 #if wxUSE_MENUS_NATIVE
     if ( !cmd && wxCurrentPopupMenu )
     {
@@ -4733,8 +5085,7 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
     // try the id
     if ( !win )
     {
     // 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 )
     }
 
     if ( win )
@@ -4748,15 +5099,11 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
     // coming from a control to wxEVT_COMMAND_MENU_SELECTED
     if ( !control )
     {
     // coming from a control to wxEVT_COMMAND_MENU_SELECTED
     if ( !control )
     {
-        // If no child window, it may be an accelerator, e.g. for a popup menu
-        // command
-
-        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED);
+        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id);
         event.SetEventObject(this);
         event.SetEventObject(this);
-        event.SetId(id);
         event.SetInt(id);
 
         event.SetInt(id);
 
-        return GetEventHandler()->ProcessEvent(event);
+        return HandleWindowEvent(event);
     }
     else
     {
     }
     else
     {
@@ -4800,7 +5147,11 @@ 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_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) < 0;
+#ifdef wxHAS_XBUTTON
+    event.m_aux1Down = (flags & MK_XBUTTON1) != 0;
+    event.m_aux2Down = (flags & MK_XBUTTON2) != 0;
+#endif // wxHAS_XBUTTON
+    event.m_altDown = ::wxIsAltDown();
 
 #ifndef __WXWINCE__
     event.SetTimestamp(::GetMessageTime());
 
 #ifndef __WXWINCE__
     event.SetTimestamp(::GetMessageTime());
@@ -4866,7 +5217,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y)
                 ::IsWindowVisible(hwndUnderMouse) &&
                     ::IsWindowEnabled(hwndUnderMouse) )
     {
                 ::IsWindowVisible(hwndUnderMouse) &&
                     ::IsWindowEnabled(hwndUnderMouse) )
     {
-        wxWindow *winUnderMouse = wxFindWinFromHandle((WXHWND)hwndUnderMouse);
+        wxWindow *winUnderMouse = wxFindWinFromHandle(hwndUnderMouse);
         if ( winUnderMouse )
         {
             // translate the mouse coords to the other window coords
         if ( winUnderMouse )
         {
             // translate the mouse coords to the other window coords
@@ -4898,13 +5249,33 @@ bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
         wxEVT_RIGHT_DCLICK,
         wxEVT_MIDDLE_DOWN,
         wxEVT_MIDDLE_UP,
         wxEVT_RIGHT_DCLICK,
         wxEVT_MIDDLE_DOWN,
         wxEVT_MIDDLE_UP,
-        wxEVT_MIDDLE_DCLICK
+        wxEVT_MIDDLE_DCLICK,
+        0, // this one is for wxEVT_MOTION which is not used here
+        wxEVT_AUX1_DOWN,
+        wxEVT_AUX1_UP,
+        wxEVT_AUX1_DCLICK,
+        wxEVT_AUX2_DOWN,
+        wxEVT_AUX2_UP,
+        wxEVT_AUX2_DCLICK
     };
 
     };
 
+#ifdef wxHAS_XBUTTON
+    // the same messages are used for both auxillary mouse buttons so we need
+    // to adjust the index manually
+    switch ( msg )
+    {
+        case WM_XBUTTONDOWN:
+        case WM_XBUTTONUP:
+        case WM_XBUTTONDBLCLK:
+            if ( flags & MK_XBUTTON2 )
+                msg += wxEVT_AUX2_DOWN - wxEVT_AUX1_DOWN;
+    }
+#endif // wxHAS_XBUTTON
+
     wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]);
     InitMouseEvent(event, x, y, 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)
 }
 
 bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
@@ -4961,7 +5332,7 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
-            (void)GetEventHandler()->ProcessEvent(event);
+            (void)HandleWindowEvent(event);
         }
     }
 #ifdef HAVE_TRACKMOUSEEVENT
         }
     }
 #ifdef HAVE_TRACKMOUSEEVENT
@@ -5030,7 +5401,7 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
     }
 
     event.m_linesPerAction = s_linesPerRotation;
     }
 
     event.m_linesPerAction = s_linesPerRotation;
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 
 #else // !wxUSE_MOUSEWHEEL
     wxUnusedVar(wParam);
 
 #else // !wxUSE_MOUSEWHEEL
     wxUnusedVar(wParam);
@@ -5077,7 +5448,7 @@ void wxWindowMSW::GenerateMouseLeave()
     wxMouseEvent event(wxEVT_LEAVE_WINDOW);
     InitMouseEvent(event, pt.x, pt.y, state);
 
     wxMouseEvent event(wxEVT_LEAVE_WINDOW);
     InitMouseEvent(event, pt.x, pt.y, state);
 
-    (void)GetEventHandler()->ProcessEvent(event);
+    (void)HandleWindowEvent(event);
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -5164,7 +5535,7 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
         event.m_altDown = false;
     }
 
         event.m_altDown = false;
     }
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
 }
 
 bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
@@ -5178,7 +5549,7 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
     }
 
     wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
     }
 
     wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
@@ -5192,9 +5563,10 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
     }
 
     wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
     }
 
     wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 }
 
+#if wxUSE_MENUS
 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
                                 WXLPARAM WXUNUSED_IN_WINCE(lParam))
 {
 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
                                 WXLPARAM WXUNUSED_IN_WINCE(lParam))
 {
@@ -5229,7 +5601,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
                 //  menu creation code
                 wxMenuItem *item = (wxMenuItem*)mii.dwItemData;
 
                 //  menu creation code
                 wxMenuItem *item = (wxMenuItem*)mii.dwItemData;
 
-                const wxChar *p = wxStrchr(item->GetText(), _T('&'));
+                const wxChar *p = wxStrchr(item->GetItemLabel().wx_str(), _T('&'));
                 while ( p++ )
                 {
                     if ( *p == _T('&') )
                 while ( p++ )
                 {
                     if ( *p == _T('&') )
@@ -5265,16 +5637,18 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
     return wxNOT_FOUND;
 }
 
     return wxNOT_FOUND;
 }
 
-bool wxWindowMSW::HandleClipboardEvent( WXUINT nMsg )
+#endif // wxUSE_MENUS
+
+bool wxWindowMSW::HandleClipboardEvent(WXUINT nMsg)
 {
 {
-    const wxEventType type = ( nMsg == WM_CUT ) ? wxEVT_COMMAND_TEXT_CUT :
-                             ( nMsg == WM_COPY ) ? wxEVT_COMMAND_TEXT_COPY :
-                           /*( nMsg == WM_PASTE ) ? */ wxEVT_COMMAND_TEXT_PASTE;
+    const wxEventType type = nMsg == WM_CUT       ? wxEVT_COMMAND_TEXT_CUT
+                           : nMsg == WM_COPY      ? wxEVT_COMMAND_TEXT_COPY
+                           : /* nMsg == WM_PASTE */ wxEVT_COMMAND_TEXT_PASTE;
     wxClipboardTextEvent evt(type, GetId());
 
     evt.SetEventObject(this);
 
     wxClipboardTextEvent evt(type, GetId());
 
     evt.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(evt);
+    return HandleWindowEvent(evt);
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -5359,7 +5733,7 @@ bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags)
     event.SetPosition(wxPoint(x, y));
     event.SetEventObject(this);
 
     event.SetPosition(wxPoint(x, y));
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 #else
     wxUnusedVar(msg);
     wxUnusedVar(x);
 #else
     wxUnusedVar(msg);
     wxUnusedVar(x);
@@ -5446,7 +5820,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
         return false;
     }
 
         return false;
     }
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -5745,31 +6119,44 @@ WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual)
             break;
 
         default:
             break;
 
         default:
-            if ( isVirtual )
-                *isVirtual = false;
-            vk = (WXWORD)wxk;
-            break;
+            // no VkKeyScan() under CE unfortunately, we need to test how does
+            // it handle OEM keys
+#ifndef __WXWINCE__
+            // check to see if its one of the OEM key codes.
+            BYTE vks = LOBYTE(VkKeyScan(wxk));
+            if ( vks != 0xff )
+            {
+                vk = vks;
+            }
+            else
+#endif // !__WXWINCE__
+            {
+                if ( isVirtual )
+                    *isVirtual = false;
+                vk = (WXWORD)wxk;
+            }
     }
 
     return vk;
 }
 
     }
 
     return vk;
 }
 
-#ifndef SM_SWAPBUTTON
-    #define SM_SWAPBUTTON 23
-#endif
-
 // small helper for wxGetKeyState() and wxGetMouseState()
 static inline bool wxIsKeyDown(WXWORD vk)
 {
 // small helper for wxGetKeyState() and wxGetMouseState()
 static inline bool wxIsKeyDown(WXWORD vk)
 {
-    switch (vk)
+    // SM_SWAPBUTTON is not available under CE, so don't swap buttons there
+#ifdef SM_SWAPBUTTON
+    if ( vk == VK_LBUTTON || vk == VK_RBUTTON )
     {
     {
-        case VK_LBUTTON:
-            if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_RBUTTON;
-            break;
-        case VK_RBUTTON:
-            if (GetSystemMetrics(SM_SWAPBUTTON)) vk = VK_LBUTTON;
-            break;
+        if ( ::GetSystemMetrics(SM_SWAPBUTTON) )
+        {
+            if ( vk == VK_LBUTTON )
+                vk = VK_RBUTTON;
+            else // vk == VK_RBUTTON
+                vk = VK_LBUTTON;
+        }
     }
     }
+#endif // SM_SWAPBUTTON
+
     // the low order bit indicates whether the key was pressed since the last
     // call and the high order one indicates whether it is down right now and
     // we only want that one
     // the low order bit indicates whether the key was pressed since the last
     // call and the high order one indicates whether it is down right now and
     // we only want that one
@@ -5814,10 +6201,14 @@ wxMouseState wxGetMouseState()
     ms.SetLeftDown(wxIsKeyDown(VK_LBUTTON));
     ms.SetMiddleDown(wxIsKeyDown(VK_MBUTTON));
     ms.SetRightDown(wxIsKeyDown(VK_RBUTTON));
     ms.SetLeftDown(wxIsKeyDown(VK_LBUTTON));
     ms.SetMiddleDown(wxIsKeyDown(VK_MBUTTON));
     ms.SetRightDown(wxIsKeyDown(VK_RBUTTON));
-
-    ms.SetControlDown(wxIsKeyDown(VK_CONTROL));
-    ms.SetShiftDown(wxIsKeyDown(VK_SHIFT));
-    ms.SetAltDown(wxIsKeyDown(VK_MENU));
+#ifdef wxHAS_XBUTTON
+    ms.SetAux1Down(wxIsKeyDown(VK_XBUTTON1));
+    ms.SetAux2Down(wxIsKeyDown(VK_XBUTTON2));
+#endif // wxHAS_XBUTTON
+
+    ms.SetControlDown(wxIsCtrlDown ());
+    ms.SetShiftDown  (wxIsShiftDown());
+    ms.SetAltDown    (wxIsAltDown  ());
 //    ms.SetMetaDown();
 
     return ms;
 //    ms.SetMetaDown();
 
     return ms;
@@ -5829,7 +6220,7 @@ wxWindow *wxGetActiveWindow()
     HWND hWnd = GetActiveWindow();
     if ( hWnd != 0 )
     {
     HWND hWnd = GetActiveWindow();
     if ( hWnd != 0 )
     {
-        return wxFindWinFromHandle((WXHWND) hWnd);
+        return wxFindWinFromHandle(hWnd);
     }
     return NULL;
 }
     }
     return NULL;
 }
@@ -5844,7 +6235,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
     wxWindow *win = (wxWindow *)NULL;
     if ( hwnd )
     {
     wxWindow *win = (wxWindow *)NULL;
     if ( hwnd )
     {
-        win = wxFindWinFromHandle((WXHWND)hwnd);
+        win = wxFindWinFromHandle(hwnd);
         if ( !win )
         {
 #if wxUSE_RADIOBOX
         if ( !win )
         {
 #if wxUSE_RADIOBOX
@@ -5888,7 +6279,7 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
 #endif
 
         hwnd = ::GetParent(hwnd);
 #endif
 
         hwnd = ::GetParent(hwnd);
-        win = wxFindWinFromHandle((WXHWND)hwnd);
+        win = wxFindWinFromHandle(hwnd);
     }
 
     return win;
     }
 
     return win;
@@ -6144,6 +6535,9 @@ const wxChar *wxGetMessageName(int message)
         case 0x0208: return wxT("WM_MBUTTONUP");
         case 0x0209: return wxT("WM_MBUTTONDBLCLK");
         case 0x020A: return wxT("WM_MOUSEWHEEL");
         case 0x0208: return wxT("WM_MBUTTONUP");
         case 0x0209: return wxT("WM_MBUTTONDBLCLK");
         case 0x020A: return wxT("WM_MOUSEWHEEL");
+        case 0x020B: return wxT("WM_XBUTTONDOWN");
+        case 0x020C: return wxT("WM_XBUTTONUP");
+        case 0x020D: return wxT("WM_XBUTTONDBLCLK");
         case 0x0210: return wxT("WM_PARENTNOTIFY");
         case 0x0211: return wxT("WM_ENTERMENULOOP");
         case 0x0212: return wxT("WM_EXITMENULOOP");
         case 0x0210: return wxT("WM_PARENTNOTIFY");
         case 0x0211: return wxT("WM_ENTERMENULOOP");
         case 0x0212: return wxT("WM_EXITMENULOOP");
@@ -6578,7 +6972,7 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
     event.m_altDown = (win_modifiers & MOD_ALT) != 0;
     event.m_metaDown = (win_modifiers & MOD_WIN) != 0;
 
     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
 }
 
 #endif // wxUSE_ACCEL