]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Include wx/stopwatch.h according to precompiled headers of wx/wx.h (with other minor...
[wxWidgets.git] / src / msw / window.cpp
index cd8d18fa32b14bfb2679b41b1451b837c39c792d..0515fe88be44d7bea076d5e4aab2b57e8213ebbe 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
 // 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"
 
     #pragma hdrstop
 #endif
 
+#include "wx/window.h"
+
 #ifndef WX_PRECOMP
     #include "wx/msw/wrapwin.h"
-    #include "wx/window.h"
     #include "wx/accel.h"
-    #include "wx/setup.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/dcclient.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"
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
@@ -56,6 +56,7 @@
 
 #include "wx/evtloop.h"
 #include "wx/module.h"
+#include "wx/power.h"
 #include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
@@ -74,9 +75,6 @@
     #endif
 #endif
 
-#include "wx/menuitem.h"
-#include "wx/log.h"
-
 #include "wx/msw/private.h"
 
 #if wxUSE_TOOLTIPS
     #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 <windowsx.h>
 #endif
 
-#include <commctrl.h>
+// include <commctrl.h> "properly"
+#include "wx/msw/wrapcctl.h"
+
+#ifndef __WXWINCE__
+    #include <pbt.h>
+#endif
 
 #include "wx/msw/missing.h"
 
 #if defined(__WXWINCE__)
     #include "wx/msw/wince/missing.h"
+#ifdef __POCKETPC__
+    #include <windows.h>
+    #include <shellapi.h>
+    #include <ole2.h>
+    #include <aygshell.h>
+#endif
 #endif
 
 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
 // 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
 
 // ---------------------------------------------------------------------------
 // global variables
@@ -145,6 +162,18 @@ extern const wxChar *wxCanvasClassName;
 // 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
+
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
@@ -155,7 +184,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
 
 
 #ifdef  __WXDEBUG__
-    const char *wxGetMessageName(int message);
+    const wxChar *wxGetMessageName(int message);
 #endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
@@ -165,8 +194,10 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 // 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
-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)
@@ -202,7 +233,7 @@ 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
-       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() )
     {
@@ -376,7 +407,7 @@ wxWindow *wxWindowMSW::FindItem(long id) const
     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)
@@ -464,14 +495,12 @@ void wxWindowMSW::Init()
     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
@@ -501,7 +530,7 @@ wxWindowMSW::~wxWindowMSW()
 #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();
 
@@ -653,7 +682,7 @@ bool wxWindowMSW::Enable(bool enable)
 
         if ( enable )
         {
-            // enable the child back unless it had been disabled before us
+            // re-enable the child unless it had been disabled before us
             if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
                 child->Enable();
         }
@@ -692,12 +721,18 @@ bool wxWindowMSW::Show(bool show)
         return false;
 
     HWND hWnd = GetHwnd();
-    int cshow = show ? SW_SHOW : SW_HIDE;
-    ::ShowWindow(hWnd, cshow);
 
-    if ( show && IsTopLevel() )
+    // 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 )
     {
-        wxBringWindowToTop(hWnd);
+        ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
     }
 
     return true;
@@ -716,16 +751,6 @@ void wxWindowMSW::Lower()
                    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();
@@ -777,28 +802,16 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
         return false;
     }
 
-    if ( m_cursor.Ok() )
+    // don't "overwrite" busy cursor
+    if ( m_cursor.Ok() && !wxIsBusy() )
     {
-        HWND hWnd = GetHwnd();
-
-        // Change the cursor NOW if we're within the correct window
-        POINT point;
-#ifdef __WXWINCE__
-        ::GetCursorPosWinCE(&point);
-#else
-        ::GetCursorPos(&point);
-#endif
-
-        RECT rect = wxGetWindowRect(hWnd);
-
-        if ( ::PtInRect(&rect, point) && !wxIsBusy() )
-            ::SetCursor(GetHcursorOf(m_cursor));
+        ::SetCursor(GetHcursorOf(m_cursor));
     }
 
     return true;
 }
 
-void wxWindowMSW::WarpPointer (int x, int y)
+void wxWindowMSW::WarpPointer(int x, int y)
 {
     ClientToScreen(&x, &y);
 
@@ -808,6 +821,26 @@ 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) == wxWINDOWS_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
 // ---------------------------------------------------------------------------
