]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
remove incorrect cast of wxString to char* (unnecessary and breaks wxUSE_STL build)
[wxWidgets.git] / src / msw / window.cpp
index a68f7b7dfdf2e53430ddd42792ba7ce6cb105619..0caca386a952d5dff425cf371737b06465ea1d6f 100644 (file)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/msw/windows.cpp
-// Purpose:     wxWindow
+// Name:        src/msw/window.cpp
+// Purpose:     wxWindowMSW
 // Author:      Julian Smart
 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
 // Created:     04/01/98
 // Author:      Julian Smart
 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
 // Created:     04/01/98
 // headers
 // ---------------------------------------------------------------------------
 
 // headers
 // ---------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "window.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
     #pragma hdrstop
 #endif
 
     #pragma hdrstop
 #endif
 
+#include "wx/window.h"
+
 #ifndef WX_PRECOMP
     #include "wx/msw/wrapwin.h"
 #ifndef WX_PRECOMP
     #include "wx/msw/wrapwin.h"
-    #include "wx/window.h"
+    #include "wx/msw/wrapcctl.h" // include <commctrl.h> "properly"
+    #include "wx/msw/missing.h"
     #include "wx/accel.h"
     #include "wx/accel.h"
-    #include "wx/setup.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/dcclient.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/dcclient.h"
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
     #include "wx/statbox.h"
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
     #include "wx/statbox.h"
+    #include "wx/sizer.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
+    #include "wx/textctrl.h"
+    #include "wx/menuitem.h"
+    #include "wx/module.h"
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
     #include "wx/ownerdrw.h"
 #endif
 
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
     #include "wx/ownerdrw.h"
 #endif
 
-#include "wx/module.h"
+#include "wx/hashmap.h"
+#include "wx/evtloop.h"
+#include "wx/power.h"
+#include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
 
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
     #endif
 #endif
 
     #endif
 #endif
 
-#include "wx/menuitem.h"
-#include "wx/log.h"
-
 #include "wx/msw/private.h"
 #include "wx/msw/private.h"
+#include "wx/msw/dcclient.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/tooltip.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/tooltip.h"
     #include "wx/spinctrl.h"
 #endif // wxUSE_SPINCTRL
 
     #include "wx/spinctrl.h"
 #endif // wxUSE_SPINCTRL
 
-#include "wx/intl.h"
-#include "wx/log.h"
-
-#include "wx/textctrl.h"
 #include "wx/notebook.h"
 #include "wx/listctrl.h"
 #include "wx/notebook.h"
 #include "wx/listctrl.h"
+#include "wx/dynlib.h"
 
 #include <string.h>
 
 
 #include <string.h>
 
     #include <windowsx.h>
 #endif
 
     #include <windowsx.h>
 #endif
 
-#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__)
-    #ifdef __WIN95__
-        #include <commctrl.h>
-    #endif
-#elif !defined(__WXMICROWIN__) && !defined(__WXWINCE__) // broken compiler
-    #include "wx/msw/gnuwin32/extra.h"
+#if !defined __WXWINCE__ && !defined NEED_PBT_H
+    #include <pbt.h>
 #endif
 
 #endif
 
-#include "wx/msw/missing.h"
-
 #if defined(__WXWINCE__)
 #if defined(__WXWINCE__)
-#include "wx/msw/wince/missing.h"
+    #include "wx/msw/wince/missing.h"
+#ifdef __POCKETPC__
+    #include <windows.h>
+    #include <shellapi.h>
+    #include <ole2.h>
+    #include <aygshell.h>
+#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 this is set to 1, we use deferred window sizing to reduce flicker when
+// resizing complicated window hierarchies, but this can in theory result in
+// different behaviour than the old code so we keep the possibility to use it
+// by setting this to 0 (in the future this should be removed completely)
+#ifdef __WXWINCE__
+#define USE_DEFERRED_SIZING 0
+#else
+#define USE_DEFERRED_SIZING 1
+#endif
+
+// set this to 1 to filter out duplicate mouse events, e.g. mouse move events
+// when mouse position didnd't change
+#ifdef __WXWINCE__
+    #define wxUSE_MOUSEEVENT_HACK 0
+#else
+    #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
 
 // ---------------------------------------------------------------------------
 #endif
 
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 
 #if wxUSE_MENUS_NATIVE
 // ---------------------------------------------------------------------------
 
 #if wxUSE_MENUS_NATIVE
-wxMenu *wxCurrentPopupMenu = NULL;
-#endif // wxUSE_MENUS_NATIVE
-
-#ifdef __WXWINCE__
-extern       wxChar *wxCanvasClassName;
-#else
-extern const wxChar *wxCanvasClassName;
+extern wxMenu *wxCurrentPopupMenu;
 #endif
 
 // true if we had already created the std colour map, used by
 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT)
 static bool gs_hasStdCmap = false;
 
 #endif
 
 // true if we had already created the std colour map, used by
 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT)
 static bool gs_hasStdCmap = false;
 
+// last mouse event information we need to filter out the duplicates
+#if wxUSE_MOUSEEVENT_HACK
+static struct MouseEventInfoDummy
+{
+    // mouse position (in screen coordinates)
+    wxPoint pos;
+
+    // last mouse event type
+    wxEventType type;
+} gs_lastMouseEvent;
+#endif // wxUSE_MOUSEEVENT_HACK
+
+// hash containing the registered handlers for the custom messages
+WX_DECLARE_HASH_MAP(int, wxWindow::MSWMessageHandler,
+                    wxIntegerHash, wxIntegerEqual,
+                    MSWMessageHandlers);
+
+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
 // ---------------------------------------------------------------------------
@@ -148,23 +223,19 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
 
 
 #ifdef  __WXDEBUG__
 
 
 #ifdef  __WXDEBUG__
-    const char *wxGetMessageName(int message);
+    const wxChar *wxGetMessageName(int message);
 #endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
 #endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
-wxWindow *wxFindWinFromHandle(WXHWND hWnd);
-
-// this magical function is used to translate VK_APPS key presses to right
-// mouse clicks
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
-                                     int *x, int *y, WPARAM *flags);
 
 // 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);
 
+#ifdef __WXWINCE__
 // find the window for the mouse event at the specified position
 // find the window for the mouse event at the specified position
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y); //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y);
+#endif // __WXWINCE__
 
 // wrapper around BringWindowToTop() API
 static inline void wxBringWindowToTop(HWND hwnd)
 
 // wrapper around BringWindowToTop() API
 static inline void wxBringWindowToTop(HWND hwnd)
@@ -200,16 +271,15 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
        get back to the initial (focused) window: as we do have this style,
        GetNextDlgTabItem() will leave this window and continue in its parent,
        but if the parent doesn't have it, it wouldn't recurse inside it later
        get back to the initial (focused) window: as we do have this style,
        GetNextDlgTabItem() will leave this window and continue in its parent,
        but if the parent doesn't have it, it wouldn't recurse inside it later
-       on and so wouldn't have a chance of getting back to this window neither.
+       on and so wouldn't have a chance of getting back to this window either.
      */
     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();
@@ -218,6 +288,21 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
 
 #endif // !__WXWINCE__
 
 
 #endif // !__WXWINCE__
 
+#ifdef __WXWINCE__
+// On Windows CE, GetCursorPos can return an error, so use this function
+// instead
+bool GetCursorPosWinCE(POINT* pt)
+{
+    if (!GetCursorPos(pt))
+    {
+        DWORD pos = GetMessagePos();
+        pt->x = LOWORD(pos);
+        pt->y = HIWORD(pos);
+    }
+    return true;
+}
+#endif
+
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
@@ -292,7 +377,7 @@ wxBEGIN_PROPERTIES_TABLE(wxWindow)
     // Always constructor Properties first
 
     wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
     // Always constructor Properties first
 
     wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( Id,wxWindowID, SetId, GetId, wxID_ANY, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
+    wxPROPERTY( Id,wxWindowID, SetId, GetId, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
     wxPROPERTY( Position,wxPoint, SetPosition , GetPosition, wxDefaultPosition , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos
     wxPROPERTY( Size,wxSize, SetSize, GetSize, wxDefaultSize , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size
     wxPROPERTY( WindowStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
     wxPROPERTY( Position,wxPoint, SetPosition , GetPosition, wxDefaultPosition , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos
     wxPROPERTY( Size,wxSize, SetSize, GetSize, wxDefaultSize , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size
     wxPROPERTY( WindowStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
@@ -310,9 +395,9 @@ wxBEGIN_PROPERTIES_TABLE(wxWindow)
     wxPROPERTY( Shown , bool , Show , IsShown , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
 #if 0
     // possible property candidates (not in xrc) or not valid in all subclasses
     wxPROPERTY( Shown , bool , Show , IsShown , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
 #if 0
     // possible property candidates (not in xrc) or not valid in all subclasses
-    wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxT("") )
+    wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxEmptyString )
     wxPROPERTY( Font , wxFont , SetFont , GetWindowFont  , )
     wxPROPERTY( Font , wxFont , SetFont , GetWindowFont  , )
-    wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxT("") )
+    wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxEmptyString )
     // MaxHeight, Width , MinHeight , Width
     // TODO switch label to control and title to toplevels
 
     // MaxHeight, Width , MinHeight , Width
     // TODO switch label to control and title to toplevels
 
@@ -337,8 +422,8 @@ wxCONSTRUCTOR_DUMMY(wxWindow)
 #endif // __WXUNIVERSAL__/__WXMSW__
 
 BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
 #endif // __WXUNIVERSAL__/__WXMSW__
 
 BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
-    EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
+    EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
 #ifdef __WXWINCE__
     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
 #endif
 #ifdef __WXWINCE__
     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
 #endif
@@ -359,7 +444,7 @@ wxWindow *wxWindowMSW::FindItem(long id) const
     wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
     wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
-        // is it we or one of our "internal" children?
+        // is it us or one of our "internal" children?
         if ( item->GetId() == id
 #ifndef __WXUNIVERSAL__
                 || (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
         if ( item->GetId() == id
 #ifndef __WXUNIVERSAL__
                 || (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
@@ -433,33 +518,28 @@ bool wxWindowMSW::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
 void wxWindowMSW::Init()
 {
     // MSW specific
 void wxWindowMSW::Init()
 {
     // MSW specific
-    m_isBeingDeleted = false;
     m_oldWndProc = NULL;
     m_mouseInWindow = false;
     m_lastKeydownProcessed = false;
 
     m_oldWndProc = NULL;
     m_mouseInWindow = false;
     m_lastKeydownProcessed = false;
 
-    m_childrenDisabled = NULL;
-    m_frozenness = 0;
-
-    // wxWnd
-    m_hMenu = 0;
-
     m_hWnd = 0;
     m_hWnd = 0;
+    m_hDWP = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
 
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
 
-#if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX =
-    m_lastMouseY = -1;
-    m_lastMouseEvent = -1;
-#endif // wxUSE_MOUSEEVENT_HACK
+    m_pendingPosition = wxDefaultPosition;
+    m_pendingSize = wxDefaultSize;
+
+#ifdef __POCKETPC__
+    m_contextMenuEnabled = false;
+#endif
 }
 
 // Destructor
 wxWindowMSW::~wxWindowMSW()
 {
 }
 
 // Destructor
 wxWindowMSW::~wxWindowMSW()
 {
-    m_isBeingDeleted = true;
+    SendDestroyEvent();
 
 #ifndef __WXUNIVERSAL__
     // VS: make sure there's no wxFrame with last focus set to us:
 
 #ifndef __WXUNIVERSAL__
     // VS: make sure there's no wxFrame with last focus set to us:
@@ -472,13 +552,18 @@ wxWindowMSW::~wxWindowMSW()
             {
                 frame->SetLastFocus(NULL);
             }
             {
                 frame->SetLastFocus(NULL);
             }
-            break;
+
+            // apparently sometimes we can end up with our grand parent
+            // pointing to us as well: this is surely a bug in focus handling
+            // code but it's not clear where it happens so for now just try to
+            // fix it here by not breaking out of the loop
+            //break;
         }
     }
 #endif // __WXUNIVERSAL__
 
     // VS: destroy children first and _then_ detach *this from its parent.
         }
     }
 #endif // __WXUNIVERSAL__
 
     // VS: destroy children first and _then_ detach *this from its parent.
-    //     If we'd do it the other way around, children wouldn't be able
+    //     If we did it the other way around, children wouldn't be able
     //     find their parent frame (see above).
     DestroyChildren();
 
     //     find their parent frame (see above).
     DestroyChildren();
 
@@ -495,7 +580,12 @@ wxWindowMSW::~wxWindowMSW()
         wxRemoveHandleAssociation(this);
     }
 
         wxRemoveHandleAssociation(this);
     }
 
-    delete m_childrenDisabled;
+}
+
+/* static */
+const wxChar *wxWindowMSW::MSWGetRegisteredClassName()
+{
+    return wxApp::GetRegisteredClassName(_T("wxWindow"), COLOR_BTNFACE);
 }
 
 // real construction (Init() must have been called before!)
 }
 
 // real construction (Init() must have been called before!)
@@ -530,7 +620,8 @@ bool wxWindowMSW::Create(wxWindow *parent,
         msflags |= WS_VISIBLE;
     }
 
         msflags |= WS_VISIBLE;
     }
 
-    if ( !MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle) )
+    if ( !MSWCreate(MSWGetRegisteredClassName(),
+                    NULL, pos, size, msflags, exstyle) )
         return false;
 
     InheritAttributes();
         return false;
 
     InheritAttributes();
@@ -586,7 +677,7 @@ void wxWindowMSW::SetFocusFromKbd()
 }
 
 // Get the window with the focus
 }
 
 // Get the window with the focus
-wxWindow *wxWindowBase::FindFocus()
+wxWindow *wxWindowBase::DoFindFocus()
 {
     HWND hWnd = ::GetFocus();
     if ( hWnd )
 {
     HWND hWnd = ::GetFocus();
     if ( hWnd )
@@ -597,83 +688,141 @@ wxWindow *wxWindowBase::FindFocus()
     return NULL;
 }
 
     return NULL;
 }
 
-bool wxWindowMSW::Enable(bool enable)
+void wxWindowMSW::DoEnable( bool enable )
 {
 {
-    if ( !wxWindowBase::Enable(enable) )
-        return false;
-
     HWND hWnd = GetHwnd();
     if ( hWnd )
         ::EnableWindow(hWnd, (BOOL)enable);
     HWND hWnd = GetHwnd();
     if ( hWnd )
         ::EnableWindow(hWnd, (BOOL)enable);
+}
 
 
-    // the logic below doesn't apply to the top level windows -- otherwise
-    // showing a modal dialog would result in total greying out (and ungreying
-    // out later) of everything which would be really ugly
-    if ( IsTopLevel() )
-        return true;
-
-    // when the parent is disabled, all of its children should be disabled as
-    // well but when it is enabled back, only those of the children which
-    // hadn't been already disabled in the beginning should be enabled again,
-    // so we have to keep the list of those children
-    for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
-          node;
-          node = node->GetNext() )
-    {
-        wxWindow *child = node->GetData();
-        if ( child->IsTopLevel() )
-        {
-            // the logic below doesn't apply to top level children
-            continue;
-        }
+bool wxWindowMSW::Show(bool show)
+{
+    if ( !wxWindowBase::Show(show) )
+        return false;
 
 
-        if ( enable )
-        {
-            // enable the child back unless it had been disabled before us
-            if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
-                child->Enable();
-        }
-        else // we're being disabled
-        {
-            if ( child->IsEnabled() )
-            {
-                // disable it as children shouldn't stay enabled while the
-                // parent is not
-                child->Disable();
-            }
-            else // child already disabled, remember it
-            {
-                // have we created the list of disabled children already?
-                if ( !m_childrenDisabled )
-                    m_childrenDisabled = new wxWindowList;
+    HWND hWnd = GetHwnd();
 
 
-                m_childrenDisabled->Append(child);
-            }
-        }
+    // we could be called before the underlying window is created (this is
+    // actually useful to prevent it from being initially shown), e.g.
+    //
+    //      wxFoo *foo = new wxFoo;
+    //      foo->Hide();
+    //      foo->Create(parent, ...);
+    //
+    // should work without errors
+    if ( hWnd )
+    {
+        ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
     }
 
     }
 
-    if ( enable && m_childrenDisabled )
+    if ( IsFrozen() )
     {
     {
-        // we don't need this list any more, don't keep unused memory
-        delete m_childrenDisabled;
-        m_childrenDisabled = NULL;
+        // 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;
 }
 
     }
 
     return true;
 }
 
-bool wxWindowMSW::Show(bool show)
+bool
+wxWindowMSW::MSWShowWithEffect(bool show,
+                               wxShowEffect effect,
+                               unsigned timeout)
 {
     if ( !wxWindowBase::Show(show) )
         return false;
 
 {
     if ( !wxWindowBase::Show(show) )
         return false;
 
-    HWND hWnd = GetHwnd();
-    int cshow = show ? SW_SHOW : SW_HIDE;
-    ::ShowWindow(hWnd, cshow);
+    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;
 
 
-    if ( show && IsTopLevel() )
+
+        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) )
     {
     {
-        wxBringWindowToTop(hWnd);
+        wxLogLastError(_T("AnimateWindow"));
+
+        return false;
     }
 
     return true;
     }
 
     return true;
@@ -692,16 +841,6 @@ void wxWindowMSW::Lower()
                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 }
 
                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 }
 
-void wxWindowMSW::SetTitle( const wxString& title)
-{
-    SetWindowText(GetHwnd(), title.c_str());
-}
-
-wxString wxWindowMSW::GetTitle() const
-{
-    return wxGetWindowText(GetHWND());
-}
-
 void wxWindowMSW::DoCaptureMouse()
 {
     HWND hWnd = GetHwnd();
 void wxWindowMSW::DoCaptureMouse()
 {
     HWND hWnd = GetHwnd();
@@ -722,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)
@@ -736,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") );
 
@@ -753,24 +896,39 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
         return false;
     }
 
         return false;
     }
 
-    if ( m_cursor.Ok() )
+    // don't "overwrite" busy cursor
+    if ( m_cursor.Ok() && !wxIsBusy() )
     {
     {
-        HWND hWnd = GetHwnd();
+        // normally we should change the cursor only if it's over this window
+        // but we should do it always if we capture the mouse currently
+        bool set = HasCapture();
+        if ( !set )
+        {
+            HWND hWnd = GetHwnd();
 
 
-        // Change the cursor NOW if we're within the correct window
-        POINT point;
-        ::GetCursorPos(&point);
+            POINT point;
+#ifdef __WXWINCE__
+            ::GetCursorPosWinCE(&point);
+#else
+            ::GetCursorPos(&point);
+#endif
+
+            RECT rect = wxGetWindowRect(hWnd);
 
 
-        RECT rect = wxGetWindowRect(hWnd);
+            set = ::PtInRect(&rect, point) != 0;
+        }
 
 
-        if ( ::PtInRect(&rect, point) && !wxIsBusy() )
+        if ( set )
+        {
             ::SetCursor(GetHcursorOf(m_cursor));
             ::SetCursor(GetHcursorOf(m_cursor));
+        }
+        //else: will be set later when the mouse enters this window
     }
 
     return true;
 }
 
     }
 
     return true;
 }
 
-void wxWindowMSW::WarpPointer (int x, int y)
+void wxWindowMSW::WarpPointer(int x, int y)
 {
     ClientToScreen(&x, &y);
 
 {
     ClientToScreen(&x, &y);
 
@@ -780,15 +938,32 @@ void wxWindowMSW::WarpPointer (int x, int y)
     }
 }
 
     }
 }
 
+void wxWindowMSW::MSWUpdateUIState(int action, int state)
+{
+    // WM_CHANGEUISTATE only appeared in Windows 2000 so it can do us no good
+    // to use it on older systems -- and could possibly do some harm
+    static int s_needToUpdate = -1;
+    if ( s_needToUpdate == -1 )
+    {
+        int verMaj, verMin;
+        s_needToUpdate = wxGetOsVersion(&verMaj, &verMin) == wxOS_WINDOWS_NT &&
+                            verMaj >= 5;
+    }
+
+    if ( s_needToUpdate )
+    {
+        // we send WM_CHANGEUISTATE so if nothing needs changing then the system
+        // won't send WM_UPDATEUISTATE
+        ::SendMessage(GetHwnd(), WM_CHANGEUISTATE, MAKEWPARAM(action, state), 0);
+    }
+}
+
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
 
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
 
-// convert wxHORIZONTAL/wxVERTICAL to SB_HORZ/SB_VERT
-static inline int wxDirToWinStyle(int orient)
+namespace
 {
 {
-    return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
-}
 
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
 
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
@@ -798,24 +973,26 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
-    if ( !::GetScrollInfo(hWnd,
-                          wOrient,
-                          &scrollInfo) )
-    {
-        // Not neccessarily an error, if there are no scrollbars yet.
-        // wxLogLastError(_T("GetScrollInfo"));
-    }
+    ::GetScrollInfo(hWnd, wOrient, &scrollInfo );
+
     return scrollInfo.nPos;
     return scrollInfo.nPos;
-//    return ::GetScrollPos(hWnd, wOrient);
+
 #endif
 }
 
 #endif
 }
 
+inline UINT WXOrientToSB(int orient)
+{
+    return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
+}
+
+} // anonymous namespace
+
 int wxWindowMSW::GetScrollPos(int orient) const
 {
     HWND hWnd = GetHwnd();
     wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
 
 int wxWindowMSW::GetScrollPos(int orient) const
 {
     HWND hWnd = GetHwnd();
     wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
 
-    return GetScrollPosition(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT);
+    return GetScrollPosition(hWnd, WXOrientToSB(orient));
 }
 
 // This now returns the whole range, not just the number
 }
 
 // This now returns the whole range, not just the number
@@ -826,15 +1003,9 @@ int wxWindowMSW::GetScrollRange(int orient) const
     HWND hWnd = GetHwnd();
     if ( !hWnd )
         return 0;
     HWND hWnd = GetHwnd();
     if ( !hWnd )
         return 0;
-#if 0
-    ::GetScrollRange(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                     &minPos, &maxPos);
-#endif
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.fMask = SIF_RANGE;
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.fMask = SIF_RANGE;
-    if ( !::GetScrollInfo(hWnd,
-                          orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                          &scrollInfo) )
+    if ( !::GetScrollInfo(hWnd, WXOrientToSB(orient), &scrollInfo) )
     {
         // Most of the time this is not really an error, since the return
         // value can also be zero when there is no scrollbar yet.
     {
         // Most of the time this is not really an error, since the return
         // value can also be zero when there is no scrollbar yet.
@@ -867,8 +1038,7 @@ void wxWindowMSW::SetScrollPos(int orient, int pos, bool refresh)
         info.fMask |= SIF_DISABLENOSCROLL;
     }
 
         info.fMask |= SIF_DISABLENOSCROLL;
     }
 
-    ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                    &info, refresh);
+    ::SetScrollInfo(hWnd, WXOrientToSB(orient), &info, refresh);
 }
 
 // New function that will replace some of the above.
 }
 
 // New function that will replace some of the above.
@@ -878,26 +1048,37 @@ void wxWindowMSW::SetScrollbar(int orient,
                                int range,
                                bool refresh)
 {
                                int range,
                                bool refresh)
 {
+    // We have to set the variables here to make them valid in events
+    // triggered by ::SetScrollInfo()
+    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
+
+    HWND hwnd = GetHwnd();
+    if ( !hwnd )
+        return;
+
     WinStruct<SCROLLINFO> info;
     WinStruct<SCROLLINFO> info;
-    info.nPage = pageSize;
-    info.nMin = 0;              // range is nMax - nMin + 1
-    info.nMax = range - 1;      //  as both nMax and nMax are inclusive
-    info.nPos = pos;
-    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
-    if ( HasFlag(wxALWAYS_SHOW_SB) )
+    if ( range != -1 )
     {
     {
-        // disable scrollbar instead of removing it then
-        info.fMask |= SIF_DISABLENOSCROLL;
+        info.nPage = pageSize;
+        info.nMin = 0;              // range is nMax - nMin + 1
+        info.nMax = range - 1;      //  as both nMax and nMax are inclusive
+        info.nPos = pos;
+
+        // enable the scrollbar if it had been disabled before by specifying
+        // SIF_DISABLENOSCROLL below: as we can't know whether this had been
+        // done or not just do it always
+        ::EnableScrollBar(hwnd, WXOrientToSB(orient), ESB_ENABLE_BOTH);
     }
     }
+    //else: leave all the fields to be 0
 
 
-    HWND hWnd = GetHwnd();
-    if ( hWnd )
+    info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
+    if ( HasFlag(wxALWAYS_SHOW_SB) || range == -1 )
     {
     {
-        ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
-                        &info, refresh);
+        // disable scrollbar instead of removing it then
+        info.fMask |= SIF_DISABLENOSCROLL;
     }
 
     }
 
-    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
+    ::SetScrollInfo(hwnd, WXOrientToSB(orient), &info, refresh);
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -906,10 +1087,7 @@ void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
     RECT *pr;
     if ( prect )
     {
     RECT *pr;
     if ( prect )
     {
-        rect.left = prect->x;
-        rect.top = prect->y;
-        rect.right = prect->x + prect->width;
-        rect.bottom = prect->y + prect->height;
+        wxCopyRectToRECT(*prect, rect);
         pr = &rect;
     }
     else
         pr = &rect;
     }
     else
@@ -966,6 +1144,65 @@ bool wxWindowMSW::ScrollPages(int pages)
                             down ? pages : -pages);
 }
 
                             down ? pages : -pages);
 }
 
+// ----------------------------------------------------------------------------
+// RTL support
+// ----------------------------------------------------------------------------
+
+void wxWindowMSW::SetLayoutDirection(wxLayoutDirection dir)
+{
+#ifdef __WXWINCE__
+    wxUnusedVar(dir);
+#else
+    wxCHECK_RET( GetHwnd(),
+                 _T("layout direction must be set after window creation") );
+
+    LONG styleOld = wxGetWindowExStyle(this);
+
+    LONG styleNew = styleOld;
+    switch ( dir )
+    {
+        case wxLayout_LeftToRight:
+            styleNew &= ~WS_EX_LAYOUTRTL;
+            break;
+
+        case wxLayout_RightToLeft:
+            styleNew |= WS_EX_LAYOUTRTL;
+            break;
+
+        default:
+            wxFAIL_MSG(_T("unsupported layout direction"));
+            break;
+    }
+
+    if ( styleNew != styleOld )
+    {
+        wxSetWindowExStyle(this, styleNew);
+    }
+#endif
+}
+
+wxLayoutDirection wxWindowMSW::GetLayoutDirection() const
+{
+#ifdef __WXWINCE__
+    return wxLayout_Default;
+#else
+    wxCHECK_MSG( GetHwnd(), wxLayout_Default, _T("invalid window") );
+
+    return wxHasWindowExStyle(this, WS_EX_LAYOUTRTL) ? wxLayout_RightToLeft
+                                                     : wxLayout_LeftToRight;
+#endif
+}
+
+wxCoord
+wxWindowMSW::AdjustForLayoutDirection(wxCoord x,
+                                      wxCoord WXUNUSED(width),
+                                      wxCoord WXUNUSED(widthTotal)) const
+{
+    // Win32 mirrors the coordinates of RTL windows automatically, so don't
+    // redo it ourselves
+    return x;
+}
+
 // ---------------------------------------------------------------------------
 // subclassing
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // subclassing
 // ---------------------------------------------------------------------------