@@ -820,15 +853,10 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
-    if ( !::GetScrollInfo(hWnd,
-                          wOrient,
-                          &scrollInfo) )
-    {
-        // Not necessarily an error, if there are no scrollbars yet.
-        // wxLogLastError(_T("GetScrollInfo"));
-    }
+    ::GetScrollInfo(hWnd, wOrient, &scrollInfo );
+
     return scrollInfo.nPos;
-//    return ::GetScrollPos(hWnd, wOrient);
+
 #endif
 }
 
@@ -915,11 +943,13 @@ void wxWindowMSW::SetScrollbar(int orient,
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
+        // We have to set the variables here to make them valid in events
+        // triggered by ::SetScrollInfo()
+        *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
+
         ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
                         &info, refresh);
     }
-
-    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -1011,12 +1041,16 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     }
     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;
     }
+
+    // we're officially created now, send the event
+    wxWindowCreateEvent event((wxWindow *)this);
+    (void)GetEventHandler()->ProcessEvent(event);
 }
 
 void wxWindowMSW::UnsubclassWin()
@@ -1065,20 +1099,19 @@ void wxWindowMSW::DissociateHandle()
 
 
 bool wxCheckWindowWndProc(WXHWND hWnd,
-                          WXFARPROC WXUNUSED_IN_WINCE(wndProc))
+                          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.
+// TODO: This list of window class names should be factored out so they can be
+// managed in one place and then accessed from here and other places, such as
+// wxApp::RegisterWindowClasses() and wxApp::UnregisterWindowClasses()
 
-    // 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;
+#else
+    extern const wxChar *wxCanvasClassName;
+    extern const wxChar *wxCanvasClassNameNR;
+#endif
     extern const wxChar *wxMDIFrameClassName;
     extern const wxChar *wxMDIFrameClassNameNoRedraw;
     extern const wxChar *wxMDIChildFrameClassName;
@@ -1086,6 +1119,10 @@ bool wxCheckWindowWndProc(WXHWND hWnd,
     wxString str(wxGetWindowClass(hWnd));
     if (str == wxCanvasClassName ||
         str == wxCanvasClassNameNR ||
+#if wxUSE_GLCANVAS
+        str == _T("wxGLCanvasClass") ||
+        str == _T("wxGLCanvasClassNR") ||
+#endif // wxUSE_GLCANVAS
         str == wxMDIFrameClassName ||
         str == wxMDIFrameClassNameNoRedraw ||
         str == wxMDIChildFrameClassName ||
@@ -1094,17 +1131,6 @@ bool wxCheckWindowWndProc(WXHWND hWnd,
         return true; // Effectively means don't subclass
     else
         return false;
-#else
-    WNDCLASS cls;
-    if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
-    {
-        wxLogLastError(_T("GetClassInfo"));
-
-        return false;
-    }
-
-    return wndProc == (WXFARPROC)cls.lpfnWndProc;
-#endif
 }
 
 // ----------------------------------------------------------------------------
@@ -1120,14 +1146,48 @@ void wxWindowMSW::SetWindowStyleFlag(long 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;
 
-    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 )
     {
@@ -1140,17 +1200,34 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
         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
+    long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+
     if ( exstyle != exstyleOld )
     {
-        long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
 
+        // 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
@@ -1158,7 +1235,7 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
                              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"));
         }
@@ -1175,7 +1252,7 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 
     // 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
+    // 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"))
@@ -1339,7 +1416,7 @@ void wxWindowMSW::Thaw()
 {
     wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
 
-    if ( !--m_frozenness )
+    if ( --m_frozenness == 0 )
     {
         if ( IsShown() )
         {
@@ -1404,6 +1481,26 @@ void wxWindowMSW::Update()
 // drag and drop
 // ---------------------------------------------------------------------------
 
+// we need to lower the sibling static boxes so controls contained within can be
+// a drop target
+static inline 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);
+        }
+    }
+}
 
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
@@ -1415,18 +1512,24 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         m_dropTarget->Register(m_hWnd);
+    }
 }
 #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.
 void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept))
 {
 #ifndef __WXWINCE__
     HWND hWnd = GetHwnd();
     if ( hWnd )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         ::DragAcceptFiles(hWnd, (BOOL)accept);
+    }
 #endif
 }
 
@@ -1450,9 +1553,21 @@ void wxWindowMSW::DoSetToolTip(wxToolTip *tooltip)
 // 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
 {
+#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
@@ -1464,6 +1579,7 @@ void wxWindowMSW::DoGetSize(int *x, int *y) const
             *y = m_pendingSize.y;
     }
     else // use current size