@@ -977,6 +1214,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);
@@ -989,12 +1228,16 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     }
     else
     {
     }
     else
     {
-        // don't bother restoring it neither: this also makes it easy to
+        // don't bother restoring it either: this also makes it easy to
         // implement IsOfStandardClass() method which returns true for the
         // standard controls and false for the wxWidgets own windows as it can
         // simply check m_oldWndProc
         m_oldWndProc = NULL;
     }
         // implement IsOfStandardClass() method which returns true for the
         // standard controls and false for the wxWidgets own windows as it can
         // simply check m_oldWndProc
         m_oldWndProc = NULL;
     }
+
+    // we're officially created now, send the event
+    wxWindowCreateEvent event((wxWindow *)this);
+    (void)HandleWindowEvent(event);
 }
 
 void wxWindowMSW::UnsubclassWin()
 }
 
 void wxWindowMSW::UnsubclassWin()
@@ -1031,7 +1274,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);
 }
 
@@ -1042,46 +1285,15 @@ void wxWindowMSW::DissociateHandle()
 }
 
 
 }
 
 
-bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
+bool wxCheckWindowWndProc(WXHWND hWnd,
+                          WXFARPROC WXUNUSED(wndProc))
 {
 {
-    // Unicows note: the code below works, but only because WNDCLASS contains
-    // original window handler rather that the unicows fake one. This may not
-    // be on purpose, though; if it stops working with future versions of
-    // unicows.dll, we can override unicows hooks by setting
-    // Unicows_{Set,Get}WindowLong and Unicows_RegisterClass to our own
-    // versions that keep track of fake<->real wnd proc mapping.
-
-    // On WinCE (at least), the wndproc comparison doesn't work,
-    // so have to use something like this.
-#ifdef __WXWINCE__
-    extern       wxChar *wxCanvasClassName;
-    extern       wxChar *wxCanvasClassNameNR;
-    extern const wxChar *wxMDIFrameClassName;
-    extern const wxChar *wxMDIFrameClassNameNoRedraw;
-    extern const wxChar *wxMDIChildFrameClassName;
-    extern const wxChar *wxMDIChildFrameClassNameNoRedraw;
-    wxString str(wxGetWindowClass(hWnd));
-    if (str == wxCanvasClassName ||
-        str == wxCanvasClassNameNR ||
-        str == wxMDIFrameClassName ||
-        str == wxMDIFrameClassNameNoRedraw ||
-        str == wxMDIChildFrameClassName ||
-        str == wxMDIChildFrameClassNameNoRedraw ||
-        str == _T("wxTLWHiddenParent"))
-        return true; // Effectively means don't subclass
-    else
-        return false;
-#else
-    WNDCLASS cls;
-    if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
-    {
-        wxLogLastError(_T("GetClassInfo"));
-
-        return false;
-    }
+    const wxString str(wxGetWindowClass(hWnd));
 
 
-    return wndProc == (WXFARPROC)cls.lpfnWndProc;
-#endif
+    // TODO: get rid of wxTLWHiddenParent special case (currently it's not
+    //       registered by wxApp but using ad hoc code in msw/toplevel.cpp);
+    //       there is also a hidden window class used by sockets &c
+    return wxApp::IsRegisteredClassName(str) || str == _T("wxTLWHiddenParent");
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -1097,14 +1309,48 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
     // update the internal variable
     wxWindowBase::SetWindowStyleFlag(flags);
 
     // update the internal variable
     wxWindowBase::SetWindowStyleFlag(flags);
 
+    // and the real window flags
+    MSWUpdateStyle(flagsOld, GetExtraStyle());
+}
+
+void wxWindowMSW::SetExtraStyle(long exflags)
+{
+    long exflagsOld = GetExtraStyle();
+    if ( exflags == exflagsOld )
+        return;
+
+    // update the internal variable
+    wxWindowBase::SetExtraStyle(exflags);
+
+    // and the real window flags
+    MSWUpdateStyle(GetWindowStyleFlag(), exflagsOld);
+}
+
+void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
+{
     // now update the Windows style as well if needed - and if the window had
     // been already created
     if ( !GetHwnd() )
         return;
 
     // now update the Windows style as well if needed - and if the window had
     // been already created
     if ( !GetHwnd() )
         return;
 
-    WXDWORD exstyle, exstyleOld;
-    long style = MSWGetStyle(flags, &exstyle),
-         styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+    // we may need to call SetWindowPos() when we change some styles
+    bool callSWP = false;
+
+    WXDWORD exstyle;
+    long style = MSWGetStyle(GetWindowStyleFlag(), &exstyle);
+
+    // this is quite a horrible hack but we need it because MSWGetStyle()
+    // doesn't take exflags as parameter but uses GetExtraStyle() internally
+    // and so we have to modify the window exflags temporarily to get the
+    // correct exstyleOld
+    long exflagsNew = GetExtraStyle();
+    wxWindowBase::SetExtraStyle(exflagsOld);
+
+    WXDWORD exstyleOld;
+    long styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+
+    wxWindowBase::SetExtraStyle(exflagsNew);
+
 
     if ( style != styleOld )
     {
 
     if ( style != styleOld )
     {
@@ -1117,31 +1363,85 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
         styleReal |= style;
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
         styleReal |= style;
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
+
+        // we need to call SetWindowPos() if any of the styles affecting the
+        // frame appearance have changed
+        callSWP = ((styleOld ^ style ) & (WS_BORDER |
+                                      WS_THICKFRAME |
+                                      WS_CAPTION |
+                                      WS_DLGFRAME |
+                                      WS_MAXIMIZEBOX |
+                                      WS_MINIMIZEBOX |
+                                      WS_SYSMENU) ) != 0;
     }
 
     // and the extended style
     }
 
     // and the extended style
+    long exstyleReal = wxGetWindowExStyle(this);
+
     if ( exstyle != exstyleOld )
     {
     if ( exstyle != exstyleOld )
     {
-        long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
-        ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
+        wxSetWindowExStyle(this, exstyleReal);
 
 
-        // we must call SetWindowPos() to flash the cached extended style and
-        // also to make the change to wxSTAY_ON_TOP style take effect: just
+        // ex style changes don't take effect without calling SetWindowPos
+        callSWP = true;
+    }
+
+    if ( callSWP )
+    {
+        // we must call SetWindowPos() to flush the cached extended style and
+        // also to make the change to wxSTAY_ON_TOP style take effect: just
         // setting the style simply doesn't work
         if ( !::SetWindowPos(GetHwnd(),
                              exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
                                                          : HWND_NOTOPMOST,
                              0, 0, 0, 0,
         // setting the style simply doesn't work
         if ( !::SetWindowPos(GetHwnd(),
                              exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
                                                          : HWND_NOTOPMOST,
                              0, 0, 0, 0,
-                             SWP_NOMOVE | SWP_NOSIZE) )
+                             SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED) )
         {
             wxLogLastError(_T("SetWindowPos"));
         }
     }
 }
 
         {
             wxLogLastError(_T("SetWindowPos"));
         }
     }
 }
 
+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
@@ -1150,11 +1450,20 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle()
     WXDWORD style = WS_CHILD;
 
     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle()
     WXDWORD style = WS_CHILD;
 
-    if ( flags & wxCLIP_CHILDREN )
+    // using this flag results in very significant reduction in flicker,
+    // especially with controls inside the static boxes (as the interior of the
+    // box is not redrawn twice), but sometimes results in redraw problems, so
+    // optionally allow the old code to continue to use it provided a special
+    // system option is turned on
+    if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children"))
+            || (flags & wxCLIP_CHILDREN) )
         style |= WS_CLIPCHILDREN;
 
         style |= WS_CLIPCHILDREN;
 
-    if ( flags & wxCLIP_SIBLINGS )
-        style |= WS_CLIPSIBLINGS;
+    // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially
+    // don't support overlapping windows and it only makes sense for them and,
+    // presumably, gives the system some extra work (to manage more clipping
+    // regions), so avoid it alltogether
+
 
     if ( flags & wxVSCROLL )
         style |= WS_VSCROLL;
 
     if ( flags & wxVSCROLL )
         style |= WS_VSCROLL;
@@ -1162,7 +1471,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 )
@@ -1187,6 +1499,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:
@@ -1202,9 +1515,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
@@ -1232,7 +1545,11 @@ bool wxWindowMSW::IsMouseInWindow() const
 {
     // get the mouse position
     POINT pt;
 {
     // get the mouse position
     POINT pt;
+#ifdef __WXWINCE__
+    ::GetCursorPosWinCE(&pt);
+#else
     ::GetCursorPos(&pt);
     ::GetCursorPos(&pt);
+#endif
 
     // find the window which currently has the cursor and go up the window
     // chain until we find this window - or exhaust it
 
     // find the window which currently has the cursor and go up the window
     // chain until we find this window - or exhaust it
@@ -1245,6 +1562,7 @@ bool wxWindowMSW::IsMouseInWindow() const
 
 void wxWindowMSW::OnInternalIdle()
 {
 
 void wxWindowMSW::OnInternalIdle()
 {
+#ifndef HAVE_TRACKMOUSEEVENT
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
@@ -1252,44 +1570,12 @@ void wxWindowMSW::OnInternalIdle()
         // or doesn't have mouse capture
         if ( !IsMouseInWindow() )
         {
         // or doesn't have mouse capture
         if ( !IsMouseInWindow() )
         {
-            // Generate a LEAVE event
-            m_mouseInWindow = false;
-
-            // Unfortunately the mouse button and keyboard state may have
-            // changed by the time the OnInternalIdle function is called, so 'state'
-            // may be meaningless.
-            int state = 0;
-            if ( wxIsShiftDown() )
-                state |= MK_SHIFT;
-            if ( wxIsCtrlDown() )
-                state |= MK_CONTROL;
-            if ( GetKeyState( VK_LBUTTON ) )
-                state |= MK_LBUTTON;
-            if ( GetKeyState( VK_MBUTTON ) )
-                state |= MK_MBUTTON;
-            if ( GetKeyState( VK_RBUTTON ) )
-                state |= MK_RBUTTON;
-
-            POINT pt;
-            if ( !::GetCursorPos(&pt) )
-            {
-                wxLogLastError(_T("GetCursorPos"));
-            }
-
-            // we need to have client coordinates here for symmetry with
-            // wxEVT_ENTER_WINDOW
-            RECT rect = wxGetWindowRect(GetHwnd());
-            pt.x -= rect.left;
-            pt.y -= rect.top;
-
-            wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-            InitMouseEvent(event2, pt.x, pt.y, state);
-
-            (void)GetEventHandler()->ProcessEvent(event2);
+            GenerateMouseLeave();
         }
     }
         }
     }
+#endif // !HAVE_TRACKMOUSEEVENT
 
 
-    if (wxUpdateUIEvent::CanUpdate(this))
+    if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
@@ -1305,7 +1591,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());
     }
@@ -1321,26 +1607,24 @@ static inline void SendSetRedraw(HWND hwnd, bool on)
 #endif
 }
 
 #endif
 }
 
-void wxWindowMSW::Freeze()
+void wxWindowMSW::DoFreeze()
 {
 {
-    if ( !m_frozenness++ )
-    {
-        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 )
-    {
-        SendSetRedraw(GetHwnd(), true);
+    SendSetRedraw(GetHwnd(), true);
 
 
-        // we need to refresh everything or otherwise he invalidated area is not
-        // 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)
@@ -1348,18 +1632,28 @@ void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
+        RECT mswRect;
+        const RECT *pRect;
         if ( rect )
         {
         if ( rect )
         {
-            RECT mswRect;
-            mswRect.left = rect->x;
-            mswRect.top = rect->y;
-            mswRect.right = rect->x + rect->width;
-            mswRect.bottom = rect->y + rect->height;
-
-            ::InvalidateRect(hWnd, &mswRect, eraseBack);
+            wxCopyRectToRECT(*rect, mswRect);
+            pRect = &mswRect;
         }
         else
         }
         else
-            ::InvalidateRect(hWnd, NULL, eraseBack);
+        {
+            pRect = NULL;
+        }
+
+        // RedrawWindow not available on SmartPhone or eVC++ 3
+#if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
+        UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
+        if ( eraseBack )
+            flags |= RDW_ERASE;
+
+        ::RedrawWindow(hWnd, pRect, NULL, flags);
+#else
+        ::InvalidateRect(hWnd, pRect, eraseBack);
+#endif
     }
 }
 
     }
 }
 
@@ -1381,6 +1675,40 @@ void wxWindowMSW::Update()
 // drag and drop
 // ---------------------------------------------------------------------------
 
 // drag and drop
 // ---------------------------------------------------------------------------
 
+#if wxUSE_DRAG_AND_DROP || !defined(__WXWINCE__)
+
+#if wxUSE_STATBOX
+
+// we need to lower the sibling static boxes so controls contained within can be
+// a drop target
+static void AdjustStaticBoxZOrder(wxWindow *parent)
+{
+    // no sibling static boxes if we have no parent (ie TLW)
+    if ( !parent )
+        return;
+
+    for ( wxWindowList::compatibility_iterator node = parent->GetChildren().GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxStaticBox *statbox = wxDynamicCast(node->GetData(), wxStaticBox);
+        if ( statbox )
+        {
+            ::SetWindowPos(GetHwndOf(statbox), HWND_BOTTOM, 0, 0, 0, 0,
+                           SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+        }
+    }
+}
+
+#else // !wxUSE_STATBOX
+
+static inline void AdjustStaticBoxZOrder(wxWindow * WXUNUSED(parent))
+{
+}
+
+#endif // wxUSE_STATBOX/!wxUSE_STATBOX
+
+#endif // drag and drop is used
 
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
@@ -1392,20 +1720,24 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         m_dropTarget->Register(m_hWnd);
         m_dropTarget->Register(m_hWnd);
+    }
 }
 #endif // wxUSE_DRAG_AND_DROP
 
 }
 #endif // wxUSE_DRAG_AND_DROP
 
-// old style file-manager drag&drop support: we retain the old-style
+// old-style file manager drag&drop support: we retain the old-style
 // DragAcceptFiles in parallel with SetDropTarget.
 // DragAcceptFiles in parallel with SetDropTarget.
-void wxWindowMSW::DragAcceptFiles(bool accept)
+void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept))
 {
 {
-#if !defined(__WXWINCE__)
+#ifndef __WXWINCE__
     HWND hWnd = GetHwnd();
     if ( hWnd )
     HWND hWnd = GetHwnd();
     if ( hWnd )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         ::DragAcceptFiles(hWnd, (BOOL)accept);
         ::DragAcceptFiles(hWnd, (BOOL)accept);
-#else
-    wxUnusedVar(accept);
+    }
 #endif
 }
 
 #endif
 }
 
@@ -1429,66 +1761,128 @@ void wxWindowMSW::DoSetToolTip(wxToolTip *tooltip)
 // moving and resizing
 // ---------------------------------------------------------------------------
 
 // moving and resizing
 // ---------------------------------------------------------------------------
 
+bool wxWindowMSW::IsSizeDeferred() const
+{
+#if USE_DEFERRED_SIZING
+    if ( m_pendingPosition != wxDefaultPosition ||
+         m_pendingSize     != wxDefaultSize )
+        return true;
+#endif // USE_DEFERRED_SIZING
+
+    return false;
+}
+
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
-    RECT rect = wxGetWindowRect(GetHwnd());
+#if USE_DEFERRED_SIZING
+    // if SetSize() had been called at wx level but not realized at Windows
+    // level yet (i.e. EndDeferWindowPos() not called), we still should return
+    // the new and not the old position to the other wx code
+    if ( m_pendingSize != wxDefaultSize )
+    {
+        if ( x )
+            *x = m_pendingSize.x;
+        if ( y )
+            *y = m_pendingSize.y;
+    }
+    else // use current size
+#endif // USE_DEFERRED_SIZING
+    {
+        RECT rect = wxGetWindowRect(GetHwnd());
 
 
-    if ( x )
-        *x = rect.right - rect.left;
-    if ( y )
-        *y = rect.bottom - rect.top;
+        if ( x )
+            *x = rect.right - rect.left;
+        if ( y )
+            *y = rect.bottom - rect.top;
+    }
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
-    RECT rect = wxGetClientRect(GetHwnd());
+#if USE_DEFERRED_SIZING
+    if ( m_pendingSize != wxDefaultSize )
+    {
+        // we need to calculate the client size corresponding to pending size
+        RECT rect;
+        rect.left = m_pendingPosition.x;
+        rect.top = m_pendingPosition.y;
+        rect.right = rect.left + m_pendingSize.x;
+        rect.bottom = rect.top + m_pendingSize.y;
 
 
-    if ( x )
-        *x = rect.right;
-    if ( y )
-        *y = rect.bottom;
+        ::SendMessage(GetHwnd(), WM_NCCALCSIZE, FALSE, (LPARAM)&rect);
+
+        if ( x )
+            *x = rect.right - rect.left;
+        if ( y )
+            *y = rect.bottom - rect.top;
+    }
+    else
+#endif // USE_DEFERRED_SIZING
+    {
+        RECT rect = wxGetClientRect(GetHwnd());
+
+        if ( x )
+            *x = rect.right;
+        if ( y )
+            *y = rect.bottom;
+    }
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
 {
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
 {
-    RECT rect = wxGetWindowRect(GetHwnd());
+    wxWindow * const parent = GetParent();
 
 
-    POINT point;
-    point.x = rect.left;
-    point.y = rect.top;
-
-    // we do the adjustments with respect to the parent only for the "real"
-    // children, not for the dialogs/frames
-    if ( !IsTopLevel() )
+    wxPoint pos;
+    if ( m_pendingPosition != wxDefaultPosition )
+    {
+        pos = m_pendingPosition;
+    }
+    else // use current position
     {
     {
-        HWND hParentWnd = 0;
-        wxWindow *parent = GetParent();
-        if ( parent )
-            hParentWnd = GetWinHwnd(parent);
+        RECT rect = wxGetWindowRect(GetHwnd());
 
 
-        // Since we now have the absolute screen coords, if there's a parent we
-        // must subtract its top left corner
-        if ( hParentWnd )
-        {
-            ::ScreenToClient(hParentWnd, &point);
-        }
+        POINT point;
+        point.x = rect.left;
+        point.y = rect.top;
 
 
-        if ( parent )
+        // we do the adjustments with respect to the parent only for the "real"
+        // children, not for the dialogs/frames
+        if ( !IsTopLevel() )
         {
         {
-            // We may be faking the client origin. So a window that's really at (0,
-            // 30) may appear (to wxWin apps) to be at (0, 0).
-            wxPoint pt(parent->GetClientAreaOrigin());
-            point.x -= pt.x;
-            point.y -= pt.y;
+            if ( wxTheApp->GetLayoutDirection() == wxLayout_RightToLeft )
+            {
+                // In RTL mode, we want the logical left x-coordinate,
+                // which would be the physical right x-coordinate.
+                point.x = rect.right;
+            }
+
+            // Since we now have the absolute screen coords, if there's a
+            // parent we must subtract its top left corner
+            if ( parent )
+            {
+                ::ScreenToClient(GetHwndOf(parent), &point);
+            }
         }
         }
+
+        pos.x = point.x;
+        pos.y = point.y;
+    }
+
+    // we also must adjust by the client area offset: a control which is just
+    // under a toolbar could be at (0, 30) in Windows but at (0, 0) in wx
+    if ( parent && !IsTopLevel() )
+    {
+        const wxPoint pt(parent->GetClientAreaOrigin());
+        pos.x -= pt.x;
+        pos.y -= pt.y;
     }
 
     if ( x )
     }
 
     if ( x )
-        *x = point.x;
+        *x = pos.x;
     if ( y )
     if ( y )
-        *y = point.y;
+        *y = pos.y;
 }
 
 void wxWindowMSW::DoScreenToClient(int *x, int *y) const
 }
 
 void wxWindowMSW::DoScreenToClient(int *x, int *y) const
@@ -1523,6 +1917,50 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
         *y = pt.y;
 }
 
         *y = pt.y;
 }
 
+bool
+wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
+{
+#if USE_DEFERRED_SIZING
+    // if our parent had prepared a defer window handle for us, use it (unless
+    // we are a top level window)
+    wxWindowMSW * const parent = IsTopLevel() ? NULL : GetParent();
+
+    HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
+    if ( hdwp )
+    {
+        hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height,
+                                SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
+        if ( !hdwp )
+        {
+            wxLogLastError(_T("DeferWindowPos"));
+        }
+    }
+
+    if ( parent )
+    {
+        // hdwp must be updated as it may have been changed
+        parent->m_hDWP = (WXHANDLE)hdwp;
+    }
+
+    if ( hdwp )
+    {
+        // did deferred move, remember new coordinates of the window as they're
+        // different from what Windows would return for it
+        return true;
+    }
+
+    // otherwise (or if deferring failed) move the window in place immediately
+#endif // USE_DEFERRED_SIZING
+    if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) )
+    {
+        wxLogLastError(wxT("MoveWindow"));
+    }
+
+    // if USE_DEFERRED_SIZING, indicates that we didn't use deferred move,
+    // ignored otherwise
+    return false;
+}
+
 void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
 {
     // TODO: is this consistent with other platforms?
 void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
 {
     // TODO: is this consistent with other platforms?
@@ -1531,9 +1969,18 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
         width = 0;
     if (height < 0)
         height = 0;
         width = 0;
     if (height < 0)
         height = 0;
-    if ( !::MoveWindow(GetHwnd(), x, y, width, height, IsShown() /*Repaint?*/) )
+
+    if ( DoMoveSibling(m_hWnd, x, y, width, height) )
     {
     {
-        wxLogLastError(wxT("MoveWindow"));
+#if USE_DEFERRED_SIZING
+        m_pendingPosition = wxPoint(x, y);
+        m_pendingSize = wxSize(width, height);
+    }
+    else // window was moved immediately, without deferring it
+    {
+        m_pendingPosition = wxDefaultPosition;
+        m_pendingSize = wxDefaultSize;
+#endif // USE_DEFERRED_SIZING
     }
 }
 
     }
 }
 
@@ -1549,14 +1996,23 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
     // get the current size and position...
     int currentX, currentY;
 {
     // get the current size and position...
     int currentX, currentY;
+    int currentW, currentH;
+
     GetPosition(&currentX, &currentY);
     GetPosition(&currentX, &currentY);
-    int currentW,currentH;
     GetSize(&currentW, &currentH);
 
     GetSize(&currentW, &currentH);
 
-    // ... and don't do anything (avoiding flicker) if it's already ok
+    // ... and don't do anything (avoiding flicker) if it's already ok unless
+    // we're forced to resize the window
     if ( x == currentX && y == currentY &&
     if ( x == currentX && y == currentY &&
-         width == currentW && height == currentH )
+         width == currentW && height == currentH &&
+            !(sizeFlags & wxSIZE_FORCE) )
     {
     {
+        if (sizeFlags & wxSIZE_FORCE_EVENT)
+        {
+            wxSizeEvent event( wxSize(width,height), GetId() );
+            event.SetEventObject( this );
+            HandleWindowEvent( event );
+        }
         return;
     }
 
         return;
     }
 
@@ -1606,11 +2062,12 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 
 void wxWindowMSW::DoSetClientSize(int width, int height)
 {
 
 void wxWindowMSW::DoSetClientSize(int width, int height)
 {
-    // setting the client size is less obvious than it it could have been
+    // setting the client size is less obvious than it could have been
     // because in the result of changing the total size the window scrollbar
     // because in the result of changing the total size the window scrollbar
-    // may [dis]appear and/or its menubar may [un]wrap and so the client size
-    // will not be correct as the difference between the total and client size
-    // changes - so we keep changing it until we get it right
+    // may [dis]appear and/or its menubar may [un]wrap (and AdjustWindowRect()
+    // doesn't take neither into account) and so the client size will not be
+    // correct as the difference between the total and client size changes --
+    // so we keep changing it until we get it right
     //
     // normally this loop shouldn't take more than 3 iterations (usually 1 but
     // if scrollbars [dis]appear as the result of the first call, then 2 and it
     //
     // normally this loop shouldn't take more than 3 iterations (usually 1 but
     // if scrollbars [dis]appear as the result of the first call, then 2 and it
@@ -1623,28 +2080,21 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
         RECT rectClient;
         ::GetClientRect(GetHwnd(), &rectClient);
 
         RECT rectClient;
         ::GetClientRect(GetHwnd(), &rectClient);
 
-        // if the size is already ok, stop here (rectClient.left = top = 0)
+        // if the size is already ok, stop here (NB: rectClient.left = top = 0)
         if ( (rectClient.right == width || width == wxDefaultCoord) &&
              (rectClient.bottom == height || height == wxDefaultCoord) )
         {
             break;
         }
 
         if ( (rectClient.right == width || width == wxDefaultCoord) &&
              (rectClient.bottom == height || height == wxDefaultCoord) )
         {
             break;
         }
 
-        int widthClient = width,
-            heightClient = height;
-
         // Find the difference between the entire window (title bar and all)
         // and the client area; add this to the new client size to move the
         // window
         RECT rectWin;
         ::GetWindowRect(GetHwnd(), &rectWin);
 
         // Find the difference between the entire window (title bar and all)
         // and the client area; add this to the new client size to move the
         // window
         RECT rectWin;
         ::GetWindowRect(GetHwnd(), &rectWin);
 
-        widthClient += rectWin.right - rectWin.left - rectClient.right;
-        heightClient += rectWin.bottom - rectWin.top - rectClient.bottom;
-
-        POINT point;
-        point.x = rectWin.left;
-        point.y = rectWin.top;
+        const int widthWin = rectWin.right - rectWin.left,
+                  heightWin = rectWin.bottom - rectWin.top;
 
         // MoveWindow positions the child windows relative to the parent, so
         // adjust if necessary
 
         // MoveWindow positions the child windows relative to the parent, so
         // adjust if necessary
@@ -1653,21 +2103,26 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
             wxWindow *parent = GetParent();
             if ( parent )
             {
             wxWindow *parent = GetParent();
             if ( parent )
             {
-                ::ScreenToClient(GetHwndOf(parent), &point);
+                ::ScreenToClient(GetHwndOf(parent), (POINT *)&rectWin);
             }
         }
 
             }
         }
 
-        DoMoveWindow(point.x, point.y, widthClient, heightClient);
+        // don't call DoMoveWindow() because we want to move window immediately
+        // and not defer it here as otherwise the value returned by
+        // GetClient/WindowRect() wouldn't change as the window wouldn't be
+        // really resized
+        if ( !::MoveWindow(GetHwnd(),
+                           rectWin.left,
+                           rectWin.top,
+                           width + widthWin - rectClient.right,
+                           height + heightWin - rectClient.bottom,
+                           TRUE) )
+        {
+            wxLogLastError(_T("MoveWindow"));
+        }
     }
 }
 
     }
 }
 
-// For implementation purposes - sometimes decorations make the client area
-// smaller
-wxPoint wxWindowMSW::GetClientAreaOrigin() const
-{
-    return wxPoint(0, 0);
-}
-
 // ---------------------------------------------------------------------------
 // text metrics
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // text metrics
 // ---------------------------------------------------------------------------
@@ -1691,23 +2146,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;
-    GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+    ::GetTextExtentPoint32(hdc, string.wx_str(), string.length(), &sizeRect);
     GetTextMetrics(hdc, &tm);
 
     if ( x )
     GetTextMetrics(hdc, &tm);
 
     if ( x )
@@ -1770,15 +2225,26 @@ 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__)
 #if defined(__WXWINCE__)
-    UINT flags = 0;
-#else
+    static const UINT flags = 0;
+#else // !__WXWINCE__
     UINT flags = TPM_RIGHTBUTTON;
     UINT flags = TPM_RIGHTBUTTON;
-#endif
+    // NT4 doesn't support TPM_RECURSE and simply doesn't show the menu at all
+    // when it's use, I'm not sure about Win95/98 but prefer to err on the safe
+    // side and not to use it there neither -- modify the test if it does work
+    // on these systems
+    if ( wxGetWinVersion() >= wxWinVersion_5 )
+    {
+        // using TPM_RECURSE allows us to show a popup menu while another menu
+        // is opened which can be useful and is supported by the other
+        // platforms, so allow it under Windows too
+        flags |= TPM_RECURSE;
+    }
+#endif // __WXWINCE__/!__WXWINCE__
+
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
-    // we need to do it righ now as otherwise the events are never going to be
+    // we need to do it right now as otherwise the events are never going to be
     // sent to wxCurrentPopupMenu from HandleCommand()
     //
     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
     // sent to wxCurrentPopupMenu from HandleCommand()
     //
     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
@@ -1787,8 +2253,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;
@@ -1819,7 +2283,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
         // here we try to do all the job which ::IsDialogMessage() usually does
         // internally
 
         // here we try to do all the job which ::IsDialogMessage() usually does
         // internally
-#if 1
         if ( msg->message == WM_KEYDOWN )
         {
             bool bCtrlDown = wxIsCtrlDown();
         if ( msg->message == WM_KEYDOWN )
         {
             bool bCtrlDown = wxIsCtrlDown();
@@ -1828,35 +2291,36 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
             // WM_GETDLGCODE: ask the control if it wants the key for itself,
             // don't process it if it's the case (except for Ctrl-Tab/Enter
             // combinations which are always processed)
             // WM_GETDLGCODE: ask the control if it wants the key for itself,
             // don't process it if it's the case (except for Ctrl-Tab/Enter
             // combinations which are always processed)
-            LONG lDlgCode = 0;
-            if ( !bCtrlDown )
-            {
-                lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+            LONG lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
 
 
-                // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the
-                // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically,
-                // it, of course, implies them
-                if ( lDlgCode & DLGC_WANTALLKEYS )
-                {
-                    lDlgCode |= DLGC_WANTTAB | DLGC_WANTARROWS;
-                }
+            // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the
+            // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically,
+            // it, of course, implies them
+            if ( lDlgCode & DLGC_WANTALLKEYS )
+            {
+                lDlgCode |= DLGC_WANTTAB | DLGC_WANTARROWS;
             }
 
             bool bForward = true,
             }
 
             bool bForward = true,
-                 bWindowChange = false;
+                 bWindowChange = false,
+                 bFromTab = false;
 
             // should we process this message specially?
             bool bProcess = true;
             switch ( msg->wParam )
             {
                 case VK_TAB:
 
             // should we process this message specially?
             bool bProcess = true;
             switch ( msg->wParam )
             {
                 case VK_TAB:
-                    if ( lDlgCode & DLGC_WANTTAB ) {
+                    if ( (lDlgCode & DLGC_WANTTAB) && !bCtrlDown )
+                    {
+                        // let the control have the TAB
                         bProcess = false;
                     }
                         bProcess = false;
                     }
-                    else {
+                    else // use it for navigation
+                    {
                         // Ctrl-Tab cycles thru notebook pages
                         bWindowChange = bCtrlDown;
                         bForward = !bShiftDown;
                         // Ctrl-Tab cycles thru notebook pages
                         bWindowChange = bCtrlDown;
                         bForward = !bShiftDown;
+                        bFromTab = true;
                     }
                     break;
 
                     }
                     break;
 
@@ -1874,35 +2338,28 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         bProcess = false;
                     break;
 
                         bProcess = false;
                     break;
 
-                case VK_ESCAPE:
-                    {
-#if wxUSE_BUTTON
-                        wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),
-                                                      wxButton);
-                        if ( btn && btn->IsEnabled() )
-                        {
-                            // if we do have a cancel button, do press it
-                            btn->MSWCommand(BN_CLICKED, 0 /* unused */);
-
-                            // we consumed the message
-                            return true;
-                        }
-#endif // wxUSE_BUTTON
+                case VK_PRIOR:
+                    bForward = false;
+                    // fall through
 
 
+                case VK_NEXT:
+                    // we treat PageUp/Dn as arrows because chances are that
+                    // a control which needs arrows also needs them for
+                    // navigation (e.g. wxTextCtrl, wxListCtrl, ...)
+                    if ( (lDlgCode & DLGC_WANTARROWS) && !bCtrlDown )
                         bProcess = false;
                         bProcess = false;
-                    }
+                    else // OTOH Ctrl-PageUp/Dn works as [Shift-]Ctrl-Tab
+                        bWindowChange = true;
                     break;
 
                 case VK_RETURN:
                     {
                     break;
 
                 case VK_RETURN:
                     {
-                        if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown )
-                        {
-                            // control wants to process Enter itself, don't
-                            // call IsDialogMessage() which would interpret
-                            // it
-                            return false;
-                        }
-                        else if ( lDlgCode & DLGC_BUTTON )
+#if wxUSE_BUTTON
+                        // currently active button should get enter press even
+                        // if there is a default button elsewhere so check if
+                        // this window is a button first
+                        wxWindow *btn = NULL;
+                        if ( lDlgCode & DLGC_DEFPUSHBUTTON )
                         {
                             // let IsDialogMessage() handle this for all
                             // buttons except the owner-drawn ones which it
                         {
                             // let IsDialogMessage() handle this for all
                             // buttons except the owner-drawn ones which it
@@ -1911,51 +2368,78 @@ 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
-                                wxWindow *btn = wxFindWinFromHandle((WXHWND)msg->hwnd);
-                                if ( btn )
-                                    btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+                                btn = wxFindWinFromHandle(msg->hwnd);
                             }
 
                             bProcess = false;
                         }
                             }
 
                             bProcess = false;
                         }
-                        // FIXME: this should be handled by
-                        //        wxNavigationKeyEvent handler and not here!!
-                        else
+                        else // not a button itself, do we have default button?
                         {
                         {
-#if wxUSE_BUTTON
-                            wxButton *btn = wxDynamicCast(GetDefaultItem(),
-                                                          wxButton);
-                            if ( btn && btn->IsEnabled() )
+                            // 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 )
                             {
                             {
-                                // if we do have a default button, do press it
-                                btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+                                // this will contain the dialog code of this
+                                // window and all of its parent windows in turn
+                                LONG lDlgCode2 = lDlgCode;
 
 
-                                return true;
-                            }
-                            else // no default button
-#endif // wxUSE_BUTTON
-                            {
-                                // this is a quick and dirty test for a text
-                                // control
-                                if ( !(lDlgCode & DLGC_HASSETSEL) )
+                                while ( win )
                                 {
                                 {
-                                    // don't process Enter, the control might
-                                    // need it for itself and don't let
-                                    // ::IsDialogMessage() have it as it can
-                                    // eat the Enter events sometimes
-                                    return false;
+                                    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 if (!IsTopLevel())
-                                {
-                                    // if not a top level window, let parent
-                                    // handle it
-                                    return false;
-                                }
-                                //else: treat Enter as TAB: pass to the next
-                                //      control as this is the best thing to do
-                                //      if the text doesn't handle Enter itself
+                            }
+                            else // bCtrlDown
+                            {
+                                win = wxGetTopLevelParent(win);
+                            }
+
+                            wxTopLevelWindow * const
+                                tlw = wxDynamicCast(win, wxTopLevelWindow);
+                            if ( tlw )
+                            {
+                                btn = wxDynamicCast(tlw->GetDefaultItem(),
+                                                    wxButton);
                             }
                         }
                             }
                         }
+
+                        if ( btn && btn->IsEnabled() )
+                        {
+                            btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+                            return true;
+                        }
+
+#endif // wxUSE_BUTTON
+
+#ifdef __WXWINCE__
+                        // map Enter presses into button presses on PDAs
+                        wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN);
+                        event.SetEventObject(this);
+                        if ( HandleWindowEvent(event) )
+                            return true;
+#endif // __WXWINCE__
                     }
                     break;
 
                     }
                     break;
 
@@ -1968,128 +2452,25 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 wxNavigationKeyEvent event;
                 event.SetDirection(bForward);
                 event.SetWindowChange(bWindowChange);
                 wxNavigationKeyEvent event;
                 event.SetDirection(bForward);
                 event.SetWindowChange(bWindowChange);
+                event.SetFromTab(bFromTab);
                 event.SetEventObject(this);
 
                 event.SetEventObject(this);
 
-                if ( GetEventHandler()->ProcessEvent(event) )
-                {
-                    return true;
-                }
-            }
-        }
-#else // 0
-        // let ::IsDialogMessage() do almost everything and handle just the
-        // things it doesn't here: Ctrl-TAB for switching notebook pages
-        if ( msg->message == WM_KEYDOWN )
-        {
-            // don't process system keys here
-            if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) )
-            {
-                if ( (msg->wParam == VK_TAB) && wxIsCtrlDown() )
+                if ( HandleWindowEvent(event) )
                 {
                 {
-                    // find the first notebook parent and change its page
-                    wxWindow *win = this;
-                    wxNotebook *nbook = NULL;
-                    while ( win && !nbook )
-                    {
-                        nbook = wxDynamicCast(win, wxNotebook);
-                        win = win->GetParent();
-                    }
-
-                    if ( nbook )
-                    {
-                        bool forward = !wxIsShiftDown();
+                    // as we don't call IsDialogMessage(), which would take of
+                    // this by default, we need to manually send this message
+                    // so that controls can change their UI state if needed
+                    MSWUpdateUIState(UIS_CLEAR, UISF_HIDEFOCUS);
 
 
-                        nbook->AdvanceSelection(forward);
-                    }
+                    return true;
                 }
             }
         }
                 }
             }
         }
-#endif // 1/0
 
 
-        // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
-        // message even when there is no cancel button and when the message is
-        // needed by the control itself: in particular, it prevents the tree in
-        // place edit control from being closed with Escape in a dialog
-        if ( msg->message != WM_KEYDOWN || msg->wParam != VK_ESCAPE )
+        if ( ::IsDialogMessage(GetHwnd(), msg) )
         {
         {
-            // ::IsDialogMessage() is broken and may sometimes hang the
-            // application by going into an infinite loop, so we try to detect
-            // [some of] the situatations when this may happen and not call it
-            // then
-
-            // assume we can call it by default
-            bool canSafelyCallIsDlgMsg = true;
-
-            HWND hwndFocus = ::GetFocus();
-
-            // if the currently focused window itself has WS_EX_CONTROLPARENT style, ::IsDialogMessage() will also enter
-            // an infinite loop, because it will recursively check the child
-            // windows but not the window itself and so if none of the children
-            // accepts focus it loops forever (as it only stops when it gets
-            // back to the window it started from)
-            //
-            // while it is very unusual that a window with WS_EX_CONTROLPARENT
-            // style has the focus, it can happen. One such possibility is if
-            // all windows are either toplevel, wxDialog, wxPanel or static
-            // controls and no window can actually accept keyboard input.
-#if !defined(__WXWINCE__)
-            if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
-            {
-                // passimistic by default
-                canSafelyCallIsDlgMsg = false;
-                for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
-                      node;
-                      node = node->GetNext() )
-                {
-                    wxWindow * const win = node->GetData();
-                    if ( win->AcceptsFocus() &&
-                            !(::GetWindowLong(GetHwndOf(win), GWL_EXSTYLE) &
-                                WS_EX_CONTROLPARENT) )
-                    {
-                        // it shouldn't hang...
-                        canSafelyCallIsDlgMsg = true;
-
-                        break;
-                    }
-                }
-            }
-#endif // !__WXWINCE__
-
-            if ( canSafelyCallIsDlgMsg )
-            {
-                // ::IsDialogMessage() can enter in an infinite loop when the
-                // currently focused window is disabled or hidden and its
-                // parent has WS_EX_CONTROLPARENT style, so don't call it in
-                // this case
-                while ( hwndFocus )
-                {
-                    if ( !::IsWindowEnabled(hwndFocus) ||
-                            !::IsWindowVisible(hwndFocus) )
-                    {
-                        // it would enter an infinite loop if we do this!
-                        canSafelyCallIsDlgMsg = false;
-
-                        break;
-                    }
-
-                    if ( !(::GetWindowLong(hwndFocus, GWL_STYLE) & WS_CHILD) )
-                    {
-                        // it's a top level window, don't go further -- e.g. even
-                        // if the parent of a dialog is disabled, this doesn't
-                        // break navigation inside the dialog
-                        break;
-                    }
-
-                    hwndFocus = ::GetParent(hwndFocus);
-                }
-            }
-
-            // let IsDialogMessage() have the message if it's safe to call it
-            if ( canSafelyCallIsDlgMsg && ::IsDialogMessage(GetHwnd(), msg) )
-            {
-                // IsDialogMessage() did something...
-                return true;
-            }
+            // IsDialogMessage() did something...
+            return true;
         }
     }
 #endif // __WXUNIVERSAL__
         }
     }
 #endif // __WXUNIVERSAL__
@@ -2100,7 +2481,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         // relay mouse move events to the tooltip control
         MSG *msg = (MSG *)pMsg;
         if ( msg->message == WM_MOUSEMOVE )
         // relay mouse move events to the tooltip control
         MSG *msg = (MSG *)pMsg;
         if ( msg->message == WM_MOUSEMOVE )
-            m_tooltip->RelayEvent(pMsg);
+            wxToolTip::RelayEvent(pMsg);
     }
 #endif // wxUSE_TOOLTIPS
 
     }
 #endif // wxUSE_TOOLTIPS
 
@@ -2117,10 +2498,95 @@ bool wxWindowMSW::MSWTranslateMessage(WXMSG* pMsg)
 #endif // wxUSE_ACCEL
 }
 
 #endif // wxUSE_ACCEL
 }
 
-bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* WXUNUSED(pMsg))
+bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* msg)
 {
 {
-    // preprocess all messages by default
-    return true;
+    // all tests below have to deal with various bugs/misfeatures of
+    // IsDialogMessage(): we have to prevent it from being called from our
+    // MSWProcessMessage() in some situations
+
+    // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
+    // message even when there is no cancel button and when the message is
+    // needed by the control itself: in particular, it prevents the tree in
+    // place edit control from being closed with Escape in a dialog
+    if ( msg->message == WM_KEYDOWN && msg->wParam == VK_ESCAPE )
+    {
+        return false;
+    }
+
+    // ::IsDialogMessage() is broken and may sometimes hang the application by
+    // going into an infinite loop when it tries to find the control to give
+    // focus to when Alt-<key> is pressed, so we try to detect [some of] the
+    // situations when this may happen and not call it then
+    if ( msg->message != WM_SYSCHAR )
+        return true;
+
+    // assume we can call it by default
+    bool canSafelyCallIsDlgMsg = true;
+
+    HWND hwndFocus = ::GetFocus();
+
+    // if the currently focused window itself has WS_EX_CONTROLPARENT style,
+    // ::IsDialogMessage() will also enter an infinite loop, because it will
+    // recursively check the child windows but not the window itself and so if
+    // none of the children accepts focus it loops forever (as it only stops
+    // when it gets back to the window it started from)
+    //
+    // while it is very unusual that a window with WS_EX_CONTROLPARENT
+    // style has the focus, it can happen. One such possibility is if
+    // all windows are either toplevel, wxDialog, wxPanel or static
+    // controls and no window can actually accept keyboard input.
+#if !defined(__WXWINCE__)
+    if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
+    {
+        // pessimistic by default
+        canSafelyCallIsDlgMsg = false;
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+              node;
+              node = node->GetNext() )
+        {
+            wxWindow * const win = node->GetData();
+            if ( win->CanAcceptFocus() &&
+                    !wxHasWindowExStyle(win, WS_EX_CONTROLPARENT) )
+            {
+                // it shouldn't hang...
+                canSafelyCallIsDlgMsg = true;
+
+                break;
+            }
+        }
+    }
+#endif // !__WXWINCE__
+
+    if ( canSafelyCallIsDlgMsg )
+    {
+        // ::IsDialogMessage() can enter in an infinite loop when the
+        // currently focused window is disabled or hidden and its
+        // parent has WS_EX_CONTROLPARENT style, so don't call it in
+        // this case
+        while ( hwndFocus )
+        {
+            if ( !::IsWindowEnabled(hwndFocus) ||
+                    !::IsWindowVisible(hwndFocus) )
+            {
+                // it would enter an infinite loop if we do this!
+                canSafelyCallIsDlgMsg = false;
+
+                break;
+            }
+
+            if ( !(::GetWindowLong(hwndFocus, GWL_STYLE) & WS_CHILD) )
+            {
+                // it's a top level window, don't go further -- e.g. even
+                // if the parent of a dialog is disabled, this doesn't
+                // break navigation inside the dialog
+                break;
+            }
+
+            hwndFocus = ::GetParent(hwndFocus);
+        }
+    }
+
+    return canSafelyCallIsDlgMsg;
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -2152,13 +2618,10 @@ void wxWindowMSW::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
 }
 
 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
 }
 
 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
-                              WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
+                                 WXHDC *hdc, WXHWND *hwnd)
 {
 {
-#ifndef __WXMICROWIN__
-    *nCtlColor = CTLCOLOR_BTN;
     *hwnd = (WXHWND)lParam;
     *hdc = (WXHDC)wParam;
     *hwnd = (WXHWND)lParam;
     *hdc = (WXHDC)wParam;
-#endif
 }
 
 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
 }
 
 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
@@ -2195,11 +2658,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
@@ -2213,7 +2676,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w
 
     LRESULT rc;
 
 
     LRESULT rc;
 
-    if ( wnd )
+    if ( wnd && wxGUIEventLoop::AllowProcessing(wnd) )
         rc = wnd->MSWWindowProc(message, wParam, lParam);
     else
         rc = ::DefWindowProc(hWnd, message, wParam, lParam);
         rc = wnd->MSWWindowProc(message, wParam, lParam);
     else
         rc = ::DefWindowProc(hWnd, message, wParam, lParam);
@@ -2231,7 +2694,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
     {
         bool        allow;
         WXLRESULT   result;
     {
         bool        allow;
         WXLRESULT   result;
-        WXHICON     hIcon;
         WXHBRUSH    hBrush;
     } rc;
 
         WXHBRUSH    hBrush;
     } rc;
 
@@ -2260,6 +2722,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             (void)HandleDestroy();
             break;
 
             (void)HandleDestroy();
             break;
 
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
+
         case WM_MOVE:
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
         case WM_MOVE:
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
@@ -2282,13 +2748,19 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
                 }
             }
             break;
-#endif
-
-        case WM_SIZE:
-            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+#if 0
+        case WM_ENTERSIZEMOVE:
+            {
+                processed = HandleEnterSizeMove();
+            }
             break;
 
             break;
 
-#if !defined(__WXWINCE__)
+        case WM_EXITSIZEMOVE:
+            {
+                processed = HandleExitSizeMove();
+            }
+            break;
+#endif
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2306,10 +2778,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
                 }
             }
             break;
-#endif
+#endif // !__WXWINCE__
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
+            // This implicitly sends a wxEVT_ACTIVATE_APP event
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
 #endif
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
 #endif
@@ -2325,59 +2798,41 @@ 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:
+            processed = HandlePrintClient((WXHDC)wParam);
             break;
 
         case WM_PAINT:
             break;
 
         case WM_PAINT:
+            if ( wParam )
             {
             {
-                if ( wParam )
-                {
-                    // cast to wxWindow is needed for wxUniv
-                    wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
-                    processed = HandlePaint();
-                }
-                else
-                {
-                    processed = HandlePaint();
-                }
-                break;
-            }
+                wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
 
 
-#ifndef __WXWINCE__
-        case WM_PRINT:
+                processed = HandlePaint();
+            }
+            else // no DC given
             {
             {
-#if wxUSE_LISTCTRL
-                // Don't call the wx handlers in this case
-                if ( wxIsKindOf(this, wxListCtrl) )
-                    break;
-#endif
-
-                if ( lParam & PRF_ERASEBKGND )
-                    HandleEraseBkgnd((WXHDC)(HDC)wParam);
-
-                wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
                 processed = HandlePaint();
             }
             break;
                 processed = HandlePaint();
             }
             break;
-#endif
 
         case WM_CLOSE:
 #ifdef __WXUNIVERSAL__
             // Universal uses its own wxFrame/wxDialog, so we don't receive
             // close events unless we have this.
             Close();
 
         case WM_CLOSE:
 #ifdef __WXUNIVERSAL__
             // Universal uses its own wxFrame/wxDialog, so we don't receive
             // close events unless we have this.
             Close();
-            processed = true;
-            rc.result = TRUE;
-#else
+#endif // __WXUNIVERSAL__
+
             // don't let the DefWindowProc() destroy our window - we'll do it
             // ourselves in ~wxWindow
             processed = true;
             rc.result = TRUE;
             // don't let the DefWindowProc() destroy our window - we'll do it
             // ourselves in ~wxWindow
             processed = true;
             rc.result = TRUE;
-#endif
             break;
 
         case WM_SHOWWINDOW:
             break;
 
         case WM_SHOWWINDOW:
@@ -2390,61 +2845,21 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                         wParam);
             break;
 
                                         wParam);
             break;
 
-            // Seems to be broken currently
-#if 0 // ndef __WXWINCE__
+#ifdef HAVE_TRACKMOUSEEVENT
         case WM_MOUSELEAVE:
         case WM_MOUSELEAVE:
-           {
-            wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
-
-            // only process this message if the mouse is not in the window,
-            // This can also check for children in composite windows.
-            // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
-            // if the mouse does not enter the window from it's child before
-            // leaving the scope of the window. ( perhaps this can be picked
-            // up in the OnIdle code as before, for this special case )
-            if ( /*IsComposite() && */ !IsMouseInWindow() )
+            // filter out excess WM_MOUSELEAVE events sent after PopupMenu()
+            // (on XP at least)
+            if ( m_mouseInWindow )
             {
             {
-                m_mouseInWindow = false;
-
-                // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
-                int state = 0;
-                if ( wxIsShiftDown() )
-                    state |= MK_SHIFT;
-                if ( wxIsCtrlDown() )
-                    state |= MK_CONTROL;
-                if ( GetKeyState( VK_LBUTTON ) )
-                    state |= MK_LBUTTON;
-                if ( GetKeyState( VK_MBUTTON ) )
-                    state |= MK_MBUTTON;
-                if ( GetKeyState( VK_RBUTTON ) )
-                    state |= MK_RBUTTON;
-
-                POINT pt;
-                if ( !::GetCursorPos(&pt) )
-                {
-                    wxLogLastError(_T("GetCursorPos"));
-                }
-
-                // we need to have client coordinates here for symmetry with
-                // wxEVT_ENTER_WINDOW
-                RECT rect = wxGetWindowRect(GetHwnd());
-                pt.x -= rect.left;
-                pt.y -= rect.top;
-
-                wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-                InitMouseEvent(event2, pt.x, pt.y, state);
-
-                (void)GetEventHandler()->ProcessEvent(event2);
+                GenerateMouseLeave();
             }
             }
+
             // always pass processed back as false, this allows the window
             // always pass processed back as false, this allows the window
-            // manager to process the message too.  This is needed to ensure
-            // windows XP themes work properly as the mouse moves over widgets
-            // like buttons.
-            processed = false;
-           }
-           break;
-#endif
- // __WXWINCE__
+            // manager to process the message too.  This is needed to
+            // ensure windows XP themes work properly as the mouse moves
+            // over widgets like buttons. So don't set processed to true here.
+            break;
+#endif // HAVE_TRACKMOUSEEVENT
 
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
 
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
@@ -2461,6 +2876,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
@@ -2487,8 +2907,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
+#ifdef __WXWINCE__
                 // redirect the event to a static control if necessary by
                 // redirect the event to a static control if necessary by
-                // finding one under mouse
+                // finding one under mouse because under CE the static controls
+                // don't generate mouse events (even with SS_NOTIFY)
                 wxWindowMSW *win;
                 if ( GetCapture() == this )
                 {
                 wxWindowMSW *win;
                 if ( GetCapture() == this )
                 {
@@ -2503,19 +2925,56 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // this should never happen
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
                     // this should never happen
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
+                }
+#ifdef __POCKETPC__
+                if (IsContextMenuEnabled() && message == WM_LBUTTONDOWN)
+                {
+                    SHRGINFO shrgi = {0};
+
+                    shrgi.cbSize = sizeof(SHRGINFO);
+                    shrgi.hwndClient = (HWND) GetHWND();
+                    shrgi.ptDown.x = x;
+                    shrgi.ptDown.y = y;
+
+                    shrgi.dwFlags = SHRG_RETURNCMD;
+                    // shrgi.dwFlags = SHRG_NOTIFYPARENT;
+
+                    if (GN_CONTEXTMENU == ::SHRecognizeGesture(&shrgi))
+                    {
+                        wxPoint pt(x, y);
+                        pt = ClientToScreen(pt);
+
+                        wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, GetId(), pt);
+
+                        evtCtx.SetEventObject(this);
+                        if (HandleWindowEvent(evtCtx))
+                        {
+                            processed = true;
+                            return true;
+                        }
+                    }
+                }
+#endif
+
+#else // !__WXWINCE__
+                wxWindowMSW *win = this;
+#endif // __WXWINCE__/!__WXWINCE__
 
 
+                processed = win->HandleMouseEvent(message, x, y, wParam);
+
+                // if the app didn't eat the event, handle it in the default
+                // way, that is by giving this window the focus
+                if ( !processed )
+                {
                     // for the standard classes their WndProc sets the focus to
                     // them anyhow and doing it from here results in some weird
                     // for the standard classes their WndProc sets the focus to
                     // them anyhow and doing it from here results in some weird
-                    // problems, but for our windows we want them to acquire
-                    // focus when clicked
+                    // problems, so don't do it for them (unnecessary anyhow)
                     if ( !win->IsOfStandardClass() )
                     {
                     if ( !win->IsOfStandardClass() )
                     {
-                        if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() )
+                        if ( message == WM_LBUTTONDOWN && win->IsFocusable() )
                             win->SetFocus();
                     }
                 }
                             win->SetFocus();
                     }
                 }
-
-                processed = win->HandleMouseEvent(message, x, y, wParam);
             }
             break;
 
             }
             break;
 
@@ -2565,33 +3024,25 @@ 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)
 
         case WM_GETDLGCODE:
             break;
 #endif // defined(WM_DRAWITEM)
 
         case WM_GETDLGCODE:
-            if ( !IsOfStandardClass() )
+            if ( !IsOfStandardClass() || HasFlag(wxWANTS_CHARS) )
             {
                 // we always want to get the char events
                 rc.result = DLGC_WANTCHARS;
 
             {
                 // we always want to get the char events
                 rc.result = DLGC_WANTCHARS;
 
-                if ( GetWindowStyleFlag() & wxWANTS_CHARS )
+                if ( HasFlag(wxWANTS_CHARS) )
                 {
                     // in fact, we want everything
                     rc.result |= DLGC_WANTARROWS |
                 {
                     // in fact, we want everything
                     rc.result |= DLGC_WANTARROWS |
@@ -2618,7 +3069,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             {
                 switch ( wParam )
                 {
             {
                 switch ( wParam )
                 {
-                    // we consider these message "not interesting" to OnChar, so
+                    // we consider these messages "not interesting" to OnChar, so
                     // just don't do anything more with them
                     case VK_SHIFT:
                     case VK_CONTROL:
                     // just don't do anything more with them
                     case VK_SHIFT:
                     case VK_CONTROL:
@@ -2641,6 +3092,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     case VK_SUBTRACT:
                     case VK_MULTIPLY:
                     case VK_DIVIDE:
                     case VK_SUBTRACT:
                     case VK_MULTIPLY:
                     case VK_DIVIDE:
+                    case VK_NUMPAD0:
+                    case VK_NUMPAD1:
+                    case VK_NUMPAD2:
+                    case VK_NUMPAD3:
+                    case VK_NUMPAD4:
+                    case VK_NUMPAD5:
+                    case VK_NUMPAD6:
+                    case VK_NUMPAD7:
+                    case VK_NUMPAD8:
+                    case VK_NUMPAD9:
                     case VK_OEM_1:
                     case VK_OEM_2:
                     case VK_OEM_3:
                     case VK_OEM_1:
                     case VK_OEM_2:
                     case VK_OEM_3:
@@ -2662,13 +3123,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // special case of VK_APPS: treat it the same as right mouse
                     // click because both usually pop up a context menu
                     case VK_APPS:
                     // special case of VK_APPS: treat it the same as right mouse
                     // click because both usually pop up a context menu
                     case VK_APPS:
-                        {
-                            WPARAM flags;
-                            int x, y;
-
-                            TranslateKbdEventToMouse(this, &x, &y, &flags);
-                            processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
-                        }
+                        processed = HandleMouseEvent(WM_RBUTTONDOWN, -1, -1, 0);
                         break;
 #endif // VK_APPS
 
                         break;
 #endif // VK_APPS
 
@@ -2687,11 +3142,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             // special case of VK_APPS: treat it the same as right mouse button
             if ( wParam == VK_APPS )
             {
             // special case of VK_APPS: treat it the same as right mouse button
             if ( wParam == VK_APPS )
             {
-                WPARAM flags;
-                int x, y;
-
-                TranslateKbdEventToMouse(this, &x, &y, &flags);
-                processed = HandleMouseEvent(WM_RBUTTONUP, x, y, flags);
+                processed = HandleMouseEvent(WM_RBUTTONUP, -1, -1, 0);
             }
             else
 #endif // VK_APPS
             }
             else
 #endif // VK_APPS
@@ -2722,6 +3173,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:
             {
@@ -2736,7 +3193,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 
         // CTLCOLOR messages are sent by children to query the parent for their
             break;
 
         // CTLCOLOR messages are sent by children to query the parent for their
-        // colors#ifndef __WXMICROWIN__
+        // colors
 #ifndef __WXMICROWIN__
         case WM_CTLCOLORMSGBOX:
         case WM_CTLCOLOREDIT:
 #ifndef __WXMICROWIN__
         case WM_CTLCOLORMSGBOX:
         case WM_CTLCOLOREDIT:
@@ -2746,18 +3203,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
         case WM_CTLCOLORSCROLLBAR:
         case WM_CTLCOLORSTATIC:
             {
         case WM_CTLCOLORSCROLLBAR:
         case WM_CTLCOLORSTATIC:
             {
-                WXWORD nCtlColor;
                 WXHDC hdc;
                 WXHWND hwnd;
                 WXHDC hdc;
                 WXHWND hwnd;
-                UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd);
-
-                processed = HandleCtlColor(&rc.hBrush,
-                                           (WXHDC)hdc,
-                                           (WXHWND)hwnd,
-                                           nCtlColor,
-                                           message,
-                                           wParam,
-                                           lParam);
+                UnpackCtlColor(wParam, lParam, &hdc, &hwnd);
+
+                processed = HandleCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)hwnd);
             }
             break;
 #endif // !__WXMICROWIN__
             }
             break;
 #endif // !__WXMICROWIN__
@@ -2774,11 +3224,15 @@ 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:
+            processed = HandleSettingChange(wParam, lParam);
             break;
 
         case WM_QUERYNEWPALETTE:
             break;
 
         case WM_QUERYNEWPALETTE:
@@ -2786,7 +3240,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
@@ -2801,7 +3255,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 )
             {
@@ -2825,7 +3279,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
 
@@ -2855,50 +3309,48 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #if defined(WM_HELP)
         case WM_HELP:
             {
 #if defined(WM_HELP)
         case WM_HELP:
             {
-                // HELPINFO doesn't seem to be supported on WinCE.
+                // by default, WM_HELP is propagated by DefWindowProc() upwards
+                // to the window parent but as we do it ourselves already
+                // (wxHelpEvent is derived from wxCommandEvent), we don't want
+                // to get the other events if we process this message at all
+                processed = true;
+
+                // WM_HELP doesn't use lParam under CE
 #ifndef __WXWINCE__
                 HELPINFO* info = (HELPINFO*) lParam;
 #ifndef __WXWINCE__
                 HELPINFO* info = (HELPINFO*) lParam;
-                // Don't yet process menu help events, just windows
-                if (info->iContextType == HELPINFO_WINDOW)
+                if ( info->iContextType == HELPINFO_WINDOW )
                 {
                 {
-#endif
-                    wxWindowMSW* subjectOfHelp = this;
-                    bool eventProcessed = false;
-                    while (subjectOfHelp && !eventProcessed)
-                    {
-                        wxHelpEvent helpEvent(wxEVT_HELP,
-                                              subjectOfHelp->GetId(),
+#endif // !__WXWINCE__
+                    wxHelpEvent helpEvent
+                                (
+                                    wxEVT_HELP,
+                                    GetId(),
 #ifdef __WXWINCE__
 #ifdef __WXWINCE__
-                                              wxPoint(0, 0)
+                                    wxGetMousePosition() // what else?
 #else
 #else
-                                              wxPoint(info->MousePos.x, info->MousePos.y)
+                                    wxPoint(info->MousePos.x, info->MousePos.y)
 #endif
 #endif
-                                              );
-
-                        helpEvent.SetEventObject(this);
-                        eventProcessed =
-                            GetEventHandler()->ProcessEvent(helpEvent);
-
-                        // Go up the window hierarchy until the event is
-                        // handled (or not)
-                        subjectOfHelp = subjectOfHelp->GetParent();
-                    }
+                                );
 
 
-                    processed = eventProcessed;
+                    helpEvent.SetEventObject(this);
+                    HandleWindowEvent(helpEvent);
 #ifndef __WXWINCE__
                 }
 #ifndef __WXWINCE__
                 }
-                else if (info->iContextType == HELPINFO_MENUITEM)
+                else if ( info->iContextType == HELPINFO_MENUITEM )
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
-                    processed = GetEventHandler()->ProcessEvent(helpEvent);
+                    HandleWindowEvent(helpEvent);
 
                 }
 
                 }
-                //else: processed is already false
-#endif
+                else // unknown help event?
+                {
+                    processed = false;
+                }
+#endif // !__WXWINCE__
             }
             break;
             }
             break;
-#endif
+#endif // WM_HELP
 
 #if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
 
 #if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
@@ -2912,33 +3364,150 @@ 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 )
             {
-                // handle menu chars for ownerdrawn menu items
-                int i = HandleMenuChar(toupper(LOWORD(wParam)), lParam);
-                if ( i != wxNOT_FOUND )
+                // handle menu chars for ownerdrawn menu items
+                int i = HandleMenuChar(toupper(LOWORD(wParam)), lParam);
+                if ( i != wxNOT_FOUND )
+                {
+                    rc.result = MAKELRESULT(i, MNC_EXECUTE);
+                    processed = true;
+                }
+            }
+            break;
+#endif // wxUSE_MENUS
+
+#ifndef __WXWINCE__
+        case WM_POWERBROADCAST:
+            {
+                bool vetoed;
+                processed = HandlePower(wParam, lParam, &vetoed);
+                rc.result = processed && vetoed ? BROADCAST_QUERY_DENY : TRUE;
+            }
+            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
+                    RECT *rect;
+                    if ( wParam )
+                    {
+                        NCCALCSIZE_PARAMS *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)
                 {
                 {
-                    rc.result = MAKELRESULT(i, MNC_EXECUTE);
+                    // first ask the widget to paint its non-client area, such as scrollbars, etc.
+                    rc.result = MSWDefWindowProc(message, wParam, lParam);
                     processed = true;
                     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;
                 }
             }
             break;
+
+#endif // wxUSE_UXTHEME
+
+        default:
+            // try a custom message handler
+            const MSWMessageHandlers::const_iterator
+                i = gs_messageHandlers.find(message);
+            if ( i != gs_messageHandlers.end() )
+            {
+                processed = (*i->second)(this, message, wParam, lParam);
+            }
     }
 
     if ( !processed )
     }
 
     if ( !processed )
@@ -2957,38 +3526,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));
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -3102,6 +3673,17 @@ 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" );
+
+    // this can happen if this function is called using the return value of
+    // wxApp::GetRegisteredClassName() which failed
+    wxCHECK_MSG( wclass, false, "failed to register window class?" );
+
+
     // 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);
@@ -3116,48 +3698,28 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     wxString className(wclass);
     if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
     {
     wxString className(wclass);
     if ( !HasFlag(wxFULL_REPAINT_ON_RESIZE) )
     {
-        className += wxT("NR");
+        className += wxApp::GetNoRedrawClassSuffix();
     }
 
     // do create the window
     wxWindowCreationHook hook(this);
 
     }
 
     // do create the window
     wxWindowCreationHook hook(this);
 
-    // VZ: anyonce cares to explain why is this done for CE?
-#ifdef __WXWINCE__
-    if (extendedStyle == 0)
-    {
-        m_hWnd = (WXHWND)::CreateWindow
-            (
-            className,
-            title ? title : wxEmptyString,
-            style,
-            x, y, w, h,
-            (HWND)MSWGetParent(),
-            (HMENU)controlId,
-            wxGetInstance(),
-            NULL                        // no extra data
-            );
-    }
-    else
-#endif // __WXWINCE__
-    {
-        m_hWnd = (WXHWND)::CreateWindowEx
-            (
-            extendedStyle,
-            className,
-            title ? title : wxEmptyString,
-            style,
-            x, y, w, h,
-            (HWND)MSWGetParent(),
-            (HMENU)controlId,
-            wxGetInstance(),
-            NULL                        // no extra data
-            );
-    }
+    m_hWnd = (WXHWND)::CreateWindowEx
+                       (
+                        extendedStyle,
+                        className.wx_str(),
+                        title ? title : m_windowName.wx_str(),
+                        style,
+                        x, y, w, h,
+                        (HWND)MSWGetParent(),
+                        (HMENU)wxUIntToPtr(controlId),
+                        wxGetInstance(),
+                        NULL                        // no extra data
+                       );
 
     if ( !m_hWnd )
     {
 
     if ( !m_hWnd )
     {
-        wxLogSysError(_("Can't create window of class %s"), wclass);
+        wxLogSysError(_("Can't create window of class %s"), className.c_str());
 
         return false;
     }
 
         return false;
     }
@@ -3175,14 +3737,12 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
-#ifdef __WIN95__
-
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
     LPNMHDR hdr = (LPNMHDR)lParam;
     HWND hWnd = hdr->hwndFrom;
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #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 )
@@ -3260,7 +3820,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
         // Truncate tooltip length if needed as otherwise we might not have
         // enough space for it in the buffer and MultiByteToWideChar() would
         // return an error
         // Truncate tooltip length if needed as otherwise we might not have
         // enough space for it in the buffer and MultiByteToWideChar() would
         // return an error
-        size_t tipLength = wxMin(ttip.Len(), WXSIZEOF(buf) - 1);
+        size_t tipLength = wxMin(ttip.length(), WXSIZEOF(buf) - 1);
 
         // Convert to WideChar without adding the NULL character. The NULL
         // character is added afterwards (this is more efficient).
 
         // Convert to WideChar without adding the NULL character. The NULL
         // character is added afterwards (this is more efficient).
@@ -3268,7 +3828,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
@@ -3289,8 +3849,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
         // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have
         // to copy the string we have into the buffer
         static wxChar buf[513];
         // if we got TTN_NEEDTEXTW in Unicode build: in this case we just have
         // to copy the string we have into the buffer
         static wxChar buf[513];
-        wxStrncpy(buf, ttip.c_str(), WXSIZEOF(buf) - 1);
-        buf[WXSIZEOF(buf) - 1] = _T('\0');
+        wxStrlcpy(buf, ttip.c_str(), WXSIZEOF(buf));
         ttText->lpszText = buf;
     }
 
         ttText->lpszText = buf;
     }
 
@@ -3320,15 +3879,13 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
     return false;
 }
 
     return false;
 }
 
-#endif // __WIN95__
-
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
 
 bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
 {
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
 
 bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
 {
-#ifndef __WXWINCE__
+#ifdef ENDSESSION_LOGOFF
     wxCloseEvent event(wxEVT_QUERY_END_SESSION, wxID_ANY);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(true);
     wxCloseEvent event(wxEVT_QUERY_END_SESSION, wxID_ANY);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(true);
@@ -3345,13 +3902,15 @@ bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
 
     return rc;
 #else
 
     return rc;
 #else
+    wxUnusedVar(logOff);
+    wxUnusedVar(mayEnd);
     return false;
 #endif
 }
 
 bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 {
     return false;
 #endif
 }
 
 bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 {
-#ifndef __WXWINCE__
+#ifdef ENDSESSION_LOGOFF
     // do nothing if the session isn't ending
     if ( !endSession )
         return false;
     // do nothing if the session isn't ending
     if ( !endSession )
         return false;
@@ -3363,10 +3922,12 @@ 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
+    wxUnusedVar(endSession);
+    wxUnusedVar(logOff);
     return false;
 #endif
 }
     return false;
 #endif
 }
@@ -3375,7 +3936,8 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 // window creation/destruction
 // ---------------------------------------------------------------------------
 
 // window creation/destruction
 // ---------------------------------------------------------------------------
 
-bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
+bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED_IN_WINCE(cs),
+                               bool *mayCreate)
 {
     // VZ: why is this commented out for WinCE? If it doesn't support
     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally,
 {
     // VZ: why is this commented out for WinCE? If it doesn't support
     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally,
@@ -3385,10 +3947,6 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
         EnsureParentHasControlParentStyle(GetParent());
 #endif // !__WXWINCE__
 
         EnsureParentHasControlParentStyle(GetParent());
 #endif // !__WXWINCE__
 
-    // TODO: should generate this event from WM_NCCREATE
-    wxWindowCreateEvent event((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(event);
-
     *mayCreate = true;
 
     return true;
     *mayCreate = true;
 
     return true;
@@ -3396,8 +3954,6 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
 
 bool wxWindowMSW::HandleDestroy()
 {
 
 bool wxWindowMSW::HandleDestroy()
 {
-    SendDestroyEvent();
-
     // delete our drop target if we've got one
 #if wxUSE_DRAG_AND_DROP
     if ( m_dropTarget != NULL )
     // delete our drop target if we've got one
 #if wxUSE_DRAG_AND_DROP
     if ( m_dropTarget != NULL )
@@ -3426,7 +3982,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)
@@ -3441,7 +3997,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
@@ -3451,22 +4007,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)
@@ -3479,16 +4026,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 )
@@ -3502,7 +4039,21 @@ 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);
+}
+
+// ---------------------------------------------------------------------------
+// labels
+// ---------------------------------------------------------------------------
+
+void wxWindowMSW::SetLabel( const wxString& label)
+{
+    SetWindowText(GetHwnd(), label.c_str());
+}
+
+wxString wxWindowMSW::GetLabel() const
+{
+    return wxGetWindowText(GetHWND());
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -3512,17 +4063,17 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
 bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
 {
     wxShowEvent event(GetId(), show);
 bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
 {
     wxShowEvent event(GetId(), show);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 {
     wxInitDialogEvent event(GetId());
 }
 
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 {
     wxInitDialogEvent event(GetId());
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
 }
 
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
@@ -3552,17 +4103,18 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
         ::DragQueryFile(hFilesInfo, wIndex,
                         wxStringBuffer(files[wIndex], len), len);
     }
         ::DragQueryFile(hFilesInfo, wIndex,
                         wxStringBuffer(files[wIndex], len), len);
     }
-    DragFinish (hFilesInfo);
 
     wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
 
     wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     POINT dropPoint;
     DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
     event.m_pos.x = dropPoint.x;
     event.m_pos.y = dropPoint.y;
 
 
     POINT dropPoint;
     DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
     event.m_pos.x = dropPoint.x;
     event.m_pos.y = dropPoint.y;
 
-    return GetEventHandler()->ProcessEvent(event);
+    DragFinish(hFilesInfo);
+
+    return HandleWindowEvent(event);
 #endif
 }
 
 #endif
 }
 
@@ -3573,59 +4125,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
-
-    if ( nHitTest != HTCLIENT )
-    {
-        return false;
-    }
+    //  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
 
     HCURSOR hcursor = 0;
 
     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;
-    if ( !::GetCursorPos(&pt) )
+    if ( wxIsBusy() )
     {
     {
-        wxLogLastError(wxT("GetCursorPos"));
+        hcursor = wxGetCurrentBusyCursor();
     }
     }
-
-    int x = pt.x,
-        y = pt.y;
-    ScreenToClient(&x, &y);
-    wxSetCursorEvent event(x, y);
-
-    bool processedEvtSetCursor = GetEventHandler()->ProcessEvent(event);
-    if ( processedEvtSetCursor && event.HasCursor() )
+    else // not busy
     {
     {
-        hcursor = GetHcursorOf(event.GetCursor());
-    }
+        if ( nHitTest != HTCLIENT )
+            return false;
 
 
-    if ( !hcursor )
-    {
-        bool isBusy = wxIsBusy();
+        // 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__
+        if ( !::GetCursorPosWinCE(&pt))
+#else
+        if ( !::GetCursorPos(&pt) )
+#endif
+        {
+            wxLogLastError(wxT("GetCursorPos"));
+        }
 
 
-        // 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() )
+        int x = pt.x,
+            y = pt.y;
+        ScreenToClient(&x, &y);
+        wxSetCursorEvent event(x, y);
+
+        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() )
@@ -3636,10 +4185,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
@@ -3651,6 +4199,98 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     return false;
 }
 
     return false;
 }
 
+bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
+                              WXLPARAM WXUNUSED(lParam),
+                              bool *WXUNUSED_IN_WINCE(vetoed))
+{
+#ifdef __WXWINCE__
+    // FIXME
+    return false;
+#else
+    wxEventType evtType;
+    switch ( wParam )
+    {
+        case PBT_APMQUERYSUSPEND:
+            evtType = wxEVT_POWER_SUSPENDING;
+            break;
+
+        case PBT_APMQUERYSUSPENDFAILED:
+            evtType = wxEVT_POWER_SUSPEND_CANCEL;
+            break;
+
+        case PBT_APMSUSPEND:
+            evtType = wxEVT_POWER_SUSPENDED;
+            break;
+
+        case PBT_APMRESUMESUSPEND:
+            evtType = wxEVT_POWER_RESUME;
+            break;
+
+        default:
+            wxLogDebug(_T("Unknown WM_POWERBROADCAST(%d) event"), wParam);
+            // fall through
+
+        // these messages are currently not mapped to wx events
+        case PBT_APMQUERYSTANDBY:
+        case PBT_APMQUERYSTANDBYFAILED:
+        case PBT_APMSTANDBY:
+        case PBT_APMRESUMESTANDBY:
+        case PBT_APMBATTERYLOW:
+        case PBT_APMPOWERSTATUSCHANGE:
+        case PBT_APMOEMEVENT:
+        case PBT_APMRESUMECRITICAL:
+#ifdef PBT_APMRESUMEAUTOMATIC
+        case PBT_APMRESUMEAUTOMATIC:
+#endif
+            evtType = wxEVT_NULL;
+            break;
+    }
+
+    // don't handle unknown messages
+    if ( evtType == wxEVT_NULL )
+        return false;
+
+    // TODO: notify about PBTF_APMRESUMEFROMFAILURE in case of resume events?
+
+    wxPowerEvent event(evtType);
+    if ( !HandleWindowEvent(event) )
+        return false;
+
+    *vetoed = event.IsVetoed();
+
+    return true;
+#endif
+}
+
+bool wxWindowMSW::IsDoubleBuffered() const
+{
+    for ( const wxWindowMSW *win = this; win; win = win->GetParent() )
+    {
+        if ( wxHasWindowExStyle(win, WS_EX_COMPOSITED) )
+            return true;
+
+        if ( win->IsTopLevel() )
+            break;
+    }
+
+    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
 // ---------------------------------------------------------------------------
@@ -3675,7 +4315,12 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+        // see comment before the same test in MSWOnMeasureItem() below
+        if ( !pMenuItem )
+            return false;
+
+        wxCHECK_MSG( wxDynamicCast(pMenuItem, wxMenuItem),
+                         false, _T("MSWOnDrawItem: bad wxMenuItem pointer") );
 
         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
         // the DC from being released
 
         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
         // the DC from being released
@@ -3723,9 +4368,7 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
 }
 
 bool
 }
 
 bool
-wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
-                              WXMEASUREITEMSTRUCT *
-                                  WXUNUSED_UNLESS_ODRAWN(itemStruct))
+wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
 {
 #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
     // is it a menu item?
 {
 #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
     // is it a menu item?
@@ -3734,7 +4377,16 @@ wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+        // according to Carsten Fuchs the pointer may be NULL under XP if an
+        // MDI child frame is initially maximized, see this for more info:
+        // http://article.gmane.org/gmane.comp.lib.wxwidgets.general/27745
+        //
+        // so silently ignore it instead of asserting
+        if ( !pMenuItem )
+            return false;
+
+        wxCHECK_MSG( wxDynamicCast(pMenuItem, wxMenuItem),
+                        false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") );
 
         size_t w, h;
         bool rc = pMenuItem->OnMeasureItem(&w, &h);
 
         size_t w, h;
         bool rc = pMenuItem->OnMeasureItem(&w, &h);
@@ -3750,7 +4402,10 @@ wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         return item->MSWOnMeasure(itemStruct);
     }
     {
         return item->MSWOnMeasure(itemStruct);
     }
-#endif // wxUSE_OWNER_DRAWN
+#else
+    wxUnusedVar(id);
+    wxUnusedVar(itemStruct);
+#endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
 
     return false;
 }
 
     return false;
 }
@@ -3764,7 +4419,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
@@ -3776,56 +4431,29 @@ bool wxWindowMSW::HandleDisplayChange()
     wxDisplayChangedEvent event;
     event.SetEventObject(this);
 
     wxDisplayChangedEvent event;
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 }
 
-bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush,
-                              WXHDC pDC,
-                              WXHWND pWnd,
-                              WXUINT nCtlColor,
-                              WXUINT message,
-                              WXWPARAM wParam,
-                              WXLPARAM lParam)
-{
 #ifndef __WXMICROWIN__
 #ifndef __WXMICROWIN__
-    WXHBRUSH hBrush = 0;
 
 
-#ifdef __WXWINCE__
-    if (false)
+bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC hDC, WXHWND hWnd)
+{
+#if !wxUSE_CONTROLS || defined(__WXUNIVERSAL__)
+    wxUnusedVar(hDC);
+    wxUnusedVar(hWnd);
 #else
 #else
-    if ( nCtlColor == CTLCOLOR_DLG )
-#endif
-    {
-        hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
-    }
-#if wxUSE_CONTROLS
+    wxControl *item = wxDynamicCast(FindItemByHWND(hWnd, true), wxControl);
+
+    if ( item )
+        *brush = item->MSWControlColor(hDC, hWnd);
     else
     else
-    {
-        wxControl *item = (wxControl *)FindItemByHWND(pWnd, true);
-        if ( item )
-            hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
-    }
 #endif // wxUSE_CONTROLS
 #endif // wxUSE_CONTROLS
+        *brush = NULL;
 
 
-    if ( hBrush )
-        *brush = hBrush;
-
-    return hBrush != 0;
-#else // __WXMICROWIN__
-    return false;
-#endif
+    return *brush != NULL;
 }
 
 }
 
-// Define for each class of dialog and control
-WXHBRUSH wxWindowMSW::OnCtlColor(WXHDC WXUNUSED(hDC),
-                                 WXHWND WXUNUSED(hWnd),
-                                 WXUINT WXUNUSED(nCtlColor),
-                                 WXUINT WXUNUSED(message),
-                                 WXWPARAM WXUNUSED(wParam),
-                                 WXLPARAM WXUNUSED(lParam))
-{
-    return (WXHBRUSH)0;
-}
+#endif // __WXMICROWIN__
 
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
 
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
@@ -3867,15 +4495,43 @@ 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)
 {
-    wxMouseCaptureChangedEvent event(GetId(), wxFindWinFromHandle(hWndGainedCapture));
+    // notify windows on the capture stack about lost capture
+    // (see http://sourceforge.net/tracker/index.php?func=detail&aid=1153662&group_id=9863&atid=109863):
+    wxWindowBase::NotifyCaptureLost();
+
+    wxWindow *win = wxFindWinFromHandle(hWndGainedCapture);
+    wxMouseCaptureChangedEvent event(GetId(), win);
     event.SetEventObject(this);
     event.SetEventObject(this);
+    return HandleWindowEvent(event);
+}
+
+bool wxWindowMSW::HandleSettingChange(WXWPARAM wParam, WXLPARAM lParam)
+{
+    // despite MSDN saying "(This message cannot be sent directly to a window.)"
+    // we need to send this to child windows (it is only sent to top-level
+    // windows) so {list,tree}ctrls can adjust their font size if necessary
+    // this is exactly how explorer does it to enable the font size changes
+
+    wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+    while ( node )
+    {
+        // top-level windows already get this message from the system
+        wxWindow *win = node->GetData();
+        if ( !win->IsTopLevel() )
+        {
+            ::SendMessage(GetHwndOf(win), WM_SETTINGCHANGE, wParam, lParam);
+        }
+
+        node = node->GetNext();
+    }
 
 
-    return GetEventHandler()->ProcessEvent(event);
+    // let the system handle it
+    return false;
 }
 
 bool wxWindowMSW::HandleQueryNewPalette()
 }
 
 bool wxWindowMSW::HandleQueryNewPalette()
@@ -3906,7 +4562,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.
@@ -3956,6 +4612,7 @@ extern wxCOLORMAP *wxGetStdColourMap()
             // we want to avoid Windows' "help" and for this we need to have a
             // reference bitmap which can tell us what the RGB values change
             // to.
             // we want to avoid Windows' "help" and for this we need to have a
             // reference bitmap which can tell us what the RGB values change
             // to.