+#endif // USE_DEFERRED_SIZING
     {
         RECT rect = wxGetWindowRect(GetHwnd());
 
@@ -1477,24 +1593,43 @@ void wxWindowMSW::DoGetSize(int *x, int *y) const
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
-    // this is only for top level windows whose resizing is never deferred, so
-    // we can safely use the current size here
-    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
 {
+    wxWindow * const parent = GetParent();
+
+    wxPoint pos;
     if ( m_pendingPosition != wxDefaultPosition )
     {
-        if ( x )
-            *x = m_pendingPosition.x;
-        if ( y )
-            *y = m_pendingPosition.y;
+        pos = m_pendingPosition;
     }
     else // use current position
     {
@@ -1508,33 +1643,31 @@ void wxWindowMSW::DoGetPosition(int *x, int *y) const
         // children, not for the dialogs/frames
         if ( !IsTopLevel() )
         {
-            HWND hParentWnd = 0;
-            wxWindow *parent = GetParent();
-            if ( parent )
-                hParentWnd = GetWinHwnd(parent);
-
             // 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);
-            }
-
             if ( parent )
             {
-                // 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;
+                ::ScreenToClient(GetHwndOf(parent), &point);
             }
         }
 
-        if ( x )
-            *x = point.x;
-        if ( y )
-            *y = point.y;
+        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 )
+        *x = pos.x;
+    if ( y )
+        *y = pos.y;
 }
 
 void wxWindowMSW::DoScreenToClient(int *x, int *y) const
@@ -1569,7 +1702,7 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
         *y = pt.y;
 }
 
-void
+bool
 wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
 {
 #if USE_DEFERRED_SIZING
@@ -1581,7 +1714,7 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
     if ( hdwp )
     {
         hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height,
-                                SWP_NOZORDER);
+                                SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
@@ -1594,15 +1727,23 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
         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
-    if ( !hdwp )
 #endif // USE_DEFERRED_SIZING
+    if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) )
     {
-        if ( !::MoveWindow((HWND)hwnd, x, y, width, height, IsShown()) )
-        {
-            wxLogLastError(wxT("MoveWindow"));
-        }
+        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)
@@ -1614,7 +1755,13 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
     if (height < 0)
         height = 0;
 
-    DoMoveSibling(m_hWnd, x, y, width, height);
+    if ( DoMoveSibling(m_hWnd, x, y, width, height) )
+    {
+#if USE_DEFERRED_SIZING
+        m_pendingPosition = wxPoint(x, y);
+        m_pendingSize = wxSize(width, height);
+#endif // USE_DEFERRED_SIZING
+    }
 }
 
 // set the size of the window: if the dimensions are positive, just use them,
@@ -1634,9 +1781,11 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     GetPosition(&currentX, &currentY);
     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 &&
-         width == currentW && height == currentH )
+         width == currentW && height == currentH &&
+            !(sizeFlags & wxSIZE_FORCE) )
     {
         return;
     }
@@ -1682,18 +1831,17 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
         }
     }
 
-    m_pendingPosition = wxPoint(x, y);
-    m_pendingSize = wxSize(width, height);
     DoMoveWindow(x, y, width, 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
-    // 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
@@ -1734,7 +1882,9 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
         }
 
         // don't call DoMoveWindow() because we want to move window immediately
-        // and not defer it here
+        // 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,
@@ -1853,11 +2003,11 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 #if defined(__WXWINCE__)
     UINT flags = 0;
 #else
-    UINT flags = TPM_RIGHTBUTTON;
+    UINT flags = TPM_RIGHTBUTTON | TPM_RECURSE;
 #endif
     ::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
@@ -1906,18 +2056,14 @@ 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)
-            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,
@@ -1954,6 +2100,20 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         bProcess = false;
                     break;
 
+                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;
+                    else
+                        bWindowChange = true;
+                    break;
+
                 case VK_RETURN:
                     {
                         if ( (lDlgCode & DLGC_WANTMESSAGE) && !bCtrlDown )
@@ -1963,7 +2123,10 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             // it
                             return false;
                         }
-                        else if ( lDlgCode & DLGC_BUTTON )
+
+                        // currently active button should get enter press even
+                        // if there is a default button elsewhere
+                        if ( lDlgCode & DLGC_DEFPUSHBUTTON )
                         {
                             // let IsDialogMessage() handle this for all
                             // buttons except the owner-drawn ones which it
@@ -1972,30 +2135,38 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW )
                             {
                                 // emulate the button click
-                                wxWindow *btn = wxFindWinFromHandle((WXHWND)msg->hwnd);
+                                wxWindow *
+                                    btn = wxFindWinFromHandle((WXHWND)msg->hwnd);
                                 if ( btn )
                                     btn->MSWCommand(BN_CLICKED, 0 /* unused */);
                             }
 
                             bProcess = false;
                         }
-                        // FIXME: this should be handled by
-                        //        wxNavigationKeyEvent handler and not here!
-                        else
+                        else // not a button itself
                         {
 #if wxUSE_BUTTON
-                            wxButton *btn = wxDynamicCast(GetDefaultItem(),
-                                                          wxButton);
-                            if ( btn && btn->IsEnabled() )
+                            wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
+                            if ( tlw )
                             {
-                                // if we do have a default button, do press it
-                                btn->MSWCommand(BN_CLICKED, 0 /* unused */);
+                                wxButton *btn = wxDynamicCast(tlw->GetDefaultItem(), wxButton);
+                                if ( btn && btn->IsEnabled() )
+                                {
+                                    // if we do have a default button, do press it
+                                    btn->MSWCommand(BN_CLICKED, 0 /* unused */);
 
-                                return true;
+                                    return true;
+                                }
                             }
                             else // no default button
 #endif // wxUSE_BUTTON
                             {
+#ifdef __WXWINCE__
+                                wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN);
+                                event.SetEventObject(this);
+                                if(GetEventHandler()->ProcessEvent(event))
+                                    return true;
+#endif
                                 // this is a quick and dirty test for a text
                                 // control
                                 if ( !(lDlgCode & DLGC_HASSETSEL) )
@@ -2034,6 +2205,11 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                 if ( GetEventHandler()->ProcessEvent(event) )
                 {
+                    // 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);
+
                     return true;
                 }
             }
@@ -2047,7 +2223,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         {
             // ::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
+            // [some of] the situations when this may happen and not call it
             // then
 
             // assume we can call it by default
@@ -2068,7 +2244,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 #if !defined(__WXWINCE__)
             if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
             {
-                // passimistic by default
+                // pessimistic by default
                 canSafelyCallIsDlgMsg = false;
                 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
                       node;
@@ -2133,7 +2309,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         // 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
 
@@ -2335,28 +2511,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 #endif // !__WXWINCE__
 
-#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
-        case WM_WINDOWPOSCHANGED:
-            {
-                WINDOWPOS *lpPos = (WINDOWPOS *)lParam;
-
-                if ( !(lpPos->flags & SWP_NOSIZE) )
-                {
-                    RECT rc;
-                    ::GetClientRect(GetHwnd(), &rc);
-
-                    AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc));
-                    AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x,  lpPos->y,
-                                                     lpPos->cx, lpPos->cy));
-
-                    // we need to invalidate any new exposed areas here
-                    // to force them to repaint
-                    if ( ::CombineRgn(hrgnNew, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION )
-                        ::InvalidateRgn(GetHwnd(), hrgnNew, TRUE);
-                }
-            }
-            break;
-#endif
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             // This implicitly sends a wxEVT_ACTIVATE_APP event
@@ -2478,8 +2632,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
+#ifdef __WXWINCE__
                 // 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 )
                 {
@@ -2495,6 +2651,39 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     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 (GetEventHandler()->ProcessEvent(evtCtx))
+                        {
+                            processed = true;
+                            return true;
+                        }
+                    }
+                }
+#endif
+
+#else // !__WXWINCE__
+                wxWindowMSW *win = this;
+#endif // __WXWINCE__/!__WXWINCE__
 
                 processed = win->HandleMouseEvent(message, x, y, wParam);
 
@@ -2613,7 +2802,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             {
                 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:
@@ -2636,6 +2825,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     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:
@@ -2759,6 +2958,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
             break;
 
+        case WM_SETTINGCHANGE:
+            processed = HandleSettingChange(wParam, lParam);
+            break;
+
         case WM_QUERYNEWPALETTE:
             processed = HandleQueryNewPalette();
             break;
@@ -2833,50 +3036,48 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #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;
-                // 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__
-                                              wxPoint(0,0)
+                                    wxGetMousePosition() // what else?
 #else
-                                              wxPoint(info->MousePos.x, info->MousePos.y)
+                                    wxPoint(info->MousePos.x, info->MousePos.y)
 #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);
+                    GetEventHandler()->ProcessEvent(helpEvent);
 #ifndef __WXWINCE__
                 }