+            wxLogNull logNo; // suppress error if we couldn't load the bitmap
             wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
             if ( stdColourBitmap.Ok() )
             {
             wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
             if ( stdColourBitmap.Ok() )
             {
@@ -4010,9 +4667,6 @@ extern wxCOLORMAP *wxGetStdColourMap()
 
 bool wxWindowMSW::HandlePaint()
 {
 
 bool wxWindowMSW::HandlePaint()
 {
-//    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
-//        return false;
-
     HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
     if ( !hRegion )
         wxLogLastError(wxT("CreateRectRgn"));
     HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
     if ( !hRegion )
         wxLogLastError(wxT("CreateRectRgn"));
@@ -4024,14 +4678,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;
 }
@@ -4042,7 +4700,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);
@@ -4052,76 +4710,145 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 
 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 {
 
 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 {
-    // Prevents flicker when dragging
-    if ( ::IsIconic(GetHwnd()) )
-        return true;
+    wxDCTemp dc(hdc, GetClientSize());
+    wxDCTempImpl *impl = (wxDCTempImpl*) dc.GetImpl();
 
 
-#if 0
-    if (GetParent() && GetParent()->GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
+    impl->SetHDC(hdc);
+    impl->SetWindow((wxWindow *)this);
+
+    wxEraseEvent event(m_windowId, &dc);
+    event.SetEventObject(this);
+    bool rc = HandleWindowEvent(event);
+
+    // must be called manually as ~wxDC doesn't do anything for wxDCTemp
+    impl->SelectOldObjects(hdc);
+
+    return rc;
+}
+
+void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
+{
+    // standard non top level controls (i.e. except the dialogs) always erase
+    // their background themselves in HandleCtlColor() or have some control-
+    // specific ways to set the colours (common controls)
+    if ( IsOfStandardClass() && !IsTopLevel() )
     {
     {
-        return false;
+        event.Skip();
+        return;
     }
 
     }
 
-    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
+    if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
     {
     {
-        if (wxUxThemeEngine::Get())
+        // don't skip the event here, custom background means that the app
+        // is drawing it itself in its OnPaint(), so don't draw it at all
+        // now to avoid flicker
+        return;
+    }
+
+    wxDC *dc = event.GetDC();
+    if (!dc) return;
+    wxMSWDCImpl *impl = (wxMSWDCImpl*) dc->GetImpl();
+
+    // do default background painting
+    if ( !DoEraseBackground(GetHdcOf(*impl)) )
+    {
+        // let the system paint the background
+        event.Skip();
+    }
+}
+
+bool wxWindowMSW::DoEraseBackground(WXHDC hDC)
+{
+    HBRUSH hbr = (HBRUSH)MSWGetBgBrush(hDC);
+    if ( !hbr )
+        return false;
+
+    wxFillRect(GetHwnd(), (HDC)hDC, hbr);
+
+    return true;
+}
+
+WXHBRUSH
+wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), WXHWND hWnd)
+{
+    if ( m_hasBgCol )
+    {
+        // our background colour applies to:
+        //  1. this window itself, always
+        //  2. all children unless the colour is "not inheritable"
+        //  3. even if it is not inheritable, our immediate transparent
+        //     children should still inherit it -- but not any transparent
+        //     children because it would look wrong if a child of non
+        //     transparent child would show our bg colour when the child itself
+        //     does not
+        wxWindow *win = wxFindWinFromHandle(hWnd);
+        if ( win == this ||
+                m_inheritBgCol ||
+                    (win && win->HasTransparentBackground() &&
+                        win->GetParent() == this) )
         {
         {
-            WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB");
-            if (hTheme)
-            {
-                WXURECT rect;
-                ::GetClientRect((HWND) GetHWND(), (RECT*) & rect);
-                wxUxThemeEngine::Get()->m_pfnDrawThemeBackground(hTheme, hdc, 10 /* TABP_BODY */, 0, &rect, &rect);
-                wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme);
-                return true;
-            }
+            // draw children with the same colour as the parent
+            wxBrush *
+                brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour());
+
+            return (WXHBRUSH)GetHbrushOf(*brush);
         }
     }
         }
     }
-#endif
-
-    wxDCTemp dc(hdc);
 
 
-    dc.SetHDC(hdc);
-    dc.SetWindow((wxWindow *)this);
-    dc.BeginDrawing();
+    return 0;
+}
 
 
-    wxEraseEvent event(m_windowId, &dc);
-    event.SetEventObject(this);
-    bool rc = GetEventHandler()->ProcessEvent(event);
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, WXHWND hWndToPaint)
+{
+    if ( !hWndToPaint )
+        hWndToPaint = GetHWND();
 
 
-    dc.EndDrawing();
+    for ( wxWindowMSW *win = this; win; win = win->GetParent() )
+    {
+        WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, hWndToPaint);
+        if ( hBrush )
+            return hBrush;
 
 
-    // must be called manually as ~wxDC doesn't do anything for wxDCTemp
-    dc.SelectOldObjects(hdc);
+        // background is not inherited beyond top level windows
+        if ( win->IsTopLevel() )
+            break;
+    }
 
 
-    return rc;
+    return 0;
 }
 
 }
 
-void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
+bool wxWindowMSW::HandlePrintClient(WXHDC hDC)
 {
 {
-    RECT rect;
-    ::GetClientRect(GetHwnd(), &rect);
+    // we receive this message when DrawThemeParentBackground() is
+    // called from def window proc of several controls under XP and we
+    // must draw properly themed background here
+    //
+    // note that naively I'd expect filling the client rect with the
+    // brush returned by MSWGetBgBrush() work -- but for some reason it
+    // doesn't and we have to call parents MSWPrintChild() which is
+    // supposed to call DrawThemeBackground() with appropriate params
+    //
+    // also note that in this case lParam == PRF_CLIENT but we're
+    // clearly expected to paint the background and nothing else!
 
 
-    wxColour backgroundColour( GetBackgroundColour());
-    COLORREF ref = PALETTERGB(backgroundColour.Red(),
-                              backgroundColour.Green(),
-                              backgroundColour.Blue());
-    HBRUSH hBrush = ::CreateSolidBrush(ref);
-    if ( !hBrush )
-        wxLogLastError(wxT("CreateSolidBrush"));
+    if ( IsTopLevel() || InheritsBackgroundColour() )
+        return false;
 
 
-    HDC hdc = (HDC)event.GetDC()->GetHDC();
+    // sometimes we don't want the parent to handle it at all, instead
+    // return whatever value this window wants
+    if ( !MSWShouldPropagatePrintChild() )
+        return MSWPrintChild(hDC, (wxWindow *)this);
 
 
-#ifndef __WXWINCE__
-    int mode = ::SetMapMode(hdc, MM_TEXT);
-#endif
+    for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
+    {
+        if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
+            return true;
 
 
-    ::FillRect(hdc, &rect, hBrush);
-    ::DeleteObject(hBrush);
+        if ( win->IsTopLevel() || win->InheritsBackgroundColour() )
+            break;
+    }
 
 
-#ifndef __WXWINCE__
-    ::SetMapMode(hdc, mode);
-#endif
+    return false;
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -4133,7 +4860,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()
@@ -4141,15 +4868,16 @@ 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)
 {
-    wxMoveEvent event(wxPoint(x, y), m_windowId);
+    wxPoint point(x,y);
+    wxMoveEvent event(point, m_windowId);
     event.SetEventObject(this);
 
     event.SetEventObject(this);
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleMoving(wxRect& rect)
 }
 
 bool wxWindowMSW::HandleMoving(wxRect& rect)
@@ -4157,16 +4885,63 @@ 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::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
-{
+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
+    // when we resize this window, its children are probably going to be
+    // repositioned as well, prepare to use DeferWindowPos() for them
+    int numChildren = 0;
+    for ( HWND child = ::GetWindow(GetHwndOf(this), GW_CHILD);
+          child;
+          child = ::GetWindow(child, GW_HWNDNEXT) )
+    {
+        numChildren ++;
+    }
+
+    // Protect against valid m_hDWP being overwritten
+    bool useDefer = false;
+
+    if ( numChildren > 1 )
+    {
+        if (!m_hDWP)
+        {
+            m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
+            if ( !m_hDWP )
+            {
+                wxLogLastError(_T("BeginDeferWindowPos"));
+            }
+            if (m_hDWP)
+                useDefer = true;
+        }
+    }
+#endif // USE_DEFERRED_SIZING
+
+    // update this window size
     bool processed = false;
     bool processed = false;
-
     switch ( wParam )
     {
         default:
     switch ( wParam )
     {
         default:
@@ -4193,8 +4968,37 @@ 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
+    // and finally change the positions of all child windows at once
+    if ( useDefer && m_hDWP )
+    {
+        // reset m_hDWP to NULL so that child windows don't try to use our
+        // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't
+        // happen anyhow normally but who knows what weird flow of control we
+        // may have depending on what the users EVT_SIZE handler does...)
+        HDWP hDWP = (HDWP)m_hDWP;
+        m_hDWP = NULL;
+
+        // do put all child controls in place at once
+        if ( !::EndDeferWindowPos(hDWP) )
+        {
+            wxLogLastError(_T("EndDeferWindowPos"));
+        }
+
+        // Reset our children's pending pos/size values.
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+              node;
+              node = node->GetNext() )
+        {
+            wxWindowMSW *child = node->GetData();
+            child->m_pendingPosition = wxDefaultPosition;
+            child->m_pendingSize = wxDefaultSize;
+        }
     }
     }
+#endif // USE_DEFERRED_SIZING
 
     return processed;
 }
 
     return processed;
 }
@@ -4204,16 +5008,15 @@ 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;
 }
 
-bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
+bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo))
 {
 #ifdef __WXWINCE__
 {
 #ifdef __WXWINCE__
-    wxUnusedVar(mmInfo);
     return false;
 #else
     MINMAXINFO *info = (MINMAXINFO *)mmInfo;
     return false;
 #else
     MINMAXINFO *info = (MINMAXINFO *)mmInfo;
@@ -4257,8 +5060,11 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *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 )
     {
@@ -4281,8 +5087,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 )
@@ -4296,28 +5101,33 @@ 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);
     }
     }
-#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
     else
     {
     else
     {
+#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
         // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND
         // notifications to its parent which we want to reflect back to
         // wxSpinCtrl
         wxSpinCtrl *spin = wxSpinCtrl::GetSpinForTextCtrl(control);
         if ( spin && spin->ProcessTextCommand(cmd, id) )
             return true;
         // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND
         // notifications to its parent which we want to reflect back to
         // wxSpinCtrl
         wxSpinCtrl *spin = wxSpinCtrl::GetSpinForTextCtrl(control);
         if ( spin && spin->ProcessTextCommand(cmd, id) )
             return true;
-    }
 #endif // wxUSE_SPINCTRL
 
 #endif // wxUSE_SPINCTRL
 
+#if wxUSE_CHOICE && defined(__SMARTPHONE__)
+        // the listbox ctrl which is logically part of wxChoice sends WM_COMMAND
+        // notifications to its parent which we want to reflect back to
+        // wxChoice
+        wxChoice *choice = wxChoice::GetChoiceForListBox(control);
+        if ( choice && choice->MSWCommand(cmd, id) )
+            return true;
+#endif
+    }
+
     return false;
 }
 
     return false;
 }
 
@@ -4339,25 +5149,26 @@ 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) & 0x80000000) != 0;
-    // Returns different negative values on WinME and WinNT,
-    // so simply test for negative value.
-    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());
 #endif
 
 
 #ifndef __WXWINCE__
     event.SetTimestamp(::GetMessageTime());
 #endif
 
-    event.m_eventObject = this;
+    event.SetEventObject(this);
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX = x;
-    m_lastMouseY = y;
-    m_lastMouseEvent = event.GetEventType();
+    gs_lastMouseEvent.pos = ClientToScreen(wxPoint(x, y));
+    gs_lastMouseEvent.type = event.GetEventType();
 #endif // wxUSE_MOUSEEVENT_HACK
 }
 
 #endif // wxUSE_MOUSEEVENT_HACK
 }
 
+#ifdef __WXWINCE__
 // Windows doesn't send the mouse events to the static controls (which are
 // transparent in the sense that their WM_NCHITTEST handler returns
 // HTTRANSPARENT) at all but we want all controls to receive the mouse events
 // Windows doesn't send the mouse events to the static controls (which are
 // transparent in the sense that their WM_NCHITTEST handler returns
 // HTTRANSPARENT) at all but we want all controls to receive the mouse events
@@ -4368,7 +5179,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
 // Notice that this is not done for the mouse move events because this could
 // (would?) be too slow, but only for clicks which means that the static texts
 // still don't get move, enter nor leave events.
 // Notice that this is not done for the mouse move events because this could
 // (would?) be too slow, but only for clicks which means that the static texts
 // still don't get move, enter nor leave events.
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y)
 {
     wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
 
 {
     wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
 
@@ -4408,7 +5219,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
@@ -4421,11 +5232,12 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
 
     return win;
 }
 
     return win;
 }
+#endif // __WXWINCE__
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
     // the mouse events take consecutive IDs from WM_MOUSEFIRST to
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
     // the mouse events take consecutive IDs from WM_MOUSEFIRST to
-    // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+    // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
     // from the message id and take the value in the table to get wxWin event
     // id
     static const wxEventType eventsMouse[] =
     // from the message id and take the value in the table to get wxWin event
     // id
     static const wxEventType eventsMouse[] =
@@ -4439,13 +5251,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)
@@ -4460,38 +5292,77 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         {
             // Generate an ENTER event
             m_mouseInWindow = true;
         {
             // Generate an ENTER event
             m_mouseInWindow = true;
-#if _WIN32_WINNT >= 0x0400
-#ifndef __WXWINCE__
-            TRACKMOUSEEVENT trackinfo;
-
-            trackinfo.cbSize = sizeof(trackinfo);
-            trackinfo.dwFlags = TME_LEAVE;
-            trackinfo.hwndTrack = GetHwnd();
-            //Use the commctrl.h _TrackMouseEvent, which will call the
-            // appropriate TrackMouseEvent or emulate it ( win95 )
-            // else we need _WIN32_WINNT >= 0x0400
-            _TrackMouseEvent(&trackinfo);
-#endif
-#endif
+
+#ifdef HAVE_TRACKMOUSEEVENT
+            typedef BOOL (WINAPI *_TrackMouseEvent_t)(LPTRACKMOUSEEVENT);
+#ifdef __WXWINCE__
+            static const _TrackMouseEvent_t
+                s_pfn_TrackMouseEvent = _TrackMouseEvent;
+#else // !__WXWINCE__
+            static _TrackMouseEvent_t s_pfn_TrackMouseEvent;
+            static bool s_initDone = false;
+            if ( !s_initDone )
+            {
+                // see comment in wxApp::GetComCtl32Version() explaining the
+                // use of wxLoadedDLL
+                wxLoadedDLL dllComCtl32(_T("comctl32.dll"));
+                if ( dllComCtl32.IsLoaded() )
+                {
+                    s_pfn_TrackMouseEvent = (_TrackMouseEvent_t)
+                        dllComCtl32.RawGetSymbol(_T("_TrackMouseEvent"));
+                }
+
+                s_initDone = true;
+            }
+
+            if ( s_pfn_TrackMouseEvent )
+#endif // __WXWINCE__/!__WXWINCE__
+            {
+                WinStruct<TRACKMOUSEEVENT> trackinfo;
+
+                trackinfo.dwFlags = TME_LEAVE;
+                trackinfo.hwndTrack = GetHwnd();
+
+                (*s_pfn_TrackMouseEvent)(&trackinfo);
+            }
+#endif // HAVE_TRACKMOUSEEVENT
+
             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
+    else // mouse not in window
+    {
+        // Check if we need to send a LEAVE event
+        // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so
+        // send it here if we are using native mouse leave tracking
+        if ( HasCapture() && !IsMouseInWindow() )
+        {
+            GenerateMouseLeave();
+        }
+    }
+#endif // HAVE_TRACKMOUSEEVENT
 
 #if wxUSE_MOUSEEVENT_HACK
 
 #if wxUSE_MOUSEEVENT_HACK
-    // Window gets a click down message followed by a mouse move message even
-    // if position isn't changed!  We want to discard the trailing move event
-    // if x and y are the same.
-    if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN ||
-          m_lastMouseEvent == wxEVT_LEFT_DOWN ||
-          m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
-         (m_lastMouseX == x && m_lastMouseY == y) )
-    {
-        m_lastMouseEvent = wxEVT_MOTION;
+    // Windows often generates mouse events even if mouse position hasn't
+    // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576)
+    //
+    // Filter this out as it can result in unexpected behaviour compared to
+    // other platforms
+    if ( gs_lastMouseEvent.type == wxEVT_RIGHT_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_LEFT_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_MIDDLE_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_MOTION )
+    {
+        if ( ClientToScreen(wxPoint(x, y)) == gs_lastMouseEvent.pos )
+        {
+            gs_lastMouseEvent.type = wxEVT_MOTION;
 
 
-        return false;
+            return false;
+        }
     }
 #endif // wxUSE_MOUSEEVENT_HACK
 
     }
 #endif // wxUSE_MOUSEEVENT_HACK
 
@@ -4502,11 +5373,14 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
 {
 #if wxUSE_MOUSEWHEEL
 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
 {
 #if wxUSE_MOUSEWHEEL
+    // notice that WM_MOUSEWHEEL position is in screen coords (as it's
+    // forwarded up to the parent by DefWindowProc()) and not in the client
+    // ones as all the other messages, translate them to the client coords for
+    // consistency
+    const wxPoint
+        pt = ScreenToClient(wxPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
     wxMouseEvent event(wxEVT_MOUSEWHEEL);
     wxMouseEvent event(wxEVT_MOUSEWHEEL);
-    InitMouseEvent(event,
-                   GET_X_LPARAM(lParam),
-                   GET_Y_LPARAM(lParam),
-                   LOWORD(wParam));
+    InitMouseEvent(event, pt.x, pt.y, LOWORD(wParam));
     event.m_wheelRotation = (short)HIWORD(wParam);
     event.m_wheelDelta = WHEEL_DELTA;
 
     event.m_wheelRotation = (short)HIWORD(wParam);
     event.m_wheelDelta = WHEEL_DELTA;
 
@@ -4525,16 +5399,55 @@ 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
-    (void) wParam;
-    (void) lParam;
+#else // !wxUSE_MOUSEWHEEL
+    wxUnusedVar(wParam);
+    wxUnusedVar(lParam);
 
     return false;
 
     return false;
-#endif
+#endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL
 }
 
 }
 
+void wxWindowMSW::GenerateMouseLeave()
+{
+    m_mouseInWindow = false;
+
+    int state = 0;
+    if ( wxIsShiftDown() )
+        state |= MK_SHIFT;
+    if ( wxIsCtrlDown() )
+        state |= MK_CONTROL;
+
+    // Only the high-order bit should be tested
+    if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
+        state |= MK_LBUTTON;
+    if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
+        state |= MK_MBUTTON;
+    if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
+        state |= MK_RBUTTON;
+
+    POINT pt;
+#ifdef __WXWINCE__
+    if ( !::GetCursorPosWinCE(&pt) )
+#else
+    if ( !::GetCursorPos(&pt) )
+#endif
+    {
+        wxLogLastError(_T("GetCursorPos"));
+    }
+
+    // we need to have client coordinates here for symmetry with
+    // wxEVT_ENTER_WINDOW
+    RECT rect = wxGetWindowRect(GetHwnd());
+    pt.x -= rect.left;
+    pt.y -= rect.top;
+
+    wxMouseEvent event(wxEVT_LEAVE_WINDOW);
+    InitMouseEvent(event, pt.x, pt.y, state);
+
+    (void)HandleWindowEvent(event);
+}
 
 // ---------------------------------------------------------------------------
 // keyboard handling
 
 // ---------------------------------------------------------------------------
 // keyboard handling
@@ -4553,10 +5466,10 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
     event.m_controlDown = wxIsCtrlDown();
     event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
 
     event.m_controlDown = wxIsCtrlDown();
     event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
 
-    event.m_eventObject = (wxWindow *)this; // const_cast
+    event.SetEventObject((wxWindow *)this); // const_cast
     event.m_keyCode = id;
 #if wxUSE_UNICODE
     event.m_keyCode = id;
 #if wxUSE_UNICODE
-    event.m_uniChar = wParam;
+    event.m_uniChar = (wxChar) wParam;
 #endif
     event.m_rawCode = (wxUint32) wParam;
     event.m_rawFlags = (wxUint32) lParam;
 #endif
     event.m_rawCode = (wxUint32) wParam;
     event.m_rawFlags = (wxUint32) lParam;
@@ -4566,7 +5479,11 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
 
     // translate the position to client coords
     POINT pt;
 
     // translate the position to client coords
     POINT pt;
+#ifdef __WXWINCE__
+    GetCursorPosWinCE(&pt);
+#else
     GetCursorPos(&pt);
     GetCursorPos(&pt);
+#endif
     RECT rect;
     GetWindowRect(GetHwnd(),&rect);
     pt.x -= rect.left;
     RECT rect;
     GetWindowRect(GetHwnd(),&rect);
     pt.x -= rect.left;
@@ -4585,35 +5502,14 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
     int id;
     if ( isASCII )
     {
     int id;
     if ( isASCII )
     {
-        // If 1 -> 26, translate to either special keycode or just set
-        // ctrlDown.  IOW, Ctrl-C should result in keycode == 3 and
-        // ControlDown() == true.
         id = wParam;
         id = wParam;
-        if ( (id > 0) && (id < 27) )
-        {
-            switch (id)
-            {
-                case 13:
-                    id = WXK_RETURN;
-                    break;
-
-                case 8:
-                    id = WXK_BACK;
-                    break;
-
-                case 9:
-                    id = WXK_TAB;
-                    break;
-
-                default:
-                    //ctrlDown = true;
-                    break;
-            }
-        }
     }
     else // we're called from WM_KEYDOWN
     {
     }
     else // we're called from WM_KEYDOWN
     {
-        id = wxCharCodeMSWToWX(wParam, lParam);
+        // don't pass lParam to wxCharCodeMSWToWX() here because we don't want
+        // to get numpad key codes: CHAR events should use the logical keys
+        // such as WXK_HOME instead of WXK_NUMPAD_HOME which is for KEY events
+        id = wxCharCodeMSWToWX(wParam);
         if ( id == 0 )
         {
             // it's ASCII and will be processed here only when called from
         if ( id == 0 )
         {
             // it's ASCII and will be processed here only when called from
@@ -4637,7 +5533,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)
@@ -4650,16 +5546,8 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
         id = wParam;
     }
 
         id = wParam;
     }
 
-    if ( id != -1 ) // VZ: does this ever happen (FIXME)?
-    {
-        wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
-        if ( GetEventHandler()->ProcessEvent(event) )
-        {
-            return true;
-        }
-    }
-
-    return false;
+    wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
+    return HandleWindowEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
@@ -4672,17 +5560,13 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
         id = wParam;
     }
 
         id = wParam;
     }
 
-    if ( id != -1 ) // VZ: does this ever happen (FIXME)?
-    {
-        wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
-        if ( GetEventHandler()->ProcessEvent(event) )
-            return true;
-    }
-
-    return false;
+    wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
+    return HandleWindowEvent(event);
 }
 
 }
 
-int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
+#if wxUSE_MENUS
+int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
+                                WXLPARAM WXUNUSED_IN_WINCE(lParam))
 {
     // FIXME: implement GetMenuItemCount for WinCE, possibly
     // in terms of GetMenuItemInfo
 {
     // FIXME: implement GetMenuItemCount for WinCE, possibly
     // in terms of GetMenuItemInfo
@@ -4692,12 +5576,20 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
+
+    // we could use MIIM_FTYPE here as we only need to know if the item is
+    // ownerdrawn or not and not dwTypeData which MIIM_TYPE also returns, but
+    // MIIM_FTYPE is not supported under Win95
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
+        // previous loop iteration could modify it, reset it back before
+        // calling GetMenuItemInfo() to prevent it from overflowing dwTypeData
+        mii.cch = 0;
+
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
@@ -4707,7 +5599,7 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
                 //  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('&') )
@@ -4720,7 +5612,7 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
                         // FIXME-UNICODE: this comparison doesn't risk to work
                         // for non ASCII accelerator characters I'm afraid, but
                         // what can we do?
                         // FIXME-UNICODE: this comparison doesn't risk to work
                         // for non ASCII accelerator characters I'm afraid, but
                         // what can we do?
-                        if ( wxToupper(*p) == (wchar_t)chAccel )
+                        if ( (wchar_t)wxToupper(*p) == (wchar_t)chAccel )
                         {
                             return i;
                         }
                         {
                             return i;
                         }
@@ -4735,18 +5627,28 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
         }
         else // failed to get the menu text?
         {
         }
         else // failed to get the menu text?
         {
-            // it's not fatal, so don't show error, but still log
-            // it
+            // it's not fatal, so don't show error, but still log it
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
-#else
-    wxUnusedVar(chAccel);
-    wxUnusedVar(lParam);
 #endif
     return wxNOT_FOUND;
 }
 
 #endif
     return wxNOT_FOUND;
 }
 
+#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;
+    wxClipboardTextEvent evt(type, GetId());
+
+    evt.SetEventObject(this);
+
+    return HandleWindowEvent(evt);
+}
+
 // ---------------------------------------------------------------------------
 // joystick
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // joystick
 // ---------------------------------------------------------------------------
@@ -4829,7 +5731,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);
@@ -4856,32 +5758,32 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
     wxScrollWinEvent event;
     event.SetPosition(pos);
     event.SetOrientation(orientation);
     wxScrollWinEvent event;
     event.SetPosition(pos);
     event.SetOrientation(orientation);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     switch ( wParam )
     {
     case SB_TOP:
 
     switch ( wParam )
     {
     case SB_TOP:
-        event.m_eventType = wxEVT_SCROLLWIN_TOP;
+        event.SetEventType(wxEVT_SCROLLWIN_TOP);
         break;
 
     case SB_BOTTOM:
         break;
 
     case SB_BOTTOM:
-        event.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
+        event.SetEventType(wxEVT_SCROLLWIN_BOTTOM);
         break;
 
     case SB_LINEUP:
         break;
 
     case SB_LINEUP:
-        event.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+        event.SetEventType(wxEVT_SCROLLWIN_LINEUP);
         break;
 
     case SB_LINEDOWN:
         break;
 
     case SB_LINEDOWN:
-        event.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+        event.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
         break;
 
     case SB_PAGEUP:
         break;
 
     case SB_PAGEUP:
-        event.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+        event.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
         break;
 
     case SB_PAGEDOWN:
         break;
 
     case SB_PAGEDOWN:
-        event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+        event.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
         break;
 
     case SB_THUMBPOSITION:
         break;
 
     case SB_THUMBPOSITION:
@@ -4896,27 +5798,50 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
             scrollInfo.fMask = SIF_TRACKPOS;
 
             if ( !::GetScrollInfo(GetHwnd(),
             scrollInfo.fMask = SIF_TRACKPOS;
 
             if ( !::GetScrollInfo(GetHwnd(),
-                                  orientation == wxHORIZONTAL ? SB_HORZ
-                                                              : SB_VERT,
+                                  WXOrientToSB(orientation),
                                   &scrollInfo) )
             {
                                   &scrollInfo) )
             {
-                // Not neccessarily an error, if there are no scrollbars yet.
+                // Not necessarily an error, if there are no scrollbars yet.
                 // wxLogLastError(_T("GetScrollInfo"));
             }
 
             event.SetPosition(scrollInfo.nTrackPos);
         }
 
                 // wxLogLastError(_T("GetScrollInfo"));
             }
 
             event.SetPosition(scrollInfo.nTrackPos);
         }
 
-        event.m_eventType = wParam == SB_THUMBPOSITION
+        event.SetEventType( wParam == SB_THUMBPOSITION
                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
-                                : wxEVT_SCROLLWIN_THUMBTRACK;
+                                : wxEVT_SCROLLWIN_THUMBTRACK );
         break;
 
     default:
         return false;
     }
 
         break;
 
     default:
         return false;
     }
 
-    return GetEventHandler()->ProcessEvent(event);
+    return HandleWindowEvent(event);
+}
+
+// ----------------------------------------------------------------------------
+// custom message handlers
+// ----------------------------------------------------------------------------
+
+/* static */ bool
+wxWindowMSW::MSWRegisterMessageHandler(int msg, MSWMessageHandler handler)
+{
+    wxCHECK_MSG( gs_messageHandlers.find(msg) == gs_messageHandlers.end(),
+                 false, _T("registering handler for the same message twice") );
+
+    gs_messageHandlers[msg] = handler;
+    return true;
+}
+
+/* static */ void
+wxWindowMSW::MSWUnregisterMessageHandler(int msg, MSWMessageHandler handler)
+{
+    const MSWMessageHandlers::iterator i = gs_messageHandlers.find(msg);
+    wxCHECK_RET( i != gs_messageHandlers.end() && i->second == handler,
+                 _T("unregistering non-registered handler?") );
+
+    gs_messageHandlers.erase(i);
 }
 
 // ===========================================================================
 }
 
 // ===========================================================================
@@ -4950,221 +5875,349 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font)
     //   the_font.ReleaseResource();
 }
 
     //   the_font.ReleaseResource();
 }
 