-                else if (info->iContextType == HELPINFO_MENUITEM)
+                else if ( info->iContextType == HELPINFO_MENUITEM )
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
-                    processed = GetEventHandler()->ProcessEvent(helpEvent);
+                    GetEventHandler()->ProcessEvent(helpEvent);
 
                 }
-                //else: processed is already false
-#endif
+                else // unknown help event?
+                {
+                    processed = false;
+                }
+#endif // !__WXWINCE__
             }
             break;
-#endif
+#endif // WM_HELP
 
 #if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
@@ -2917,6 +3118,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
+
+#ifndef __WXWINCE__
+        case WM_POWERBROADCAST:
+            {
+                bool vetoed;
+                processed = HandlePower(wParam, lParam, &vetoed);
+                rc.result = processed && vetoed ? BROADCAST_QUERY_DENY : TRUE;
+            }
+            break;
+#endif // __WXWINCE__
     }
 
     if ( !processed )
@@ -3133,8 +3344,6 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
-#ifdef __WIN95__
-
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
@@ -3218,7 +3427,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
-        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).
@@ -3278,8 +3487,6 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
     return false;
 }
 
-#endif // __WIN95__
-
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
@@ -3348,10 +3555,6 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED_IN_WINCE(cs),
         EnsureParentHasControlParentStyle(GetParent());
 #endif // !__WXWINCE__
 
-    // TODO: should generate this event from WM_NCCREATE
-    wxWindowCreateEvent event((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(event);
-
     *mayCreate = true;
 
     return true;
@@ -3468,6 +3671,20 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     return GetEventHandler()->ProcessEvent(event);
 }
 
+// ---------------------------------------------------------------------------
+// labels
+// ---------------------------------------------------------------------------
+
+void wxWindowMSW::SetLabel( const wxString& label)
+{
+    SetWindowText(GetHwnd(), label.c_str());
+}
+
+wxString wxWindowMSW::GetLabel() const
+{
+    return wxGetWindowText(GetHWND());
+}
+
 // ---------------------------------------------------------------------------
 // miscellaneous
 // ---------------------------------------------------------------------------
@@ -3618,6 +3835,69 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     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:
+#ifdef PBT_APMRESUMEAUTOMATIC
+        case PBT_APMRESUMEAUTOMATIC:
+#endif
+            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:
+            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 ( !GetEventHandler()->ProcessEvent(event) )
+        return false;
+
+    *vetoed = event.IsVetoed();
+
+    return true;
+#endif
+}
+
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
@@ -3833,6 +4113,30 @@ bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
     return GetEventHandler()->ProcessEvent(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();
+    }
+
+    // let the system handle it
+    return false;
+}
+
 bool wxWindowMSW::HandleQueryNewPalette()
 {
 
@@ -4009,14 +4313,11 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
     dc.SetHDC(hdc);
     dc.SetWindow((wxWindow *)this);
-    dc.BeginDrawing();
 
     wxEraseEvent event(m_windowId, &dc);
     event.SetEventObject(this);
     bool rc = GetEventHandler()->ProcessEvent(event);
 
-    dc.EndDrawing();
-
     // must be called manually as ~wxDC doesn't do anything for wxDCTemp
     dc.SelectOldObjects(hdc);
 
@@ -4111,37 +4412,11 @@ WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, WXHWND hWndToPaint)
     return 0;
 }
 
-bool wxWindowMSW::HandlePrintClient(WXHDC hDC)
+bool wxWindowMSW::HandlePrintClient(WXHDC WXUNUSED(hDC))
 {
-    // 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!
-
-    if ( IsTopLevel() || InheritsBackgroundColour() )
-        return false;
-
-    // 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);
-
-    for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
-    {
-        if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
-            return true;
-
-        if ( win->IsTopLevel() || win->InheritsBackgroundColour() )
-            break;
-    }
-
+    // TODO: handle wxBG_STYLE_CUSTOM and/or wxBG_STYLE_COLOUR here so when
+    // DrawParentThemeBackground() from uxtheme.dll is called we don't get
+    // the default background e.g. the border when custom drawing buttons
     return false;
 }
 
@@ -4214,7 +4489,7 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
                 useDefer = true;
         }
     }
-#endif
+#endif // USE_DEFERRED_SIZING
 
     // update this window size
     bool processed = false;
@@ -4437,12 +4712,12 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     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
 }
 
+#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
@@ -4453,7 +4728,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.
-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") );
 
@@ -4506,6 +4781,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
 
     return win;
 }
+#endif // __WXWINCE__
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
@@ -4563,19 +4839,36 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             (void)GetEventHandler()->ProcessEvent(event);
         }
     }
+#ifdef HAVE_TRACKMOUSEEVENT
+    else
+    {
+        // 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
-    // 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
 
@@ -4715,35 +5008,14 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool 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;
-        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
     {
-        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
@@ -4780,16 +5052,8 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
         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 GetEventHandler()->ProcessEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
@@ -4802,14 +5066,8 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
         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 GetEventHandler()->ProcessEvent(event);
 }
 
 int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
@@ -4823,12 +5081,20 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
     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++ )
     {
+        // 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 )
@@ -4866,8 +5132,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
         }
         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"));
         }
     }
@@ -4875,6 +5140,18 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
     return wxNOT_FOUND;
 }
 
+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 GetEventHandler()->ProcessEvent(evt);
+}
+
 // ---------------------------------------------------------------------------
 // joystick
 // ---------------------------------------------------------------------------
@@ -5078,226 +5355,313 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font)
     //   the_font.ReleaseResource();
 }
 
+// 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)
+{
+    // 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
+    { VK_LWIN,          WXK_WINDOWS_LEFT },
+    { VK_RWIN,          WXK_WINDOWS_RIGHT },
+    { VK_APPS,          WXK_WINDOWS_MENU },
+#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 keySym, WXLPARAM lParam)
+int wxCharCodeMSWToWX(int vk, WXLPARAM lParam)
 {
-    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_ALT; 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;
+    // 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:      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;
+        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;
 
-#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;
-#endif // VK_APPS defined
+        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:
-            // 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:
-            id = 0;
-    }
-
-    return id;
-}
-
-WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual)
-{
-    *isVirtual = true;
-    WXWORD 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_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 = (WORD)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;
+
+        default:
+            if ( isVirtual )
+                *isVirtual = false;
+            vk = (WXWORD)wxk;
             break;
-        }
     }
-    return keySym;
+
+    return vk;
+}
+
+// small helper for wxGetKeyState() and wxGetMouseState()
+static inline bool wxIsKeyDown(WXWORD vk)
+{
+    // 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 bVirtual;
+    // 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") );
 
-    wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
-        WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
+    const WXWORD vk = wxCharCodeWXToMSW(key);
 
-//High order with GetAsyncKeyState only available on WIN32
-#ifdef __WIN32__
-    //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)
+    // 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 )
     {
-#endif
-        //low order bit means LED is highlighted,
-        //high order means key is down
-        //Here, for compat with other ports we want both
-        return GetKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) != 0;
+        // 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;
 
-#ifdef __WIN32__
     }
-    else
+    else // normal key
     {
-        //normal key
-        //low order bit means key pressed since last call
-        //high order means key is down
-        //We want only the high order bit - the key may not be down if only low order
-        return ( GetAsyncKeyState( wxCharCodeWXToMSW(key, &bVirtual) ) & (1<<15) ) != 0;
+        return wxIsKeyDown(vk);
     }
-#endif
 }
 
+
+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));
+
+    ms.SetControlDown(wxIsKeyDown(VK_CONTROL));
+    ms.SetShiftDown(wxIsKeyDown(VK_SHIFT));
+    ms.SetAltDown(wxIsKeyDown(VK_MENU));
+//    ms.SetMetaDown();
+
+    return ms;
+}
+
+
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
@@ -5441,413 +5805,413 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
 #endif // !__WXMICROWIN__
 
 #ifdef __WXDEBUG__
-const char *wxGetMessageName(int message)
+const wxChar *wxGetMessageName(int 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";
+        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 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 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 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 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");
 #if wxUSE_HOTKEY
-        case 0x0312: return "WM_HOTKEY";
+        case 0x0312: return wxT("WM_HOTKEY");
 #endif
 
         // 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
-        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
-        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
-        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
-        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:
-            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__
@@ -5897,18 +6261,10 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
     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.
@@ -6106,4 +6462,3 @@ void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event )
     event.Skip();
 }
 #endif
-