-// Returns 0 if was a normal ASCII value, not a special key. This indicates that
-// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
-int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
+// use the "extended" bit (24) of lParam to distinguish extended keys
+// from normal keys as the same key is sent
+static inline
+int ChooseNormalOrExtended(int lParam, int keyNormal, int keyExtended)
 {
 {
-    int id;
-    switch (keySym)
-    {
-        case VK_CANCEL:     id = WXK_CANCEL; break;
-        case VK_BACK:       id = WXK_BACK; break;
-        case VK_TAB:        id = WXK_TAB; break;
-        case VK_CLEAR:      id = WXK_CLEAR; break;
-        case VK_SHIFT:      id = WXK_SHIFT; break;
-        case VK_CONTROL:    id = WXK_CONTROL; break;
-        case VK_MENU :      id = WXK_MENU; break;
-        case VK_PAUSE:      id = WXK_PAUSE; break;
-        case VK_CAPITAL:    id = WXK_CAPITAL; break;
-        case VK_SPACE:      id = WXK_SPACE; break;
-        case VK_ESCAPE:     id = WXK_ESCAPE; break;
-        case VK_PRIOR:      id = WXK_PRIOR; break;
-        case VK_NEXT :      id = WXK_NEXT; break;
-        case VK_END:        id = WXK_END; break;
-        case VK_HOME :      id = WXK_HOME; break;
-        case VK_LEFT :      id = WXK_LEFT; break;
-        case VK_UP:         id = WXK_UP; break;
-        case VK_RIGHT:      id = WXK_RIGHT; break;
-        case VK_DOWN :      id = WXK_DOWN; break;
-        case VK_SELECT:     id = WXK_SELECT; break;
-        case VK_PRINT:      id = WXK_PRINT; break;
-        case VK_EXECUTE:    id = WXK_EXECUTE; break;
-        case VK_INSERT:     id = WXK_INSERT; break;
-        case VK_DELETE:     id = WXK_DELETE; break;
-        case VK_HELP :      id = WXK_HELP; break;
-        case VK_NUMPAD0:    id = WXK_NUMPAD0; break;
-        case VK_NUMPAD1:    id = WXK_NUMPAD1; break;
-        case VK_NUMPAD2:    id = WXK_NUMPAD2; break;
-        case VK_NUMPAD3:    id = WXK_NUMPAD3; break;
-        case VK_NUMPAD4:    id = WXK_NUMPAD4; break;
-        case VK_NUMPAD5:    id = WXK_NUMPAD5; break;
-        case VK_NUMPAD6:    id = WXK_NUMPAD6; break;
-        case VK_NUMPAD7:    id = WXK_NUMPAD7; break;
-        case VK_NUMPAD8:    id = WXK_NUMPAD8; break;
-        case VK_NUMPAD9:    id = WXK_NUMPAD9; break;
-        case VK_MULTIPLY:   id = WXK_NUMPAD_MULTIPLY; break;
-        case VK_ADD:        id = WXK_NUMPAD_ADD; break;
-        case VK_SUBTRACT:   id = WXK_NUMPAD_SUBTRACT; break;
-        case VK_DECIMAL:    id = WXK_NUMPAD_DECIMAL; break;
-        case VK_DIVIDE:     id = WXK_NUMPAD_DIVIDE; break;
-        case VK_F1:         id = WXK_F1; break;
-        case VK_F2:         id = WXK_F2; break;
-        case VK_F3:         id = WXK_F3; break;
-        case VK_F4:         id = WXK_F4; break;
-        case VK_F5:         id = WXK_F5; break;
-        case VK_F6:         id = WXK_F6; break;
-        case VK_F7:         id = WXK_F7; break;
-        case VK_F8:         id = WXK_F8; break;
-        case VK_F9:         id = WXK_F9; break;
-        case VK_F10:        id = WXK_F10; break;
-        case VK_F11:        id = WXK_F11; break;
-        case VK_F12:        id = WXK_F12; break;
-        case VK_F13:        id = WXK_F13; break;
-        case VK_F14:        id = WXK_F14; break;
-        case VK_F15:        id = WXK_F15; break;
-        case VK_F16:        id = WXK_F16; break;
-        case VK_F17:        id = WXK_F17; break;
-        case VK_F18:        id = WXK_F18; break;
-        case VK_F19:        id = WXK_F19; break;
-        case VK_F20:        id = WXK_F20; break;
-        case VK_F21:        id = WXK_F21; break;
-        case VK_F22:        id = WXK_F22; break;
-        case VK_F23:        id = WXK_F23; break;
-        case VK_F24:        id = WXK_F24; break;
-        case VK_NUMLOCK:    id = WXK_NUMLOCK; break;
-        case VK_SCROLL:     id = WXK_SCROLL; break;
-
-        case VK_OEM_1:      id = ';'; break;
-        case VK_OEM_PLUS:   id = '+'; break;
-        case VK_OEM_COMMA:  id = ','; break;
-        case VK_OEM_MINUS:  id = '-'; break;
-        case VK_OEM_PERIOD: id = '.'; break;
-        case VK_OEM_2:      id = '/'; break;
-        case VK_OEM_3:      id = '~'; break;
-        case VK_OEM_4:      id = '['; break;
-        case VK_OEM_5:      id = '\\'; break;
-        case VK_OEM_6:      id = ']'; break;
-        case VK_OEM_7:      id = '\''; break;
+    // except that if lParam is 0, it means we don't have real lParam from
+    // WM_KEYDOWN but are just translating just a VK constant (e.g. done from
+    // msw/treectrl.cpp when processing TVN_KEYDOWN) -- then assume this is a
+    // non-numpad (hence extended) key as this is a more common case
+    return !lParam || (lParam & (1 << 24)) ? keyExtended : keyNormal;
+}
+
+// this array contains the Windows virtual key codes which map one to one to
+// WXK_xxx constants and is used in wxCharCodeMSWToWX/WXToMSW() below
+//
+// note that keys having a normal and numpad version (e.g. WXK_HOME and
+// WXK_NUMPAD_HOME) are not included in this table as the mapping is not 1-to-1
+static const struct wxKeyMapping
+{
+    int vk;
+    wxKeyCode wxk;
+} gs_specialKeys[] =
+{
+    { VK_CANCEL,        WXK_CANCEL },
+    { VK_BACK,          WXK_BACK },
+    { VK_TAB,           WXK_TAB },
+    { VK_CLEAR,         WXK_CLEAR },
+    { VK_SHIFT,         WXK_SHIFT },
+    { VK_CONTROL,       WXK_CONTROL },
+    { VK_MENU ,         WXK_ALT },
+    { VK_PAUSE,         WXK_PAUSE },
+    { VK_CAPITAL,       WXK_CAPITAL },
+    { VK_SPACE,         WXK_SPACE },
+    { VK_ESCAPE,        WXK_ESCAPE },
+    { VK_SELECT,        WXK_SELECT },
+    { VK_PRINT,         WXK_PRINT },
+    { VK_EXECUTE,       WXK_EXECUTE },
+    { VK_SNAPSHOT,      WXK_SNAPSHOT },
+    { VK_HELP,          WXK_HELP },
+
+    { VK_NUMPAD0,       WXK_NUMPAD0 },
+    { VK_NUMPAD1,       WXK_NUMPAD1 },
+    { VK_NUMPAD2,       WXK_NUMPAD2 },
+    { VK_NUMPAD3,       WXK_NUMPAD3 },
+    { VK_NUMPAD4,       WXK_NUMPAD4 },
+    { VK_NUMPAD5,       WXK_NUMPAD5 },
+    { VK_NUMPAD6,       WXK_NUMPAD6 },
+    { VK_NUMPAD7,       WXK_NUMPAD7 },
+    { VK_NUMPAD8,       WXK_NUMPAD8 },
+    { VK_NUMPAD9,       WXK_NUMPAD9 },
+    { VK_MULTIPLY,      WXK_NUMPAD_MULTIPLY },
+    { VK_ADD,           WXK_NUMPAD_ADD },
+    { VK_SUBTRACT,      WXK_NUMPAD_SUBTRACT },
+    { VK_DECIMAL,       WXK_NUMPAD_DECIMAL },
+    { VK_DIVIDE,        WXK_NUMPAD_DIVIDE },
+
+    { VK_F1,            WXK_F1 },
+    { VK_F2,            WXK_F2 },
+    { VK_F3,            WXK_F3 },
+    { VK_F4,            WXK_F4 },
+    { VK_F5,            WXK_F5 },
+    { VK_F6,            WXK_F6 },
+    { VK_F7,            WXK_F7 },
+    { VK_F8,            WXK_F8 },
+    { VK_F9,            WXK_F9 },
+    { VK_F10,           WXK_F10 },
+    { VK_F11,           WXK_F11 },
+    { VK_F12,           WXK_F12 },
+    { VK_F13,           WXK_F13 },
+    { VK_F14,           WXK_F14 },
+    { VK_F15,           WXK_F15 },
+    { VK_F16,           WXK_F16 },
+    { VK_F17,           WXK_F17 },
+    { VK_F18,           WXK_F18 },
+    { VK_F19,           WXK_F19 },
+    { VK_F20,           WXK_F20 },
+    { VK_F21,           WXK_F21 },
+    { VK_F22,           WXK_F22 },
+    { VK_F23,           WXK_F23 },
+    { VK_F24,           WXK_F24 },
+
+    { VK_NUMLOCK,       WXK_NUMLOCK },
+    { VK_SCROLL,        WXK_SCROLL },
 
 #ifdef VK_APPS
 
 #ifdef VK_APPS
-        case VK_LWIN:       id = WXK_WINDOWS_LEFT; break;
-        case VK_RWIN:       id = WXK_WINDOWS_RIGHT; break;
-        case VK_APPS:       id = WXK_WINDOWS_MENU; break;
+    { VK_LWIN,          WXK_WINDOWS_LEFT },
+    { VK_RWIN,          WXK_WINDOWS_RIGHT },
+    { VK_APPS,          WXK_WINDOWS_MENU },
 #endif // VK_APPS defined
 #endif // VK_APPS defined
+};
+
+// Returns 0 if was a normal ASCII value, not a special key. This indicates that
+// the key should be ignored by WM_KEYDOWN and processed by WM_CHAR instead.
+int wxCharCodeMSWToWX(int vk, WXLPARAM lParam)
+{
+    // check the table first
+    for ( size_t n = 0; n < WXSIZEOF(gs_specialKeys); n++ )
+    {
+        if ( gs_specialKeys[n].vk == vk )
+            return gs_specialKeys[n].wxk;
+    }
+
+    // keys requiring special handling
+    int wxk;
+    switch ( vk )
+    {
+        // the mapping for these keys may be incorrect on non-US keyboards so
+        // maybe we shouldn't map them to ASCII values at all
+        case VK_OEM_1:      wxk = ';'; break;
+        case VK_OEM_PLUS:   wxk = '+'; break;
+        case VK_OEM_COMMA:  wxk = ','; break;
+        case VK_OEM_MINUS:  wxk = '-'; break;
+        case VK_OEM_PERIOD: wxk = '.'; break;
+        case VK_OEM_2:      wxk = '/'; break;
+        case VK_OEM_3:      wxk = '~'; break;
+        case VK_OEM_4:      wxk = '['; break;
+        case VK_OEM_5:      wxk = '\\'; break;
+        case VK_OEM_6:      wxk = ']'; break;
+        case VK_OEM_7:      wxk = '\''; break;
+
+        // handle extended keys
+        case VK_PRIOR:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_PAGEUP, WXK_PAGEUP);
+            break;
+
+        case VK_NEXT:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_PAGEDOWN, WXK_PAGEDOWN);
+            break;
+
+        case VK_END:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_END, WXK_END);
+            break;
+
+        case VK_HOME:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_HOME, WXK_HOME);
+            break;
+
+        case VK_LEFT:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_LEFT, WXK_LEFT);
+            break;
+
+        case VK_UP:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_UP, WXK_UP);
+            break;
+
+        case VK_RIGHT:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_RIGHT, WXK_RIGHT);
+            break;
+
+        case VK_DOWN:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_DOWN, WXK_DOWN);
+            break;
+
+        case VK_INSERT:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_INSERT, WXK_INSERT);
+            break;
+
+        case VK_DELETE:
+            wxk = ChooseNormalOrExtended(lParam, WXK_NUMPAD_DELETE, WXK_DELETE);
+            break;
 
         case VK_RETURN:
 
         case VK_RETURN:
-            // the same key is sent for both the "return" key on the main
-            // keyboard and the numeric keypad but we want to distinguish
-            // between them: we do this using the "extended" bit (24) of lParam
-            id = lParam & (1 << 24) ? WXK_NUMPAD_ENTER : WXK_RETURN;
+            // don't use ChooseNormalOrExtended() here as the keys are reversed
+            // here: numpad enter is the extended one
+            wxk = lParam && (lParam & (1 << 24)) ? WXK_NUMPAD_ENTER : WXK_RETURN;
             break;
 
         default:
             break;
 
         default:
-            id = 0;
-    }
-
-    return id;
-}
-
-int wxCharCodeWXToMSW(int id, bool *isVirtual)
-{
-    *isVirtual = true;
-    int keySym;
-    switch (id)
-    {
-    case WXK_CANCEL:    keySym = VK_CANCEL; break;
-    case WXK_CLEAR:     keySym = VK_CLEAR; break;
-    case WXK_SHIFT:     keySym = VK_SHIFT; break;
-    case WXK_CONTROL:   keySym = VK_CONTROL; break;
-    case WXK_ALT:       keySym = VK_MENU; break;
-    case WXK_MENU :     keySym = VK_MENU; break;
-    case WXK_PAUSE:     keySym = VK_PAUSE; break;
-    case WXK_CAPITAL:   keySym = VK_CAPITAL; break;
-    case WXK_PRIOR:     keySym = VK_PRIOR; break;
-    case WXK_NEXT :     keySym = VK_NEXT; break;
-    case WXK_END:       keySym = VK_END; break;
-    case WXK_HOME :     keySym = VK_HOME; break;
-    case WXK_LEFT :     keySym = VK_LEFT; break;
-    case WXK_UP:        keySym = VK_UP; break;
-    case WXK_RIGHT:     keySym = VK_RIGHT; break;
-    case WXK_DOWN :     keySym = VK_DOWN; break;
-    case WXK_SELECT:    keySym = VK_SELECT; break;
-    case WXK_PRINT:     keySym = VK_PRINT; break;
-    case WXK_EXECUTE:   keySym = VK_EXECUTE; break;
-    case WXK_INSERT:    keySym = VK_INSERT; break;
-    case WXK_DELETE:    keySym = VK_DELETE; break;
-    case WXK_HELP :     keySym = VK_HELP; break;
-    case WXK_NUMPAD0:   keySym = VK_NUMPAD0; break;
-    case WXK_NUMPAD1:   keySym = VK_NUMPAD1; break;
-    case WXK_NUMPAD2:   keySym = VK_NUMPAD2; break;
-    case WXK_NUMPAD3:   keySym = VK_NUMPAD3; break;
-    case WXK_NUMPAD4:   keySym = VK_NUMPAD4; break;
-    case WXK_NUMPAD5:   keySym = VK_NUMPAD5; break;
-    case WXK_NUMPAD6:   keySym = VK_NUMPAD6; break;
-    case WXK_NUMPAD7:   keySym = VK_NUMPAD7; break;
-    case WXK_NUMPAD8:   keySym = VK_NUMPAD8; break;
-    case WXK_NUMPAD9:   keySym = VK_NUMPAD9; break;
-    case WXK_NUMPAD_MULTIPLY:  keySym = VK_MULTIPLY; break;
-    case WXK_NUMPAD_ADD:       keySym = VK_ADD; break;
-    case WXK_NUMPAD_SUBTRACT:  keySym = VK_SUBTRACT; break;
-    case WXK_NUMPAD_DECIMAL:   keySym = VK_DECIMAL; break;
-    case WXK_NUMPAD_DIVIDE:    keySym = VK_DIVIDE; break;
-    case WXK_F1:        keySym = VK_F1; break;
-    case WXK_F2:        keySym = VK_F2; break;
-    case WXK_F3:        keySym = VK_F3; break;
-    case WXK_F4:        keySym = VK_F4; break;
-    case WXK_F5:        keySym = VK_F5; break;
-    case WXK_F6:        keySym = VK_F6; break;
-    case WXK_F7:        keySym = VK_F7; break;
-    case WXK_F8:        keySym = VK_F8; break;
-    case WXK_F9:        keySym = VK_F9; break;
-    case WXK_F10:       keySym = VK_F10; break;
-    case WXK_F11:       keySym = VK_F11; break;
-    case WXK_F12:       keySym = VK_F12; break;
-    case WXK_F13:       keySym = VK_F13; break;
-    case WXK_F14:       keySym = VK_F14; break;
-    case WXK_F15:       keySym = VK_F15; break;
-    case WXK_F16:       keySym = VK_F16; break;
-    case WXK_F17:       keySym = VK_F17; break;
-    case WXK_F18:       keySym = VK_F18; break;
-    case WXK_F19:       keySym = VK_F19; break;
-    case WXK_F20:       keySym = VK_F20; break;
-    case WXK_F21:       keySym = VK_F21; break;
-    case WXK_F22:       keySym = VK_F22; break;
-    case WXK_F23:       keySym = VK_F23; break;
-    case WXK_F24:       keySym = VK_F24; break;
-    case WXK_NUMLOCK:   keySym = VK_NUMLOCK; break;
-    case WXK_SCROLL:    keySym = VK_SCROLL; break;
-    default:
-        {
-            *isVirtual = false;
-            keySym = id;
+            wxk = 0;
+    }
+
+    return wxk;
+}
+
+WXWORD wxCharCodeWXToMSW(int wxk, bool *isVirtual)
+{
+    if ( isVirtual )
+        *isVirtual = true;
+
+    // check the table first
+    for ( size_t n = 0; n < WXSIZEOF(gs_specialKeys); n++ )
+    {
+        if ( gs_specialKeys[n].wxk == wxk )
+            return gs_specialKeys[n].vk;
+    }
+
+    // and then check for special keys not included in the table
+    WXWORD vk;
+    switch ( wxk )
+    {
+        case WXK_PAGEUP:
+        case WXK_NUMPAD_PAGEUP:
+            vk = VK_PRIOR;
+            break;
+
+        case WXK_PAGEDOWN:
+        case WXK_NUMPAD_PAGEDOWN:
+            vk = VK_NEXT;
+            break;
+
+        case WXK_END:
+        case WXK_NUMPAD_END:
+            vk = VK_END;
+            break;
+
+        case WXK_HOME:
+        case WXK_NUMPAD_HOME:
+            vk = VK_HOME;
+            break;
+
+        case WXK_LEFT:
+        case WXK_NUMPAD_LEFT:
+            vk = VK_LEFT;
+            break;
+
+        case WXK_UP:
+        case WXK_NUMPAD_UP:
+            vk = VK_UP;
+            break;
+
+        case WXK_RIGHT:
+        case WXK_NUMPAD_RIGHT:
+            vk = VK_RIGHT;
+            break;
+
+        case WXK_DOWN:
+        case WXK_NUMPAD_DOWN:
+            vk = VK_DOWN;
+            break;
+
+        case WXK_INSERT:
+        case WXK_NUMPAD_INSERT:
+            vk = VK_INSERT;
+            break;
+
+        case WXK_DELETE:
+        case WXK_NUMPAD_DELETE:
+            vk = VK_DELETE;
             break;
             break;
+
+        default:
+            // 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;
+}
+
+// small helper for wxGetKeyState() and wxGetMouseState()
+static inline bool wxIsKeyDown(WXWORD vk)
+{
+    // SM_SWAPBUTTON is not available under CE, so don't swap buttons there
+#ifdef SM_SWAPBUTTON
+    if ( vk == VK_LBUTTON || vk == VK_RBUTTON )
+    {
+        if ( ::GetSystemMetrics(SM_SWAPBUTTON) )
+        {
+            if ( vk == VK_LBUTTON )
+                vk = VK_RBUTTON;
+            else // vk == VK_RBUTTON
+                vk = VK_LBUTTON;
         }
     }
         }
     }
-    return keySym;
+#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
+    return (GetAsyncKeyState(vk) & (1<<15)) != 0;
 }
 
 bool wxGetKeyState(wxKeyCode key)
 {
 }
 
 bool wxGetKeyState(wxKeyCode key)
 {
-    bool bVirtual;
-    int vkey = wxCharCodeWXToMSW(key, &bVirtual);
-    SHORT state;
+    // although this does work under Windows, it is not supported under other
+    // platforms so don't allow it, you must use wxGetMouseState() instead
+    wxASSERT_MSG( key != VK_LBUTTON &&
+                    key != VK_RBUTTON &&
+                        key != VK_MBUTTON,
+                    wxT("can't use wxGetKeyState() for mouse buttons") );
+
+    const WXWORD vk = wxCharCodeWXToMSW(key);
 
 
-    switch (key)
+    // if the requested key is a LED key, return true if the led is pressed
+    if ( key == WXK_NUMLOCK || key == WXK_CAPITAL || key == WXK_SCROLL )
     {
     {
-    case WXK_NUMLOCK:
-    case WXK_CAPITAL:
-    case WXK_SCROLL:
-        // get the toggle state of the special key
-        state = GetKeyState(vkey);
-        break;
+        // low order bit means LED is highlighted and high order one means the
+        // key is down; for compatibility with the other ports return true if
+        // either one is set
+        return GetKeyState(vk) != 0;
 
 
-    default:
-        // Get the current state of the physical key
-        state = GetAsyncKeyState(vkey);
-        break;
     }
     }
-    // if the most significant bit is set then the key is down
-    return ( state & 0x0001 ) != 0;
+    else // normal key
+    {
+        return wxIsKeyDown(vk);
+    }
+}
+
+
+wxMouseState wxGetMouseState()
+{
+    wxMouseState ms;
+    POINT pt;
+    GetCursorPos( &pt );
+
+    ms.SetX(pt.x);
+    ms.SetY(pt.y);
+    ms.SetLeftDown(wxIsKeyDown(VK_LBUTTON));
+    ms.SetMiddleDown(wxIsKeyDown(VK_MBUTTON));
+    ms.SetRightDown(wxIsKeyDown(VK_RBUTTON));
+#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;
 }
 
 }
 
+
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
     if ( hWnd != 0 )
     {
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
     if ( hWnd != 0 )
     {
-        return wxFindWinFromHandle((WXHWND) hWnd);
+        return wxFindWinFromHandle(hWnd);
     }
     return NULL;
 }
     }
     return NULL;
 }
@@ -5176,10 +6229,10 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
     // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set
     // by code in msw/radiobox.cpp), for all the others we just search up the
     // window hierarchy
     // For a radiobutton, we get the radiobox from GWL_USERDATA (which is set
     // by code in msw/radiobox.cpp), for all the others we just search up the
     // window hierarchy
-    wxWindow *win = (wxWindow *)NULL;
+    wxWindow *win = NULL;
     if ( hwnd )
     {
     if ( hwnd )
     {
-        win = wxFindWinFromHandle((WXHWND)hwnd);
+        win = wxFindWinFromHandle(hwnd);
         if ( !win )
         {
 #if wxUSE_RADIOBOX
         if ( !win )
         {
 #if wxUSE_RADIOBOX
@@ -5223,7 +6276,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;
@@ -5268,7 +6321,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
             if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
                 event.m_altDown = true;
 
             if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
                 event.m_altDown = true;
 
-            event.m_eventObject = NULL;
+            event.SetEventObject(NULL);
             event.m_keyCode = id;
             event.m_shiftDown = wxIsShiftDown();
             event.m_controlDown = wxIsCtrlDown();
             event.m_keyCode = id;
             event.m_shiftDown = wxIsShiftDown();
             event.m_controlDown = wxIsCtrlDown();
@@ -5302,437 +6355,476 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
 #endif // !__WXMICROWIN__
 
 #ifdef __WXDEBUG__
 #endif // !__WXMICROWIN__
 
 #ifdef __WXDEBUG__
-const char *wxGetMessageName(int message)
+const wxChar *wxGetMessageName(int message)
 {
     switch ( message )
     {
 {
     switch ( message )
     {
-        case 0x0000: return "WM_NULL";
-        case 0x0001: return "WM_CREATE";
-        case 0x0002: return "WM_DESTROY";
-        case 0x0003: return "WM_MOVE";
-        case 0x0005: return "WM_SIZE";
-        case 0x0006: return "WM_ACTIVATE";
-        case 0x0007: return "WM_SETFOCUS";
-        case 0x0008: return "WM_KILLFOCUS";
-        case 0x000A: return "WM_ENABLE";
-        case 0x000B: return "WM_SETREDRAW";
-        case 0x000C: return "WM_SETTEXT";
-        case 0x000D: return "WM_GETTEXT";
-        case 0x000E: return "WM_GETTEXTLENGTH";
-        case 0x000F: return "WM_PAINT";
-        case 0x0010: return "WM_CLOSE";
-        case 0x0011: return "WM_QUERYENDSESSION";
-        case 0x0012: return "WM_QUIT";
-        case 0x0013: return "WM_QUERYOPEN";
-        case 0x0014: return "WM_ERASEBKGND";
-        case 0x0015: return "WM_SYSCOLORCHANGE";
-        case 0x0016: return "WM_ENDSESSION";
-        case 0x0017: return "WM_SYSTEMERROR";
-        case 0x0018: return "WM_SHOWWINDOW";
-        case 0x0019: return "WM_CTLCOLOR";
-        case 0x001A: return "WM_WININICHANGE";
-        case 0x001B: return "WM_DEVMODECHANGE";
-        case 0x001C: return "WM_ACTIVATEAPP";
-        case 0x001D: return "WM_FONTCHANGE";
-        case 0x001E: return "WM_TIMECHANGE";
-        case 0x001F: return "WM_CANCELMODE";
-        case 0x0020: return "WM_SETCURSOR";
-        case 0x0021: return "WM_MOUSEACTIVATE";
-        case 0x0022: return "WM_CHILDACTIVATE";
-        case 0x0023: return "WM_QUEUESYNC";
-        case 0x0024: return "WM_GETMINMAXINFO";
-        case 0x0026: return "WM_PAINTICON";
-        case 0x0027: return "WM_ICONERASEBKGND";
-        case 0x0028: return "WM_NEXTDLGCTL";
-        case 0x002A: return "WM_SPOOLERSTATUS";
-        case 0x002B: return "WM_DRAWITEM";
-        case 0x002C: return "WM_MEASUREITEM";
-        case 0x002D: return "WM_DELETEITEM";
-        case 0x002E: return "WM_VKEYTOITEM";
-        case 0x002F: return "WM_CHARTOITEM";
-        case 0x0030: return "WM_SETFONT";
-        case 0x0031: return "WM_GETFONT";
-        case 0x0037: return "WM_QUERYDRAGICON";
-        case 0x0039: return "WM_COMPAREITEM";
-        case 0x0041: return "WM_COMPACTING";
-        case 0x0044: return "WM_COMMNOTIFY";
-        case 0x0046: return "WM_WINDOWPOSCHANGING";
-        case 0x0047: return "WM_WINDOWPOSCHANGED";
-        case 0x0048: return "WM_POWER";
-
-        case 0x004A: return "WM_COPYDATA";
-        case 0x004B: return "WM_CANCELJOURNAL";
-        case 0x004E: return "WM_NOTIFY";
-        case 0x0050: return "WM_INPUTLANGCHANGEREQUEST";
-        case 0x0051: return "WM_INPUTLANGCHANGE";
-        case 0x0052: return "WM_TCARD";
-        case 0x0053: return "WM_HELP";
-        case 0x0054: return "WM_USERCHANGED";
-        case 0x0055: return "WM_NOTIFYFORMAT";
-        case 0x007B: return "WM_CONTEXTMENU";
-        case 0x007C: return "WM_STYLECHANGING";
-        case 0x007D: return "WM_STYLECHANGED";
-        case 0x007E: return "WM_DISPLAYCHANGE";
-        case 0x007F: return "WM_GETICON";
-        case 0x0080: return "WM_SETICON";
-
-        case 0x0081: return "WM_NCCREATE";
-        case 0x0082: return "WM_NCDESTROY";
-        case 0x0083: return "WM_NCCALCSIZE";
-        case 0x0084: return "WM_NCHITTEST";
-        case 0x0085: return "WM_NCPAINT";
-        case 0x0086: return "WM_NCACTIVATE";
-        case 0x0087: return "WM_GETDLGCODE";
-        case 0x00A0: return "WM_NCMOUSEMOVE";
-        case 0x00A1: return "WM_NCLBUTTONDOWN";
-        case 0x00A2: return "WM_NCLBUTTONUP";
-        case 0x00A3: return "WM_NCLBUTTONDBLCLK";
-        case 0x00A4: return "WM_NCRBUTTONDOWN";
-        case 0x00A5: return "WM_NCRBUTTONUP";
-        case 0x00A6: return "WM_NCRBUTTONDBLCLK";
-        case 0x00A7: return "WM_NCMBUTTONDOWN";
-        case 0x00A8: return "WM_NCMBUTTONUP";
-        case 0x00A9: return "WM_NCMBUTTONDBLCLK";
-        case 0x0100: return "WM_KEYDOWN";
-        case 0x0101: return "WM_KEYUP";
-        case 0x0102: return "WM_CHAR";
-        case 0x0103: return "WM_DEADCHAR";
-        case 0x0104: return "WM_SYSKEYDOWN";
-        case 0x0105: return "WM_SYSKEYUP";
-        case 0x0106: return "WM_SYSCHAR";
-        case 0x0107: return "WM_SYSDEADCHAR";
-        case 0x0108: return "WM_KEYLAST";
-
-        case 0x010D: return "WM_IME_STARTCOMPOSITION";
-        case 0x010E: return "WM_IME_ENDCOMPOSITION";
-        case 0x010F: return "WM_IME_COMPOSITION";
-
-        case 0x0110: return "WM_INITDIALOG";
-        case 0x0111: return "WM_COMMAND";
-        case 0x0112: return "WM_SYSCOMMAND";
-        case 0x0113: return "WM_TIMER";
-        case 0x0114: return "WM_HSCROLL";
-        case 0x0115: return "WM_VSCROLL";
-        case 0x0116: return "WM_INITMENU";
-        case 0x0117: return "WM_INITMENUPOPUP";
-        case 0x011F: return "WM_MENUSELECT";
-        case 0x0120: return "WM_MENUCHAR";
-        case 0x0121: return "WM_ENTERIDLE";
-        case 0x0200: return "WM_MOUSEMOVE";
-        case 0x0201: return "WM_LBUTTONDOWN";
-        case 0x0202: return "WM_LBUTTONUP";
-        case 0x0203: return "WM_LBUTTONDBLCLK";
-        case 0x0204: return "WM_RBUTTONDOWN";
-        case 0x0205: return "WM_RBUTTONUP";
-        case 0x0206: return "WM_RBUTTONDBLCLK";
-        case 0x0207: return "WM_MBUTTONDOWN";
-        case 0x0208: return "WM_MBUTTONUP";
-        case 0x0209: return "WM_MBUTTONDBLCLK";
-        case 0x020A: return "WM_MOUSEWHEEL";
-        case 0x0210: return "WM_PARENTNOTIFY";
-        case 0x0211: return "WM_ENTERMENULOOP";
-        case 0x0212: return "WM_EXITMENULOOP";
-
-        case 0x0213: return "WM_NEXTMENU";
-        case 0x0214: return "WM_SIZING";
-        case 0x0215: return "WM_CAPTURECHANGED";
-        case 0x0216: return "WM_MOVING";
-        case 0x0218: return "WM_POWERBROADCAST";
-        case 0x0219: return "WM_DEVICECHANGE";
-
-        case 0x0220: return "WM_MDICREATE";
-        case 0x0221: return "WM_MDIDESTROY";
-        case 0x0222: return "WM_MDIACTIVATE";
-        case 0x0223: return "WM_MDIRESTORE";
-        case 0x0224: return "WM_MDINEXT";
-        case 0x0225: return "WM_MDIMAXIMIZE";
-        case 0x0226: return "WM_MDITILE";
-        case 0x0227: return "WM_MDICASCADE";
-        case 0x0228: return "WM_MDIICONARRANGE";
-        case 0x0229: return "WM_MDIGETACTIVE";
-        case 0x0230: return "WM_MDISETMENU";
-        case 0x0233: return "WM_DROPFILES";
-
-        case 0x0281: return "WM_IME_SETCONTEXT";
-        case 0x0282: return "WM_IME_NOTIFY";
-        case 0x0283: return "WM_IME_CONTROL";
-        case 0x0284: return "WM_IME_COMPOSITIONFULL";
-        case 0x0285: return "WM_IME_SELECT";
-        case 0x0286: return "WM_IME_CHAR";
-        case 0x0290: return "WM_IME_KEYDOWN";
-        case 0x0291: return "WM_IME_KEYUP";
-
-        case 0x0300: return "WM_CUT";
-        case 0x0301: return "WM_COPY";
-        case 0x0302: return "WM_PASTE";
-        case 0x0303: return "WM_CLEAR";
-        case 0x0304: return "WM_UNDO";
-        case 0x0305: return "WM_RENDERFORMAT";
-        case 0x0306: return "WM_RENDERALLFORMATS";
-        case 0x0307: return "WM_DESTROYCLIPBOARD";
-        case 0x0308: return "WM_DRAWCLIPBOARD";
-        case 0x0309: return "WM_PAINTCLIPBOARD";
-        case 0x030A: return "WM_VSCROLLCLIPBOARD";
-        case 0x030B: return "WM_SIZECLIPBOARD";
-        case 0x030C: return "WM_ASKCBFORMATNAME";
-        case 0x030D: return "WM_CHANGECBCHAIN";
-        case 0x030E: return "WM_HSCROLLCLIPBOARD";
-        case 0x030F: return "WM_QUERYNEWPALETTE";
-        case 0x0310: return "WM_PALETTEISCHANGING";
-        case 0x0311: return "WM_PALETTECHANGED";
-#if wxUSE_HOTKEY
-        case 0x0312: return "WM_HOTKEY";
-#endif
+        case 0x0000: return wxT("WM_NULL");
+        case 0x0001: return wxT("WM_CREATE");
+        case 0x0002: return wxT("WM_DESTROY");
+        case 0x0003: return wxT("WM_MOVE");
+        case 0x0005: return wxT("WM_SIZE");
+        case 0x0006: return wxT("WM_ACTIVATE");
+        case 0x0007: return wxT("WM_SETFOCUS");
+        case 0x0008: return wxT("WM_KILLFOCUS");
+        case 0x000A: return wxT("WM_ENABLE");
+        case 0x000B: return wxT("WM_SETREDRAW");
+        case 0x000C: return wxT("WM_SETTEXT");
+        case 0x000D: return wxT("WM_GETTEXT");
+        case 0x000E: return wxT("WM_GETTEXTLENGTH");
+        case 0x000F: return wxT("WM_PAINT");
+        case 0x0010: return wxT("WM_CLOSE");
+        case 0x0011: return wxT("WM_QUERYENDSESSION");
+        case 0x0012: return wxT("WM_QUIT");
+        case 0x0013: return wxT("WM_QUERYOPEN");
+        case 0x0014: return wxT("WM_ERASEBKGND");
+        case 0x0015: return wxT("WM_SYSCOLORCHANGE");
+        case 0x0016: return wxT("WM_ENDSESSION");
+        case 0x0017: return wxT("WM_SYSTEMERROR");
+        case 0x0018: return wxT("WM_SHOWWINDOW");
+        case 0x0019: return wxT("WM_CTLCOLOR");
+        case 0x001A: return wxT("WM_WININICHANGE");
+        case 0x001B: return wxT("WM_DEVMODECHANGE");
+        case 0x001C: return wxT("WM_ACTIVATEAPP");
+        case 0x001D: return wxT("WM_FONTCHANGE");
+        case 0x001E: return wxT("WM_TIMECHANGE");
+        case 0x001F: return wxT("WM_CANCELMODE");
+        case 0x0020: return wxT("WM_SETCURSOR");
+        case 0x0021: return wxT("WM_MOUSEACTIVATE");
+        case 0x0022: return wxT("WM_CHILDACTIVATE");
+        case 0x0023: return wxT("WM_QUEUESYNC");
+        case 0x0024: return wxT("WM_GETMINMAXINFO");
+        case 0x0026: return wxT("WM_PAINTICON");
+        case 0x0027: return wxT("WM_ICONERASEBKGND");
+        case 0x0028: return wxT("WM_NEXTDLGCTL");
+        case 0x002A: return wxT("WM_SPOOLERSTATUS");
+        case 0x002B: return wxT("WM_DRAWITEM");
+        case 0x002C: return wxT("WM_MEASUREITEM");
+        case 0x002D: return wxT("WM_DELETEITEM");
+        case 0x002E: return wxT("WM_VKEYTOITEM");
+        case 0x002F: return wxT("WM_CHARTOITEM");
+        case 0x0030: return wxT("WM_SETFONT");
+        case 0x0031: return wxT("WM_GETFONT");
+        case 0x0037: return wxT("WM_QUERYDRAGICON");
+        case 0x0039: return wxT("WM_COMPAREITEM");
+        case 0x0041: return wxT("WM_COMPACTING");
+        case 0x0044: return wxT("WM_COMMNOTIFY");
+        case 0x0046: return wxT("WM_WINDOWPOSCHANGING");
+        case 0x0047: return wxT("WM_WINDOWPOSCHANGED");
+        case 0x0048: return wxT("WM_POWER");
+
+        case 0x004A: return wxT("WM_COPYDATA");
+        case 0x004B: return wxT("WM_CANCELJOURNAL");
+        case 0x004E: return wxT("WM_NOTIFY");
+        case 0x0050: return wxT("WM_INPUTLANGCHANGEREQUEST");
+        case 0x0051: return wxT("WM_INPUTLANGCHANGE");
+        case 0x0052: return wxT("WM_TCARD");
+        case 0x0053: return wxT("WM_HELP");
+        case 0x0054: return wxT("WM_USERCHANGED");
+        case 0x0055: return wxT("WM_NOTIFYFORMAT");
+        case 0x007B: return wxT("WM_CONTEXTMENU");
+        case 0x007C: return wxT("WM_STYLECHANGING");
+        case 0x007D: return wxT("WM_STYLECHANGED");
+        case 0x007E: return wxT("WM_DISPLAYCHANGE");
+        case 0x007F: return wxT("WM_GETICON");
+        case 0x0080: return wxT("WM_SETICON");
+
+        case 0x0081: return wxT("WM_NCCREATE");
+        case 0x0082: return wxT("WM_NCDESTROY");
+        case 0x0083: return wxT("WM_NCCALCSIZE");
+        case 0x0084: return wxT("WM_NCHITTEST");
+        case 0x0085: return wxT("WM_NCPAINT");
+        case 0x0086: return wxT("WM_NCACTIVATE");
+        case 0x0087: return wxT("WM_GETDLGCODE");
+        case 0x00A0: return wxT("WM_NCMOUSEMOVE");
+        case 0x00A1: return wxT("WM_NCLBUTTONDOWN");
+        case 0x00A2: return wxT("WM_NCLBUTTONUP");
+        case 0x00A3: return wxT("WM_NCLBUTTONDBLCLK");
+        case 0x00A4: return wxT("WM_NCRBUTTONDOWN");
+        case 0x00A5: return wxT("WM_NCRBUTTONUP");
+        case 0x00A6: return wxT("WM_NCRBUTTONDBLCLK");
+        case 0x00A7: return wxT("WM_NCMBUTTONDOWN");
+        case 0x00A8: return wxT("WM_NCMBUTTONUP");
+        case 0x00A9: return wxT("WM_NCMBUTTONDBLCLK");
+
+        case 0x00B0: return wxT("EM_GETSEL");
+        case 0x00B1: return wxT("EM_SETSEL");
+        case 0x00B2: return wxT("EM_GETRECT");
+        case 0x00B3: return wxT("EM_SETRECT");
+        case 0x00B4: return wxT("EM_SETRECTNP");
+        case 0x00B5: return wxT("EM_SCROLL");
+        case 0x00B6: return wxT("EM_LINESCROLL");
+        case 0x00B7: return wxT("EM_SCROLLCARET");
+        case 0x00B8: return wxT("EM_GETMODIFY");
+        case 0x00B9: return wxT("EM_SETMODIFY");
+        case 0x00BA: return wxT("EM_GETLINECOUNT");
+        case 0x00BB: return wxT("EM_LINEINDEX");
+        case 0x00BC: return wxT("EM_SETHANDLE");
+        case 0x00BD: return wxT("EM_GETHANDLE");
+        case 0x00BE: return wxT("EM_GETTHUMB");
+        case 0x00C1: return wxT("EM_LINELENGTH");
+        case 0x00C2: return wxT("EM_REPLACESEL");
+        case 0x00C4: return wxT("EM_GETLINE");
+        case 0x00C5: return wxT("EM_LIMITTEXT/EM_SETLIMITTEXT"); /* ;win40 Name change */
+        case 0x00C6: return wxT("EM_CANUNDO");
+        case 0x00C7: return wxT("EM_UNDO");
+        case 0x00C8: return wxT("EM_FMTLINES");
+        case 0x00C9: return wxT("EM_LINEFROMCHAR");
+        case 0x00CB: return wxT("EM_SETTABSTOPS");
+        case 0x00CC: return wxT("EM_SETPASSWORDCHAR");
+        case 0x00CD: return wxT("EM_EMPTYUNDOBUFFER");
+        case 0x00CE: return wxT("EM_GETFIRSTVISIBLELINE");
+        case 0x00CF: return wxT("EM_SETREADONLY");
+        case 0x00D0: return wxT("EM_SETWORDBREAKPROC");
+        case 0x00D1: return wxT("EM_GETWORDBREAKPROC");
+        case 0x00D2: return wxT("EM_GETPASSWORDCHAR");
+        case 0x00D3: return wxT("EM_SETMARGINS");
+        case 0x00D4: return wxT("EM_GETMARGINS");
+        case 0x00D5: return wxT("EM_GETLIMITTEXT");
+        case 0x00D6: return wxT("EM_POSFROMCHAR");
+        case 0x00D7: return wxT("EM_CHARFROMPOS");
+        case 0x00D8: return wxT("EM_SETIMESTATUS");
+        case 0x00D9: return wxT("EM_GETIMESTATUS");
+
+        case 0x0100: return wxT("WM_KEYDOWN");
+        case 0x0101: return wxT("WM_KEYUP");
+        case 0x0102: return wxT("WM_CHAR");
+        case 0x0103: return wxT("WM_DEADCHAR");
+        case 0x0104: return wxT("WM_SYSKEYDOWN");
+        case 0x0105: return wxT("WM_SYSKEYUP");
+        case 0x0106: return wxT("WM_SYSCHAR");
+        case 0x0107: return wxT("WM_SYSDEADCHAR");
+        case 0x0108: return wxT("WM_KEYLAST");
+
+        case 0x010D: return wxT("WM_IME_STARTCOMPOSITION");
+        case 0x010E: return wxT("WM_IME_ENDCOMPOSITION");
+        case 0x010F: return wxT("WM_IME_COMPOSITION");
+
+        case 0x0110: return wxT("WM_INITDIALOG");
+        case 0x0111: return wxT("WM_COMMAND");
+        case 0x0112: return wxT("WM_SYSCOMMAND");
+        case 0x0113: return wxT("WM_TIMER");
+        case 0x0114: return wxT("WM_HSCROLL");
+        case 0x0115: return wxT("WM_VSCROLL");
+        case 0x0116: return wxT("WM_INITMENU");
+        case 0x0117: return wxT("WM_INITMENUPOPUP");
+        case 0x011F: return wxT("WM_MENUSELECT");
+        case 0x0120: return wxT("WM_MENUCHAR");
+        case 0x0121: return wxT("WM_ENTERIDLE");
+
+        case 0x0132: return wxT("WM_CTLCOLORMSGBOX");
+        case 0x0133: return wxT("WM_CTLCOLOREDIT");
+        case 0x0134: return wxT("WM_CTLCOLORLISTBOX");
+        case 0x0135: return wxT("WM_CTLCOLORBTN");
+        case 0x0136: return wxT("WM_CTLCOLORDLG");
+        case 0x0137: return wxT("WM_CTLCOLORSCROLLBAR");
+        case 0x0138: return wxT("WM_CTLCOLORSTATIC");
+        case 0x01E1: return wxT("MN_GETHMENU");
+
+        case 0x0200: return wxT("WM_MOUSEMOVE");
+        case 0x0201: return wxT("WM_LBUTTONDOWN");
+        case 0x0202: return wxT("WM_LBUTTONUP");
+        case 0x0203: return wxT("WM_LBUTTONDBLCLK");
+        case 0x0204: return wxT("WM_RBUTTONDOWN");
+        case 0x0205: return wxT("WM_RBUTTONUP");
+        case 0x0206: return wxT("WM_RBUTTONDBLCLK");
+        case 0x0207: return wxT("WM_MBUTTONDOWN");
+        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 0x0213: return wxT("WM_NEXTMENU");
+        case 0x0214: return wxT("WM_SIZING");
+        case 0x0215: return wxT("WM_CAPTURECHANGED");
+        case 0x0216: return wxT("WM_MOVING");
+        case 0x0218: return wxT("WM_POWERBROADCAST");
+        case 0x0219: return wxT("WM_DEVICECHANGE");
+
+        case 0x0220: return wxT("WM_MDICREATE");
+        case 0x0221: return wxT("WM_MDIDESTROY");
+        case 0x0222: return wxT("WM_MDIACTIVATE");
+        case 0x0223: return wxT("WM_MDIRESTORE");
+        case 0x0224: return wxT("WM_MDINEXT");
+        case 0x0225: return wxT("WM_MDIMAXIMIZE");
+        case 0x0226: return wxT("WM_MDITILE");
+        case 0x0227: return wxT("WM_MDICASCADE");
+        case 0x0228: return wxT("WM_MDIICONARRANGE");
+        case 0x0229: return wxT("WM_MDIGETACTIVE");
+        case 0x0230: return wxT("WM_MDISETMENU");
+        case 0x0233: return wxT("WM_DROPFILES");
+
+        case 0x0281: return wxT("WM_IME_SETCONTEXT");
+        case 0x0282: return wxT("WM_IME_NOTIFY");
+        case 0x0283: return wxT("WM_IME_CONTROL");
+        case 0x0284: return wxT("WM_IME_COMPOSITIONFULL");
+        case 0x0285: return wxT("WM_IME_SELECT");
+        case 0x0286: return wxT("WM_IME_CHAR");
+        case 0x0290: return wxT("WM_IME_KEYDOWN");
+        case 0x0291: return wxT("WM_IME_KEYUP");
+
+        case 0x02A0: return wxT("WM_NCMOUSEHOVER");
+        case 0x02A1: return wxT("WM_MOUSEHOVER");
+        case 0x02A2: return wxT("WM_NCMOUSELEAVE");
+        case 0x02A3: return wxT("WM_MOUSELEAVE");
+
+        case 0x0300: return wxT("WM_CUT");
+        case 0x0301: return wxT("WM_COPY");
+        case 0x0302: return wxT("WM_PASTE");
+        case 0x0303: return wxT("WM_CLEAR");
+        case 0x0304: return wxT("WM_UNDO");
+        case 0x0305: return wxT("WM_RENDERFORMAT");
+        case 0x0306: return wxT("WM_RENDERALLFORMATS");
+        case 0x0307: return wxT("WM_DESTROYCLIPBOARD");
+        case 0x0308: return wxT("WM_DRAWCLIPBOARD");
+        case 0x0309: return wxT("WM_PAINTCLIPBOARD");
+        case 0x030A: return wxT("WM_VSCROLLCLIPBOARD");
+        case 0x030B: return wxT("WM_SIZECLIPBOARD");
+        case 0x030C: return wxT("WM_ASKCBFORMATNAME");
+        case 0x030D: return wxT("WM_CHANGECBCHAIN");
+        case 0x030E: return wxT("WM_HSCROLLCLIPBOARD");
+        case 0x030F: return wxT("WM_QUERYNEWPALETTE");
+        case 0x0310: return wxT("WM_PALETTEISCHANGING");
+        case 0x0311: return wxT("WM_PALETTECHANGED");
+        case 0x0312: return wxT("WM_HOTKEY");
+
+        case 0x0317: return wxT("WM_PRINT");
+        case 0x0318: return wxT("WM_PRINTCLIENT");
 
         // common controls messages - although they're not strictly speaking
         // standard, it's nice to decode them nevertheless
 
         // listview
 
         // common controls messages - although they're not strictly speaking
         // standard, it's nice to decode them nevertheless
 
         // listview
-        case 0x1000 + 0: return "LVM_GETBKCOLOR";
-        case 0x1000 + 1: return "LVM_SETBKCOLOR";
-        case 0x1000 + 2: return "LVM_GETIMAGELIST";
-        case 0x1000 + 3: return "LVM_SETIMAGELIST";
-        case 0x1000 + 4: return "LVM_GETITEMCOUNT";
-        case 0x1000 + 5: return "LVM_GETITEMA";
-        case 0x1000 + 75: return "LVM_GETITEMW";
-        case 0x1000 + 6: return "LVM_SETITEMA";
-        case 0x1000 + 76: return "LVM_SETITEMW";
-        case 0x1000 + 7: return "LVM_INSERTITEMA";
-        case 0x1000 + 77: return "LVM_INSERTITEMW";
-        case 0x1000 + 8: return "LVM_DELETEITEM";
-        case 0x1000 + 9: return "LVM_DELETEALLITEMS";
-        case 0x1000 + 10: return "LVM_GETCALLBACKMASK";
-        case 0x1000 + 11: return "LVM_SETCALLBACKMASK";
-        case 0x1000 + 12: return "LVM_GETNEXTITEM";
-        case 0x1000 + 13: return "LVM_FINDITEMA";
-        case 0x1000 + 83: return "LVM_FINDITEMW";
-        case 0x1000 + 14: return "LVM_GETITEMRECT";
-        case 0x1000 + 15: return "LVM_SETITEMPOSITION";
-        case 0x1000 + 16: return "LVM_GETITEMPOSITION";
-        case 0x1000 + 17: return "LVM_GETSTRINGWIDTHA";
-        case 0x1000 + 87: return "LVM_GETSTRINGWIDTHW";
-        case 0x1000 + 18: return "LVM_HITTEST";
-        case 0x1000 + 19: return "LVM_ENSUREVISIBLE";
-        case 0x1000 + 20: return "LVM_SCROLL";
-        case 0x1000 + 21: return "LVM_REDRAWITEMS";
-        case 0x1000 + 22: return "LVM_ARRANGE";
-        case 0x1000 + 23: return "LVM_EDITLABELA";
-        case 0x1000 + 118: return "LVM_EDITLABELW";
-        case 0x1000 + 24: return "LVM_GETEDITCONTROL";
-        case 0x1000 + 25: return "LVM_GETCOLUMNA";
-        case 0x1000 + 95: return "LVM_GETCOLUMNW";
-        case 0x1000 + 26: return "LVM_SETCOLUMNA";
-        case 0x1000 + 96: return "LVM_SETCOLUMNW";
-        case 0x1000 + 27: return "LVM_INSERTCOLUMNA";
-        case 0x1000 + 97: return "LVM_INSERTCOLUMNW";
-        case 0x1000 + 28: return "LVM_DELETECOLUMN";
-        case 0x1000 + 29: return "LVM_GETCOLUMNWIDTH";
-        case 0x1000 + 30: return "LVM_SETCOLUMNWIDTH";
-        case 0x1000 + 31: return "LVM_GETHEADER";
-        case 0x1000 + 33: return "LVM_CREATEDRAGIMAGE";
-        case 0x1000 + 34: return "LVM_GETVIEWRECT";
-        case 0x1000 + 35: return "LVM_GETTEXTCOLOR";
-        case 0x1000 + 36: return "LVM_SETTEXTCOLOR";
-        case 0x1000 + 37: return "LVM_GETTEXTBKCOLOR";
-        case 0x1000 + 38: return "LVM_SETTEXTBKCOLOR";
-        case 0x1000 + 39: return "LVM_GETTOPINDEX";
-        case 0x1000 + 40: return "LVM_GETCOUNTPERPAGE";
-        case 0x1000 + 41: return "LVM_GETORIGIN";
-        case 0x1000 + 42: return "LVM_UPDATE";
-        case 0x1000 + 43: return "LVM_SETITEMSTATE";
-        case 0x1000 + 44: return "LVM_GETITEMSTATE";
-        case 0x1000 + 45: return "LVM_GETITEMTEXTA";
-        case 0x1000 + 115: return "LVM_GETITEMTEXTW";
-        case 0x1000 + 46: return "LVM_SETITEMTEXTA";
-        case 0x1000 + 116: return "LVM_SETITEMTEXTW";
-        case 0x1000 + 47: return "LVM_SETITEMCOUNT";
-        case 0x1000 + 48: return "LVM_SORTITEMS";
-        case 0x1000 + 49: return "LVM_SETITEMPOSITION32";
-        case 0x1000 + 50: return "LVM_GETSELECTEDCOUNT";
-        case 0x1000 + 51: return "LVM_GETITEMSPACING";
-        case 0x1000 + 52: return "LVM_GETISEARCHSTRINGA";
-        case 0x1000 + 117: return "LVM_GETISEARCHSTRINGW";
-        case 0x1000 + 53: return "LVM_SETICONSPACING";
-        case 0x1000 + 54: return "LVM_SETEXTENDEDLISTVIEWSTYLE";
-        case 0x1000 + 55: return "LVM_GETEXTENDEDLISTVIEWSTYLE";
-        case 0x1000 + 56: return "LVM_GETSUBITEMRECT";
-        case 0x1000 + 57: return "LVM_SUBITEMHITTEST";
-        case 0x1000 + 58: return "LVM_SETCOLUMNORDERARRAY";
-        case 0x1000 + 59: return "LVM_GETCOLUMNORDERARRAY";
-        case 0x1000 + 60: return "LVM_SETHOTITEM";
-        case 0x1000 + 61: return "LVM_GETHOTITEM";
-        case 0x1000 + 62: return "LVM_SETHOTCURSOR";
-        case 0x1000 + 63: return "LVM_GETHOTCURSOR";
-        case 0x1000 + 64: return "LVM_APPROXIMATEVIEWRECT";
-        case 0x1000 + 65: return "LVM_SETWORKAREA";
+        case 0x1000 + 0: return wxT("LVM_GETBKCOLOR");
+        case 0x1000 + 1: return wxT("LVM_SETBKCOLOR");
+        case 0x1000 + 2: return wxT("LVM_GETIMAGELIST");
+        case 0x1000 + 3: return wxT("LVM_SETIMAGELIST");
+        case 0x1000 + 4: return wxT("LVM_GETITEMCOUNT");
+        case 0x1000 + 5: return wxT("LVM_GETITEMA");
+        case 0x1000 + 75: return wxT("LVM_GETITEMW");
+        case 0x1000 + 6: return wxT("LVM_SETITEMA");
+        case 0x1000 + 76: return wxT("LVM_SETITEMW");
+        case 0x1000 + 7: return wxT("LVM_INSERTITEMA");
+        case 0x1000 + 77: return wxT("LVM_INSERTITEMW");
+        case 0x1000 + 8: return wxT("LVM_DELETEITEM");
+        case 0x1000 + 9: return wxT("LVM_DELETEALLITEMS");
+        case 0x1000 + 10: return wxT("LVM_GETCALLBACKMASK");
+        case 0x1000 + 11: return wxT("LVM_SETCALLBACKMASK");
+        case 0x1000 + 12: return wxT("LVM_GETNEXTITEM");
+        case 0x1000 + 13: return wxT("LVM_FINDITEMA");
+        case 0x1000 + 83: return wxT("LVM_FINDITEMW");
+        case 0x1000 + 14: return wxT("LVM_GETITEMRECT");
+        case 0x1000 + 15: return wxT("LVM_SETITEMPOSITION");
+        case 0x1000 + 16: return wxT("LVM_GETITEMPOSITION");
+        case 0x1000 + 17: return wxT("LVM_GETSTRINGWIDTHA");
+        case 0x1000 + 87: return wxT("LVM_GETSTRINGWIDTHW");
+        case 0x1000 + 18: return wxT("LVM_HITTEST");
+        case 0x1000 + 19: return wxT("LVM_ENSUREVISIBLE");
+        case 0x1000 + 20: return wxT("LVM_SCROLL");
+        case 0x1000 + 21: return wxT("LVM_REDRAWITEMS");
+        case 0x1000 + 22: return wxT("LVM_ARRANGE");
+        case 0x1000 + 23: return wxT("LVM_EDITLABELA");
+        case 0x1000 + 118: return wxT("LVM_EDITLABELW");
+        case 0x1000 + 24: return wxT("LVM_GETEDITCONTROL");
+        case 0x1000 + 25: return wxT("LVM_GETCOLUMNA");
+        case 0x1000 + 95: return wxT("LVM_GETCOLUMNW");
+        case 0x1000 + 26: return wxT("LVM_SETCOLUMNA");
+        case 0x1000 + 96: return wxT("LVM_SETCOLUMNW");
+        case 0x1000 + 27: return wxT("LVM_INSERTCOLUMNA");
+        case 0x1000 + 97: return wxT("LVM_INSERTCOLUMNW");
+        case 0x1000 + 28: return wxT("LVM_DELETECOLUMN");
+        case 0x1000 + 29: return wxT("LVM_GETCOLUMNWIDTH");
+        case 0x1000 + 30: return wxT("LVM_SETCOLUMNWIDTH");
+        case 0x1000 + 31: return wxT("LVM_GETHEADER");
+        case 0x1000 + 33: return wxT("LVM_CREATEDRAGIMAGE");
+        case 0x1000 + 34: return wxT("LVM_GETVIEWRECT");
+        case 0x1000 + 35: return wxT("LVM_GETTEXTCOLOR");
+        case 0x1000 + 36: return wxT("LVM_SETTEXTCOLOR");
+        case 0x1000 + 37: return wxT("LVM_GETTEXTBKCOLOR");
+        case 0x1000 + 38: return wxT("LVM_SETTEXTBKCOLOR");
+        case 0x1000 + 39: return wxT("LVM_GETTOPINDEX");
+        case 0x1000 + 40: return wxT("LVM_GETCOUNTPERPAGE");
+        case 0x1000 + 41: return wxT("LVM_GETORIGIN");
+        case 0x1000 + 42: return wxT("LVM_UPDATE");
+        case 0x1000 + 43: return wxT("LVM_SETITEMSTATE");
+        case 0x1000 + 44: return wxT("LVM_GETITEMSTATE");
+        case 0x1000 + 45: return wxT("LVM_GETITEMTEXTA");
+        case 0x1000 + 115: return wxT("LVM_GETITEMTEXTW");
+        case 0x1000 + 46: return wxT("LVM_SETITEMTEXTA");
+        case 0x1000 + 116: return wxT("LVM_SETITEMTEXTW");
+        case 0x1000 + 47: return wxT("LVM_SETITEMCOUNT");
+        case 0x1000 + 48: return wxT("LVM_SORTITEMS");
+        case 0x1000 + 49: return wxT("LVM_SETITEMPOSITION32");
+        case 0x1000 + 50: return wxT("LVM_GETSELECTEDCOUNT");
+        case 0x1000 + 51: return wxT("LVM_GETITEMSPACING");
+        case 0x1000 + 52: return wxT("LVM_GETISEARCHSTRINGA");
+        case 0x1000 + 117: return wxT("LVM_GETISEARCHSTRINGW");
+        case 0x1000 + 53: return wxT("LVM_SETICONSPACING");
+        case 0x1000 + 54: return wxT("LVM_SETEXTENDEDLISTVIEWSTYLE");
+        case 0x1000 + 55: return wxT("LVM_GETEXTENDEDLISTVIEWSTYLE");
+        case 0x1000 + 56: return wxT("LVM_GETSUBITEMRECT");
+        case 0x1000 + 57: return wxT("LVM_SUBITEMHITTEST");
+        case 0x1000 + 58: return wxT("LVM_SETCOLUMNORDERARRAY");
+        case 0x1000 + 59: return wxT("LVM_GETCOLUMNORDERARRAY");
+        case 0x1000 + 60: return wxT("LVM_SETHOTITEM");
+        case 0x1000 + 61: return wxT("LVM_GETHOTITEM");
+        case 0x1000 + 62: return wxT("LVM_SETHOTCURSOR");
+        case 0x1000 + 63: return wxT("LVM_GETHOTCURSOR");
+        case 0x1000 + 64: return wxT("LVM_APPROXIMATEVIEWRECT");
+        case 0x1000 + 65: return wxT("LVM_SETWORKAREA");
 
         // tree view
 
         // tree view
-        case 0x1100 + 0: return "TVM_INSERTITEMA";
-        case 0x1100 + 50: return "TVM_INSERTITEMW";
-        case 0x1100 + 1: return "TVM_DELETEITEM";
-        case 0x1100 + 2: return "TVM_EXPAND";
-        case 0x1100 + 4: return "TVM_GETITEMRECT";
-        case 0x1100 + 5: return "TVM_GETCOUNT";
-        case 0x1100 + 6: return "TVM_GETINDENT";
-        case 0x1100 + 7: return "TVM_SETINDENT";
-        case 0x1100 + 8: return "TVM_GETIMAGELIST";
-        case 0x1100 + 9: return "TVM_SETIMAGELIST";
-        case 0x1100 + 10: return "TVM_GETNEXTITEM";
-        case 0x1100 + 11: return "TVM_SELECTITEM";
-        case 0x1100 + 12: return "TVM_GETITEMA";
-        case 0x1100 + 62: return "TVM_GETITEMW";
-        case 0x1100 + 13: return "TVM_SETITEMA";
-        case 0x1100 + 63: return "TVM_SETITEMW";
-        case 0x1100 + 14: return "TVM_EDITLABELA";
-        case 0x1100 + 65: return "TVM_EDITLABELW";
-        case 0x1100 + 15: return "TVM_GETEDITCONTROL";
-        case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
-        case 0x1100 + 17: return "TVM_HITTEST";
-        case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
-        case 0x1100 + 19: return "TVM_SORTCHILDREN";
-        case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
-        case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
-        case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
-        case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
-        case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
-        case 0x1100 + 24: return "TVM_SETTOOLTIPS";
-        case 0x1100 + 25: return "TVM_GETTOOLTIPS";
+        case 0x1100 + 0: return wxT("TVM_INSERTITEMA");
+        case 0x1100 + 50: return wxT("TVM_INSERTITEMW");
+        case 0x1100 + 1: return wxT("TVM_DELETEITEM");
+        case 0x1100 + 2: return wxT("TVM_EXPAND");
+        case 0x1100 + 4: return wxT("TVM_GETITEMRECT");
+        case 0x1100 + 5: return wxT("TVM_GETCOUNT");
+        case 0x1100 + 6: return wxT("TVM_GETINDENT");
+        case 0x1100 + 7: return wxT("TVM_SETINDENT");
+        case 0x1100 + 8: return wxT("TVM_GETIMAGELIST");
+        case 0x1100 + 9: return wxT("TVM_SETIMAGELIST");
+        case 0x1100 + 10: return wxT("TVM_GETNEXTITEM");
+        case 0x1100 + 11: return wxT("TVM_SELECTITEM");
+        case 0x1100 + 12: return wxT("TVM_GETITEMA");
+        case 0x1100 + 62: return wxT("TVM_GETITEMW");
+        case 0x1100 + 13: return wxT("TVM_SETITEMA");
+        case 0x1100 + 63: return wxT("TVM_SETITEMW");
+        case 0x1100 + 14: return wxT("TVM_EDITLABELA");
+        case 0x1100 + 65: return wxT("TVM_EDITLABELW");
+        case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL");
+        case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT");
+        case 0x1100 + 17: return wxT("TVM_HITTEST");
+        case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE");
+        case 0x1100 + 19: return wxT("TVM_SORTCHILDREN");
+        case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE");
+        case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB");
+        case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW");
+        case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA");
+        case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW");
+        case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS");
+        case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS");
 
         // header
 
         // header
-        case 0x1200 + 0: return "HDM_GETITEMCOUNT";
-        case 0x1200 + 1: return "HDM_INSERTITEMA";
-        case 0x1200 + 10: return "HDM_INSERTITEMW";
-        case 0x1200 + 2: return "HDM_DELETEITEM";
-        case 0x1200 + 3: return "HDM_GETITEMA";
-        case 0x1200 + 11: return "HDM_GETITEMW";
-        case 0x1200 + 4: return "HDM_SETITEMA";
-        case 0x1200 + 12: return "HDM_SETITEMW";
-        case 0x1200 + 5: return "HDM_LAYOUT";
-        case 0x1200 + 6: return "HDM_HITTEST";
-        case 0x1200 + 7: return "HDM_GETITEMRECT";
-        case 0x1200 + 8: return "HDM_SETIMAGELIST";
-        case 0x1200 + 9: return "HDM_GETIMAGELIST";
-        case 0x1200 + 15: return "HDM_ORDERTOINDEX";
-        case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
-        case 0x1200 + 17: return "HDM_GETORDERARRAY";
-        case 0x1200 + 18: return "HDM_SETORDERARRAY";
-        case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
+        case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT");
+        case 0x1200 + 1: return wxT("HDM_INSERTITEMA");
+        case 0x1200 + 10: return wxT("HDM_INSERTITEMW");
+        case 0x1200 + 2: return wxT("HDM_DELETEITEM");
+        case 0x1200 + 3: return wxT("HDM_GETITEMA");
+        case 0x1200 + 11: return wxT("HDM_GETITEMW");
+        case 0x1200 + 4: return wxT("HDM_SETITEMA");
+        case 0x1200 + 12: return wxT("HDM_SETITEMW");
+        case 0x1200 + 5: return wxT("HDM_LAYOUT");
+        case 0x1200 + 6: return wxT("HDM_HITTEST");
+        case 0x1200 + 7: return wxT("HDM_GETITEMRECT");
+        case 0x1200 + 8: return wxT("HDM_SETIMAGELIST");
+        case 0x1200 + 9: return wxT("HDM_GETIMAGELIST");
+        case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX");
+        case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE");
+        case 0x1200 + 17: return wxT("HDM_GETORDERARRAY");
+        case 0x1200 + 18: return wxT("HDM_SETORDERARRAY");
+        case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER");
 
         // tab control
 
         // tab control
-        case 0x1300 + 2: return "TCM_GETIMAGELIST";
-        case 0x1300 + 3: return "TCM_SETIMAGELIST";
-        case 0x1300 + 4: return "TCM_GETITEMCOUNT";
-        case 0x1300 + 5: return "TCM_GETITEMA";
-        case 0x1300 + 60: return "TCM_GETITEMW";
-        case 0x1300 + 6: return "TCM_SETITEMA";
-        case 0x1300 + 61: return "TCM_SETITEMW";
-        case 0x1300 + 7: return "TCM_INSERTITEMA";
-        case 0x1300 + 62: return "TCM_INSERTITEMW";
-        case 0x1300 + 8: return "TCM_DELETEITEM";
-        case 0x1300 + 9: return "TCM_DELETEALLITEMS";
-        case 0x1300 + 10: return "TCM_GETITEMRECT";
-        case 0x1300 + 11: return "TCM_GETCURSEL";
-        case 0x1300 + 12: return "TCM_SETCURSEL";
-        case 0x1300 + 13: return "TCM_HITTEST";
-        case 0x1300 + 14: return "TCM_SETITEMEXTRA";
-        case 0x1300 + 40: return "TCM_ADJUSTRECT";
-        case 0x1300 + 41: return "TCM_SETITEMSIZE";
-        case 0x1300 + 42: return "TCM_REMOVEIMAGE";
-        case 0x1300 + 43: return "TCM_SETPADDING";
-        case 0x1300 + 44: return "TCM_GETROWCOUNT";
-        case 0x1300 + 45: return "TCM_GETTOOLTIPS";
-        case 0x1300 + 46: return "TCM_SETTOOLTIPS";
-        case 0x1300 + 47: return "TCM_GETCURFOCUS";
-        case 0x1300 + 48: return "TCM_SETCURFOCUS";
-        case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
-        case 0x1300 + 50: return "TCM_DESELECTALL";
+        case 0x1300 + 2: return wxT("TCM_GETIMAGELIST");
+        case 0x1300 + 3: return wxT("TCM_SETIMAGELIST");
+        case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT");
+        case 0x1300 + 5: return wxT("TCM_GETITEMA");
+        case 0x1300 + 60: return wxT("TCM_GETITEMW");
+        case 0x1300 + 6: return wxT("TCM_SETITEMA");
+        case 0x1300 + 61: return wxT("TCM_SETITEMW");
+        case 0x1300 + 7: return wxT("TCM_INSERTITEMA");
+        case 0x1300 + 62: return wxT("TCM_INSERTITEMW");
+        case 0x1300 + 8: return wxT("TCM_DELETEITEM");
+        case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS");
+        case 0x1300 + 10: return wxT("TCM_GETITEMRECT");
+        case 0x1300 + 11: return wxT("TCM_GETCURSEL");
+        case 0x1300 + 12: return wxT("TCM_SETCURSEL");
+        case 0x1300 + 13: return wxT("TCM_HITTEST");
+        case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA");
+        case 0x1300 + 40: return wxT("TCM_ADJUSTRECT");
+        case 0x1300 + 41: return wxT("TCM_SETITEMSIZE");
+        case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE");
+        case 0x1300 + 43: return wxT("TCM_SETPADDING");
+        case 0x1300 + 44: return wxT("TCM_GETROWCOUNT");
+        case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS");
+        case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS");
+        case 0x1300 + 47: return wxT("TCM_GETCURFOCUS");
+        case 0x1300 + 48: return wxT("TCM_SETCURFOCUS");
+        case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH");
+        case 0x1300 + 50: return wxT("TCM_DESELECTALL");
 
         // toolbar
 
         // toolbar
-        case WM_USER+1: return "TB_ENABLEBUTTON";
-        case WM_USER+2: return "TB_CHECKBUTTON";
-        case WM_USER+3: return "TB_PRESSBUTTON";
-        case WM_USER+4: return "TB_HIDEBUTTON";
-        case WM_USER+5: return "TB_INDETERMINATE";
-        case WM_USER+9: return "TB_ISBUTTONENABLED";
-        case WM_USER+10: return "TB_ISBUTTONCHECKED";
-        case WM_USER+11: return "TB_ISBUTTONPRESSED";
-        case WM_USER+12: return "TB_ISBUTTONHIDDEN";
-        case WM_USER+13: return "TB_ISBUTTONINDETERMINATE";
-        case WM_USER+17: return "TB_SETSTATE";
-        case WM_USER+18: return "TB_GETSTATE";
-        case WM_USER+19: return "TB_ADDBITMAP";
-        case WM_USER+20: return "TB_ADDBUTTONS";
-        case WM_USER+21: return "TB_INSERTBUTTON";
-        case WM_USER+22: return "TB_DELETEBUTTON";
-        case WM_USER+23: return "TB_GETBUTTON";
-        case WM_USER+24: return "TB_BUTTONCOUNT";
-        case WM_USER+25: return "TB_COMMANDTOINDEX";
-        case WM_USER+26: return "TB_SAVERESTOREA";
-        case WM_USER+76: return "TB_SAVERESTOREW";
-        case WM_USER+27: return "TB_CUSTOMIZE";
-        case WM_USER+28: return "TB_ADDSTRINGA";
-        case WM_USER+77: return "TB_ADDSTRINGW";
-        case WM_USER+29: return "TB_GETITEMRECT";
-        case WM_USER+30: return "TB_BUTTONSTRUCTSIZE";
-        case WM_USER+31: return "TB_SETBUTTONSIZE";
-        case WM_USER+32: return "TB_SETBITMAPSIZE";
-        case WM_USER+33: return "TB_AUTOSIZE";
-        case WM_USER+35: return "TB_GETTOOLTIPS";
-        case WM_USER+36: return "TB_SETTOOLTIPS";
-        case WM_USER+37: return "TB_SETPARENT";
-        case WM_USER+39: return "TB_SETROWS";
-        case WM_USER+40: return "TB_GETROWS";
-        case WM_USER+42: return "TB_SETCMDID";
-        case WM_USER+43: return "TB_CHANGEBITMAP";
-        case WM_USER+44: return "TB_GETBITMAP";
-        case WM_USER+45: return "TB_GETBUTTONTEXTA";
-        case WM_USER+75: return "TB_GETBUTTONTEXTW";
-        case WM_USER+46: return "TB_REPLACEBITMAP";
-        case WM_USER+47: return "TB_SETINDENT";
-        case WM_USER+48: return "TB_SETIMAGELIST";
-        case WM_USER+49: return "TB_GETIMAGELIST";
-        case WM_USER+50: return "TB_LOADIMAGES";
-        case WM_USER+51: return "TB_GETRECT";
-        case WM_USER+52: return "TB_SETHOTIMAGELIST";
-        case WM_USER+53: return "TB_GETHOTIMAGELIST";
-        case WM_USER+54: return "TB_SETDISABLEDIMAGELIST";
-        case WM_USER+55: return "TB_GETDISABLEDIMAGELIST";
-        case WM_USER+56: return "TB_SETSTYLE";
-        case WM_USER+57: return "TB_GETSTYLE";
-        case WM_USER+58: return "TB_GETBUTTONSIZE";
-        case WM_USER+59: return "TB_SETBUTTONWIDTH";
-        case WM_USER+60: return "TB_SETMAXTEXTROWS";
-        case WM_USER+61: return "TB_GETTEXTROWS";
-        case WM_USER+41: return "TB_GETBITMAPFLAGS";
+        case WM_USER+1: return wxT("TB_ENABLEBUTTON");
+        case WM_USER+2: return wxT("TB_CHECKBUTTON");
+        case WM_USER+3: return wxT("TB_PRESSBUTTON");
+        case WM_USER+4: return wxT("TB_HIDEBUTTON");
+        case WM_USER+5: return wxT("TB_INDETERMINATE");
+        case WM_USER+9: return wxT("TB_ISBUTTONENABLED");
+        case WM_USER+10: return wxT("TB_ISBUTTONCHECKED");
+        case WM_USER+11: return wxT("TB_ISBUTTONPRESSED");
+        case WM_USER+12: return wxT("TB_ISBUTTONHIDDEN");
+        case WM_USER+13: return wxT("TB_ISBUTTONINDETERMINATE");
+        case WM_USER+17: return wxT("TB_SETSTATE");
+        case WM_USER+18: return wxT("TB_GETSTATE");
+        case WM_USER+19: return wxT("TB_ADDBITMAP");
+        case WM_USER+20: return wxT("TB_ADDBUTTONS");
+        case WM_USER+21: return wxT("TB_INSERTBUTTON");
+        case WM_USER+22: return wxT("TB_DELETEBUTTON");
+        case WM_USER+23: return wxT("TB_GETBUTTON");
+        case WM_USER+24: return wxT("TB_BUTTONCOUNT");
+        case WM_USER+25: return wxT("TB_COMMANDTOINDEX");
+        case WM_USER+26: return wxT("TB_SAVERESTOREA");
+        case WM_USER+76: return wxT("TB_SAVERESTOREW");
+        case WM_USER+27: return wxT("TB_CUSTOMIZE");
+        case WM_USER+28: return wxT("TB_ADDSTRINGA");
+        case WM_USER+77: return wxT("TB_ADDSTRINGW");
+        case WM_USER+29: return wxT("TB_GETITEMRECT");
+        case WM_USER+30: return wxT("TB_BUTTONSTRUCTSIZE");
+        case WM_USER+31: return wxT("TB_SETBUTTONSIZE");
+        case WM_USER+32: return wxT("TB_SETBITMAPSIZE");
+        case WM_USER+33: return wxT("TB_AUTOSIZE");
+        case WM_USER+35: return wxT("TB_GETTOOLTIPS");
+        case WM_USER+36: return wxT("TB_SETTOOLTIPS");
+        case WM_USER+37: return wxT("TB_SETPARENT");
+        case WM_USER+39: return wxT("TB_SETROWS");
+        case WM_USER+40: return wxT("TB_GETROWS");
+        case WM_USER+42: return wxT("TB_SETCMDID");
+        case WM_USER+43: return wxT("TB_CHANGEBITMAP");
+        case WM_USER+44: return wxT("TB_GETBITMAP");
+        case WM_USER+45: return wxT("TB_GETBUTTONTEXTA");
+        case WM_USER+75: return wxT("TB_GETBUTTONTEXTW");
+        case WM_USER+46: return wxT("TB_REPLACEBITMAP");
+        case WM_USER+47: return wxT("TB_SETINDENT");
+        case WM_USER+48: return wxT("TB_SETIMAGELIST");
+        case WM_USER+49: return wxT("TB_GETIMAGELIST");
+        case WM_USER+50: return wxT("TB_LOADIMAGES");
+        case WM_USER+51: return wxT("TB_GETRECT");
+        case WM_USER+52: return wxT("TB_SETHOTIMAGELIST");
+        case WM_USER+53: return wxT("TB_GETHOTIMAGELIST");
+        case WM_USER+54: return wxT("TB_SETDISABLEDIMAGELIST");
+        case WM_USER+55: return wxT("TB_GETDISABLEDIMAGELIST");
+        case WM_USER+56: return wxT("TB_SETSTYLE");
+        case WM_USER+57: return wxT("TB_GETSTYLE");
+        case WM_USER+58: return wxT("TB_GETBUTTONSIZE");
+        case WM_USER+59: return wxT("TB_SETBUTTONWIDTH");
+        case WM_USER+60: return wxT("TB_SETMAXTEXTROWS");
+        case WM_USER+61: return wxT("TB_GETTEXTROWS");
+        case WM_USER+41: return wxT("TB_GETBITMAPFLAGS");
 
         default:
 
         default:
-            static char s_szBuf[128];
-            sprintf(s_szBuf, "<unknown message = %d>", message);
-            return s_szBuf;
+            static wxString s_szBuf;
+            s_szBuf.Printf(wxT("<unknown message = %d>"), message);
+            return s_szBuf.c_str();
     }
 }
 #endif //__WXDEBUG__
 
     }
 }
 #endif //__WXDEBUG__
 
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
-                                     int *x, int *y, WPARAM *flags)
-{
-    // construct the key mask
-    WPARAM& fwKeys = *flags;
-
-    fwKeys = MK_RBUTTON;
-    if ( wxIsCtrlDown() )
-        fwKeys |= MK_CONTROL;
-    if ( wxIsShiftDown() )
-        fwKeys |= MK_SHIFT;
-
-    // simulate right mouse button click
-    DWORD dwPos = ::GetMessagePos();
-    *x = GET_X_LPARAM(dwPos);
-    *y = GET_Y_LPARAM(dwPos);
-
-    win->ScreenToClient(x, y);
-}
-
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win)
 {
     // prepare the DC
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win)
 {
     // prepare the DC
@@ -5778,31 +6870,46 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
     POINT pt2;
     pt2.x = pt.x;
     pt2.y = pt.y;
     POINT pt2;
     pt2.x = pt.x;
     pt2.y = pt.y;
-    HWND hWndHit = ::WindowFromPoint(pt2);
 
 
-    wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ;
-    HWND hWnd = hWndHit;
+    HWND hWnd = ::WindowFromPoint(pt2);
 
 
-    // Try to find a window with a wxWindow associated with it
-    while (!win && (hWnd != 0))
-    {
-        hWnd = ::GetParent(hWnd);
-        win = wxFindWinFromHandle((WXHWND) hWnd) ;
-    }
-    return win;
+    return wxGetWindowFromHWND((WXHWND)hWnd);
 }
 
 // Get the current mouse position.
 wxPoint wxGetMousePosition()
 {
     POINT pt;
 }
 
 // Get the current mouse position.
 wxPoint wxGetMousePosition()
 {
     POINT pt;
+#ifdef __WXWINCE__
+    GetCursorPosWinCE(&pt);
+#else
     GetCursorPos( & pt );
     GetCursorPos( & pt );
+#endif
 
     return wxPoint(pt.x, pt.y);
 }
 
 #if wxUSE_HOTKEY
 
 
     return wxPoint(pt.x, pt.y);
 }
 
 #if wxUSE_HOTKEY
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+static void WinCEUnregisterHotKey(int modifiers, int id)
+{
+    // Register hotkeys for the hardware buttons
+    HINSTANCE hCoreDll;
+    typedef BOOL (WINAPI *UnregisterFunc1Proc)(UINT, UINT);
+
+    UnregisterFunc1Proc procUnregisterFunc;
+    hCoreDll = LoadLibrary(_T("coredll.dll"));
+    if (hCoreDll)
+    {
+        procUnregisterFunc = (UnregisterFunc1Proc)GetProcAddress(hCoreDll, _T("UnregisterFunc1"));
+        if (procUnregisterFunc)
+            procUnregisterFunc(modifiers, id);
+        FreeLibrary(hCoreDll);
+    }
+}
+#endif
+
 bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 {
     UINT win_modifiers=0;
 bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 {
     UINT win_modifiers=0;
@@ -5815,6 +6922,12 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
     if ( modifiers & wxMOD_WIN )
         win_modifiers |= MOD_WIN;
 
     if ( modifiers & wxMOD_WIN )
         win_modifiers |= MOD_WIN;
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    // Required for PPC and Smartphone hardware buttons
+    if (keycode >= WXK_SPECIAL1 && keycode <= WXK_SPECIAL20)
+        WinCEUnregisterHotKey(win_modifiers, hotkeyId);
+#endif
+
     if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) )
     {
         wxLogLastError(_T("RegisterHotKey"));
     if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) )
     {
         wxLogLastError(_T("RegisterHotKey"));
@@ -5827,6 +6940,10 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 
 bool wxWindowMSW::UnregisterHotKey(int hotkeyId)
 {
 
 bool wxWindowMSW::UnregisterHotKey(int hotkeyId)
 {
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    WinCEUnregisterHotKey(MOD_WIN, hotkeyId);
+#endif
+
     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId) )
     {
         wxLogLastError(_T("UnregisterHotKey"));
     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId) )
     {
         wxLogLastError(_T("UnregisterHotKey"));
@@ -5852,7 +6969,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
@@ -5898,13 +7015,17 @@ public:
     static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     {
         MSG *msg = (MSG*)lParam;
     static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     {
         MSG *msg = (MSG*)lParam;
-        if ( msg->message == WM_NULL )
+
+        // only process the message if it is actually going to be removed from
+        // the message queue, this prevents that the same event from being
+        // processed multiple times if now someone just called PeekMessage()
+        if ( msg->message == WM_NULL && wParam == PM_REMOVE )
         {
             wxTheApp->ProcessPendingEvents();
         }
 
         return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam);
         {
             wxTheApp->ProcessPendingEvents();
         }
 
         return CallNextHookEx(ms_hMsgHookProc, nCode, wParam, lParam);
-    };
+    }
 
 private:
     static HHOOK ms_hMsgHookProc;
 
 private:
     static HHOOK ms_hMsgHookProc;
@@ -5950,4 +7071,3 @@ void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event )
     event.Skip();
 }
 #endif
     event.Skip();
 }
 #endif
-