]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
protect gs_allThreads with a mutex (modified patch 1518719)
[wxWidgets.git] / src / msw / window.cpp
index c332ba35effc6223edba8c3e93eb411442723db3..32facca38443fc382a1c13d2559326c713154722 100644 (file)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/msw/windows.cpp
-// Purpose:     wxWindow
+// Name:        src/msw/window.cpp
+// Purpose:     wxWindowMSW
 // Author:      Julian Smart
 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
 // Created:     04/01/98
 // Author:      Julian Smart
 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
 // Created:     04/01/98
 // headers
 // ---------------------------------------------------------------------------
 
 // headers
 // ---------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "window.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
     #pragma hdrstop
 #endif
 
     #pragma hdrstop
 #endif
 
+#include "wx/window.h"
+
 #ifndef WX_PRECOMP
     #include "wx/msw/wrapwin.h"
 #ifndef WX_PRECOMP
     #include "wx/msw/wrapwin.h"
-    #include "wx/window.h"
     #include "wx/accel.h"
     #include "wx/accel.h"
-    #include "wx/setup.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/dcclient.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/dcclient.h"
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
     #include "wx/statbox.h"
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
     #include "wx/statbox.h"
+    #include "wx/sizer.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
+    #include "wx/textctrl.h"
+    #include "wx/menuitem.h"
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
     #include "wx/ownerdrw.h"
 #endif
 
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
     #include "wx/ownerdrw.h"
 #endif
 
+#include "wx/evtloop.h"
 #include "wx/module.h"
 #include "wx/module.h"
+#include "wx/power.h"
 #include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
 #include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
@@ -72,9 +75,6 @@
     #endif
 #endif
 
     #endif
 #endif
 
-#include "wx/menuitem.h"
-#include "wx/log.h"
-
 #include "wx/msw/private.h"
 
 #if wxUSE_TOOLTIPS
 #include "wx/msw/private.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/spinctrl.h"
 #endif // wxUSE_SPINCTRL
 
     #include "wx/spinctrl.h"
 #endif // wxUSE_SPINCTRL
 
-#include "wx/intl.h"
-#include "wx/log.h"
-
-#include "wx/textctrl.h"
 #include "wx/notebook.h"
 #include "wx/listctrl.h"
 
 #include "wx/notebook.h"
 #include "wx/listctrl.h"
 
     #include <windowsx.h>
 #endif
 
     #include <windowsx.h>
 #endif
 
-#if (!defined(__GNUWIN32_OLD__) && !defined(__WXMICROWIN__) /* && !defined(__WXWINCE__) */ ) || defined(__CYGWIN10__)
-    #ifdef __WIN95__
-        #include <commctrl.h>
-    #endif
-#elif !defined(__WXMICROWIN__) && !defined(__WXWINCE__) // broken compiler
-    #include "wx/msw/gnuwin32/extra.h"
+// 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"
 #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)
     #define HAVE_TRACKMOUSEEVENT
 #endif // everything needed for TrackMouseEvent()
 
 #endif
 
 #if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
     #define HAVE_TRACKMOUSEEVENT
 #endif // everything needed for TrackMouseEvent()
 
+// if this is set to 1, we use deferred window sizing to reduce flicker when
+// resizing complicated window hierarchies, but this can in theory result in
+// different behaviour than the old code so we keep the possibility to use it
+// by setting this to 0 (in the future this should be removed completely)
+#ifdef __WXWINCE__
+#define USE_DEFERRED_SIZING 0
+#else
+#define USE_DEFERRED_SIZING 1
+#endif
+
+// set this to 1 to filter out duplicate mouse events, e.g. mouse move events
+// when mouse position didnd't change
+#ifdef __WXWINCE__
+    #define wxUSE_MOUSEEVENT_HACK 0
+#else
+    #define wxUSE_MOUSEEVENT_HACK 1
+#endif
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
@@ -143,6 +162,18 @@ extern const wxChar *wxCanvasClassName;
 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT)
 static bool gs_hasStdCmap = false;
 
 // 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
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
@@ -153,7 +184,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
 
 
 #ifdef  __WXDEBUG__
 
 
 #ifdef  __WXDEBUG__
-    const char *wxGetMessageName(int message);
+    const wxChar *wxGetMessageName(int message);
 #endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
 #endif  //__WXDEBUG__
 
 void wxRemoveHandleAssociation(wxWindowMSW *win);
@@ -163,8 +194,10 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
+#ifdef __WXWINCE__
 // find the window for the mouse event at the specified position
 // find the window for the mouse event at the specified position
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y); //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y);
+#endif // __WXWINCE__
 
 // wrapper around BringWindowToTop() API
 static inline void wxBringWindowToTop(HWND hwnd)
 
 // wrapper around BringWindowToTop() API
 static inline void wxBringWindowToTop(HWND hwnd)
@@ -200,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
        get back to the initial (focused) window: as we do have this style,
        GetNextDlgTabItem() will leave this window and continue in its parent,
        but if the parent doesn't have it, it wouldn't recurse inside it later
-       on and so wouldn't have a chance of getting back to this window neither.
+       on and so wouldn't have a chance of getting back to this window either.
      */
     while ( parent && !parent->IsTopLevel() )
     {
      */
     while ( parent && !parent->IsTopLevel() )
     {
@@ -218,6 +251,21 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
 
 #endif // !__WXWINCE__
 
 
 #endif // !__WXWINCE__
 
+#ifdef __WXWINCE__
+// On Windows CE, GetCursorPos can return an error, so use this function
+// instead
+bool GetCursorPosWinCE(POINT* pt)
+{
+    if (!GetCursorPos(pt))
+    {
+        DWORD pos = GetMessagePos();
+        pt->x = LOWORD(pos);
+        pt->y = HIWORD(pos);
+    }
+    return true;
+}
+#endif
+
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // event tables
 // ---------------------------------------------------------------------------
@@ -359,7 +407,7 @@ wxWindow *wxWindowMSW::FindItem(long id) const
     wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
     wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
-        // is it we or one of our "internal" children?
+        // is it us or one of our "internal" children?
         if ( item->GetId() == id
 #ifndef __WXUNIVERSAL__
                 || (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
         if ( item->GetId() == id
 #ifndef __WXUNIVERSAL__
                 || (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
@@ -447,11 +495,12 @@ void wxWindowMSW::Init()
     m_xThumbSize = 0;
     m_yThumbSize = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
 
-#if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX =
-    m_lastMouseY = -1;
-    m_lastMouseEvent = -1;
-#endif // wxUSE_MOUSEEVENT_HACK
+    m_pendingPosition = wxDefaultPosition;
+    m_pendingSize = wxDefaultSize;
+
+#ifdef __POCKETPC__
+    m_contextMenuEnabled = false;
+#endif
 }
 
 // Destructor
 }
 
 // Destructor
@@ -470,13 +519,18 @@ wxWindowMSW::~wxWindowMSW()
             {
                 frame->SetLastFocus(NULL);
             }
             {
                 frame->SetLastFocus(NULL);
             }
-            break;
+
+            // apparently sometimes we can end up with our grand parent
+            // pointing to us as well: this is surely a bug in focus handling
+            // code but it's not clear where it happens so for now just try to
+            // fix it here by not breaking out of the loop
+            //break;
         }
     }
 #endif // __WXUNIVERSAL__
 
     // VS: destroy children first and _then_ detach *this from its parent.
         }
     }
 #endif // __WXUNIVERSAL__
 
     // VS: destroy children first and _then_ detach *this from its parent.
-    //     If we'd do it the other way around, children wouldn't be able
+    //     If we did it the other way around, children wouldn't be able
     //     find their parent frame (see above).
     DestroyChildren();
 
     //     find their parent frame (see above).
     DestroyChildren();
 
@@ -494,6 +548,7 @@ wxWindowMSW::~wxWindowMSW()
     }
 
     delete m_childrenDisabled;
     }
 
     delete m_childrenDisabled;
+
 }
 
 // real construction (Init() must have been called before!)
 }
 
 // real construction (Init() must have been called before!)
@@ -627,7 +682,7 @@ bool wxWindowMSW::Enable(bool enable)
 
         if ( 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();
         }
             if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
                 child->Enable();
         }
@@ -666,12 +721,18 @@ bool wxWindowMSW::Show(bool show)
         return false;
 
     HWND hWnd = GetHwnd();
         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;
     }
 
     return true;
@@ -690,16 +751,6 @@ void wxWindowMSW::Lower()
                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 }
 
                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 }
 
-void wxWindowMSW::SetTitle( const wxString& title)
-{
-    SetWindowText(GetHwnd(), title.c_str());
-}
-
-wxString wxWindowMSW::GetTitle() const
-{
-    return wxGetWindowText(GetHWND());
-}
-
 void wxWindowMSW::DoCaptureMouse()
 {
     HWND hWnd = GetHwnd();
 void wxWindowMSW::DoCaptureMouse()
 {
     HWND hWnd = GetHwnd();
@@ -751,24 +802,16 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
         return false;
     }
 
         return false;
     }
 
-    if ( m_cursor.Ok() )
+    // don't "overwrite" busy cursor
+    if ( m_cursor.Ok() && !wxIsBusy() )
     {
     {
-        HWND hWnd = GetHwnd();
-
-        // Change the cursor NOW if we're within the correct window
-        POINT point;
-        ::GetCursorPos(&point);
-
-        RECT rect = wxGetWindowRect(hWnd);
-
-        if ( ::PtInRect(&rect, point) && !wxIsBusy() )
-            ::SetCursor(GetHcursorOf(m_cursor));
+        ::SetCursor(GetHcursorOf(m_cursor));
     }
 
     return true;
 }
 
     }
 
     return true;
 }
 
-void wxWindowMSW::WarpPointer (int x, int y)
+void wxWindowMSW::WarpPointer(int x, int y)
 {
     ClientToScreen(&x, &y);
 
 {
     ClientToScreen(&x, &y);
 
@@ -778,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
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
@@ -790,15 +853,10 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
-    if ( !::GetScrollInfo(hWnd,
-                          wOrient,
-                          &scrollInfo) )
-    {
-        // Not neccessarily an error, if there are no scrollbars yet.
-        // wxLogLastError(_T("GetScrollInfo"));
-    }
+    ::GetScrollInfo(hWnd, wOrient, &scrollInfo );
+
     return scrollInfo.nPos;
     return scrollInfo.nPos;
-//    return ::GetScrollPos(hWnd, wOrient);
+
 #endif
 }
 
 #endif
 }
 
@@ -885,11 +943,13 @@ void wxWindowMSW::SetScrollbar(int orient,
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
     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);
     }
         ::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)
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -981,12 +1041,16 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     }
     else
     {
     }
     else
     {
-        // don't bother restoring it neither: this also makes it easy to
+        // don't bother restoring it either: this also makes it easy to
         // implement IsOfStandardClass() method which returns true for the
         // standard controls and false for the wxWidgets own windows as it can
         // simply check m_oldWndProc
         m_oldWndProc = NULL;
     }
         // implement IsOfStandardClass() method which returns true for the
         // standard controls and false for the wxWidgets own windows as it can
         // simply check m_oldWndProc
         m_oldWndProc = NULL;
     }
+
+    // we're officially created now, send the event
+    wxWindowCreateEvent event((wxWindow *)this);
+    (void)GetEventHandler()->ProcessEvent(event);
 }
 
 void wxWindowMSW::UnsubclassWin()
 }
 
 void wxWindowMSW::UnsubclassWin()
@@ -1034,22 +1098,20 @@ void wxWindowMSW::DissociateHandle()
 }
 
 
 }
 
 
-bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
+bool wxCheckWindowWndProc(WXHWND hWnd,
+                          WXFARPROC WXUNUSED(wndProc))
 {
 {
-    // Unicows note: the code below works, but only because WNDCLASS contains
-    // original window handler rather that the unicows fake one. This may not
-    // be on purpose, though; if it stops working with future versions of
-    // unicows.dll, we can override unicows hooks by setting
-    // Unicows_{Set,Get}WindowLong and Unicows_RegisterClass to our own
-    // versions that keep track of fake<->real wnd proc mapping.
+// 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__
 #ifdef __WXWINCE__
-    wxUnusedVar(wndProc);
-
     extern       wxChar *wxCanvasClassName;
     extern       wxChar *wxCanvasClassNameNR;
     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;
     extern const wxChar *wxMDIFrameClassName;
     extern const wxChar *wxMDIFrameClassNameNoRedraw;
     extern const wxChar *wxMDIChildFrameClassName;
@@ -1057,6 +1119,10 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     wxString str(wxGetWindowClass(hWnd));
     if (str == wxCanvasClassName ||
         str == wxCanvasClassNameNR ||
     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 ||
         str == wxMDIFrameClassName ||
         str == wxMDIFrameClassNameNoRedraw ||
         str == wxMDIChildFrameClassName ||
@@ -1065,17 +1131,6 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
         return true; // Effectively means don't subclass
     else
         return false;
         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
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -1091,14 +1146,48 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
     // update the internal variable
     wxWindowBase::SetWindowStyleFlag(flags);
 
     // update the internal variable
     wxWindowBase::SetWindowStyleFlag(flags);
 
+    // and the real window flags
+    MSWUpdateStyle(flagsOld, GetExtraStyle());
+}
+
+void wxWindowMSW::SetExtraStyle(long exflags)
+{
+    long exflagsOld = GetExtraStyle();
+    if ( exflags == exflagsOld )
+        return;
+
+    // update the internal variable
+    wxWindowBase::SetExtraStyle(exflags);
+
+    // and the real window flags
+    MSWUpdateStyle(GetWindowStyleFlag(), exflagsOld);
+}
+
+void wxWindowMSW::MSWUpdateStyle(long flagsOld, long exflagsOld)
+{
     // now update the Windows style as well if needed - and if the window had
     // been already created
     if ( !GetHwnd() )
         return;
 
     // now update the Windows style as well if needed - and if the window had
     // been already created
     if ( !GetHwnd() )
         return;
 
-    WXDWORD exstyle, exstyleOld;
-    long style = MSWGetStyle(flags, &exstyle),
-         styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+    // we may need to call SetWindowPos() when we change some styles
+    bool callSWP = false;
+
+    WXDWORD exstyle;
+    long style = MSWGetStyle(GetWindowStyleFlag(), &exstyle);
+
+    // this is quite a horrible hack but we need it because MSWGetStyle()
+    // doesn't take exflags as parameter but uses GetExtraStyle() internally
+    // and so we have to modify the window exflags temporarily to get the
+    // correct exstyleOld
+    long exflagsNew = GetExtraStyle();
+    wxWindowBase::SetExtraStyle(exflagsOld);
+
+    WXDWORD exstyleOld;
+    long styleOld = MSWGetStyle(flagsOld, &exstyleOld);
+
+    wxWindowBase::SetExtraStyle(exflagsNew);
+
 
     if ( style != styleOld )
     {
 
     if ( style != styleOld )
     {
@@ -1111,25 +1200,42 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
         styleReal |= style;
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
         styleReal |= style;
 
         ::SetWindowLong(GetHwnd(), GWL_STYLE, styleReal);
+
+        // we need to call SetWindowPos() if any of the styles affecting the
+        // frame appearance have changed
+        callSWP = ((styleOld ^ style ) & (WS_BORDER |
+                                      WS_THICKFRAME |
+                                      WS_CAPTION |
+                                      WS_DLGFRAME |
+                                      WS_MAXIMIZEBOX |
+                                      WS_MINIMIZEBOX |
+                                      WS_SYSMENU) ) != 0;
     }
 
     // and the extended style
     }
 
     // and the extended style
+    long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
+
     if ( exstyle != exstyleOld )
     {
     if ( exstyle != exstyleOld )
     {
-        long exstyleReal = ::GetWindowLong(GetHwnd(), GWL_EXSTYLE);
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
 
         exstyleReal &= ~exstyleOld;
         exstyleReal |= exstyle;
 
         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
 
-        // we must call SetWindowPos() to flash the cached extended style and
+        // ex style changes don't take effect without calling SetWindowPos
+        callSWP = true;
+    }
+
+    if ( callSWP )
+    {
+        // we must call SetWindowPos() to flush the cached extended style and
         // also to make the change to wxSTAY_ON_TOP style take effect: just
         // setting the style simply doesn't work
         if ( !::SetWindowPos(GetHwnd(),
                              exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
                                                          : HWND_NOTOPMOST,
                              0, 0, 0, 0,
         // also to make the change to wxSTAY_ON_TOP style take effect: just
         // setting the style simply doesn't work
         if ( !::SetWindowPos(GetHwnd(),
                              exstyleReal & WS_EX_TOPMOST ? HWND_TOPMOST
                                                          : HWND_NOTOPMOST,
                              0, 0, 0, 0,
-                             SWP_NOMOVE | SWP_NOSIZE) )
+                             SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED) )
         {
             wxLogLastError(_T("SetWindowPos"));
         }
         {
             wxLogLastError(_T("SetWindowPos"));
         }
@@ -1146,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
 
     // 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"))
     // 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"))
@@ -1235,7 +1341,11 @@ bool wxWindowMSW::IsMouseInWindow() const
 {
     // get the mouse position
     POINT pt;
 {
     // get the mouse position
     POINT pt;
+#ifdef __WXWINCE__
+    ::GetCursorPosWinCE(&pt);
+#else
     ::GetCursorPos(&pt);
     ::GetCursorPos(&pt);
+#endif
 
     // find the window which currently has the cursor and go up the window
     // chain until we find this window - or exhaust it
 
     // find the window which currently has the cursor and go up the window
     // chain until we find this window - or exhaust it
@@ -1297,7 +1407,8 @@ void wxWindowMSW::Freeze()
 {
     if ( !m_frozenness++ )
     {
 {
     if ( !m_frozenness++ )
     {
-        SendSetRedraw(GetHwnd(), false);
+        if ( IsShown() )
+            SendSetRedraw(GetHwnd(), false);
     }
 }
 
     }
 }
 
@@ -1305,13 +1416,16 @@ void wxWindowMSW::Thaw()
 {
     wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
 
 {
     wxASSERT_MSG( m_frozenness > 0, _T("Thaw() without matching Freeze()") );
 
-    if ( !--m_frozenness )
+    if ( --m_frozenness == 0 )
     {
     {
-        SendSetRedraw(GetHwnd(), true);
+        if ( IsShown() )
+        {
+            SendSetRedraw(GetHwnd(), true);
 
 
-        // we need to refresh everything or otherwise he invalidated area is not
-        // repainted
-        Refresh();
+            // we need to refresh everything or otherwise the invalidated area
+            // is not going to be repainted
+            Refresh();
+        }
     }
 }
 
     }
 }
 
@@ -1320,18 +1434,32 @@ void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
+        RECT mswRect;
+        const RECT *pRect;
         if ( rect )
         {
         if ( rect )
         {
-            RECT mswRect;
             mswRect.left = rect->x;
             mswRect.top = rect->y;
             mswRect.right = rect->x + rect->width;
             mswRect.bottom = rect->y + rect->height;
 
             mswRect.left = rect->x;
             mswRect.top = rect->y;
             mswRect.right = rect->x + rect->width;
             mswRect.bottom = rect->y + rect->height;
 
-            ::InvalidateRect(hWnd, &mswRect, eraseBack);
+            pRect = &mswRect;
         }
         else
         }
         else
-            ::InvalidateRect(hWnd, NULL, eraseBack);
+        {
+            pRect = NULL;
+        }
+
+        // RedrawWindow not available on SmartPhone or eVC++ 3
+#if !defined(__SMARTPHONE__) && !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
+        UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
+        if ( eraseBack )
+            flags |= RDW_ERASE;
+
+        ::RedrawWindow(hWnd, pRect, NULL, flags);
+#else
+        ::InvalidateRect(hWnd, pRect, eraseBack);
+#endif
     }
 }
 
     }
 }
 
@@ -1353,6 +1481,26 @@ void wxWindowMSW::Update()
 // drag and drop
 // ---------------------------------------------------------------------------
 
 // 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)
 
 #if wxUSE_DRAG_AND_DROP
 void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
@@ -1364,20 +1512,24 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != 0 )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         m_dropTarget->Register(m_hWnd);
         m_dropTarget->Register(m_hWnd);
+    }
 }
 #endif // wxUSE_DRAG_AND_DROP
 
 }
 #endif // wxUSE_DRAG_AND_DROP
 
-// old style file-manager drag&drop support: we retain the old-style
+// old-style file manager drag&drop support: we retain the old-style
 // DragAcceptFiles in parallel with SetDropTarget.
 // DragAcceptFiles in parallel with SetDropTarget.
-void wxWindowMSW::DragAcceptFiles(bool accept)
+void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept))
 {
 {
-#if !defined(__WXWINCE__)
+#ifndef __WXWINCE__
     HWND hWnd = GetHwnd();
     if ( hWnd )
     HWND hWnd = GetHwnd();
     if ( hWnd )
+    {
+        AdjustStaticBoxZOrder(GetParent());
         ::DragAcceptFiles(hWnd, (BOOL)accept);
         ::DragAcceptFiles(hWnd, (BOOL)accept);
-#else
-    wxUnusedVar(accept);
+    }
 #endif
 }
 
 #endif
 }
 
@@ -1401,66 +1553,121 @@ void wxWindowMSW::DoSetToolTip(wxToolTip *tooltip)
 // moving and resizing
 // ---------------------------------------------------------------------------
 
 // moving and resizing
 // ---------------------------------------------------------------------------
 
+bool wxWindowMSW::IsSizeDeferred() const
+{
+#if USE_DEFERRED_SIZING
+    if ( m_pendingPosition != wxDefaultPosition ||
+         m_pendingSize     != wxDefaultSize )
+        return true;
+#endif // USE_DEFERRED_SIZING
+
+    return false;
+}
+
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
-    RECT rect = wxGetWindowRect(GetHwnd());
+#if USE_DEFERRED_SIZING
+    // if SetSize() had been called at wx level but not realized at Windows
+    // level yet (i.e. EndDeferWindowPos() not called), we still should return
+    // the new and not the old position to the other wx code
+    if ( m_pendingSize != wxDefaultSize )
+    {
+        if ( x )
+            *x = m_pendingSize.x;
+        if ( y )
+            *y = m_pendingSize.y;
+    }
+    else // use current size
+#endif // USE_DEFERRED_SIZING
+    {
+        RECT rect = wxGetWindowRect(GetHwnd());
 
 
-    if ( x )
-        *x = rect.right - rect.left;
-    if ( y )
-        *y = rect.bottom - rect.top;
+        if ( x )
+            *x = rect.right - rect.left;
+        if ( y )
+            *y = rect.bottom - rect.top;
+    }
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
 }
 
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
-    RECT rect = wxGetClientRect(GetHwnd());
+#if USE_DEFERRED_SIZING
+    if ( m_pendingSize != wxDefaultSize )
+    {
+        // we need to calculate the client size corresponding to pending size
+        RECT rect;
+        rect.left = m_pendingPosition.x;
+        rect.top = m_pendingPosition.y;
+        rect.right = rect.left + m_pendingSize.x;
+        rect.bottom = rect.top + m_pendingSize.y;
 
 
-    if ( x )
-        *x = rect.right;
-    if ( y )
-        *y = rect.bottom;
+        ::SendMessage(GetHwnd(), WM_NCCALCSIZE, FALSE, (LPARAM)&rect);
+
+        if ( x )
+            *x = rect.right - rect.left;
+        if ( y )
+            *y = rect.bottom - rect.top;
+    }
+    else
+#endif // USE_DEFERRED_SIZING
+    {
+        RECT rect = wxGetClientRect(GetHwnd());
+
+        if ( x )
+            *x = rect.right;
+        if ( y )
+            *y = rect.bottom;
+    }
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
 {
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
 {
-    RECT rect = wxGetWindowRect(GetHwnd());
-
-    POINT point;
-    point.x = rect.left;
-    point.y = rect.top;
+    wxWindow * const parent = GetParent();
 
 
-    // we do the adjustments with respect to the parent only for the "real"
-    // children, not for the dialogs/frames
-    if ( !IsTopLevel() )
+    wxPoint pos;
+    if ( m_pendingPosition != wxDefaultPosition )
+    {
+        pos = m_pendingPosition;
+    }
+    else // use current position
     {
     {
-        HWND hParentWnd = 0;
-        wxWindow *parent = GetParent();
-        if ( parent )
-            hParentWnd = GetWinHwnd(parent);
+        RECT rect = wxGetWindowRect(GetHwnd());
 
 
-        // Since we now have the absolute screen coords, if there's a parent we
-        // must subtract its top left corner
-        if ( hParentWnd )
-        {
-            ::ScreenToClient(hParentWnd, &point);
-        }
+        POINT point;
+        point.x = rect.left;
+        point.y = rect.top;
 
 
-        if ( parent )
+        // we do the adjustments with respect to the parent only for the "real"
+        // children, not for the dialogs/frames
+        if ( !IsTopLevel() )
         {
         {
-            // We may be faking the client origin. So a window that's really at (0,
-            // 30) may appear (to wxWin apps) to be at (0, 0).
-            wxPoint pt(parent->GetClientAreaOrigin());
-            point.x -= pt.x;
-            point.y -= pt.y;
+            // Since we now have the absolute screen coords, if there's a
+            // parent we must subtract its top left corner
+            if ( parent )
+            {
+                ::ScreenToClient(GetHwndOf(parent), &point);
+            }
         }
         }
+
+        pos.x = point.x;
+        pos.y = point.y;
+    }
+
+    // we also must adjust by the client area offset: a control which is just
+    // under a toolbar could be at (0, 30) in Windows but at (0, 0) in wx
+    if ( parent && !IsTopLevel() )
+    {
+        const wxPoint pt(parent->GetClientAreaOrigin());
+        pos.x -= pt.x;
+        pos.y -= pt.y;
     }
 
     if ( x )
     }
 
     if ( x )
-        *x = point.x;
+        *x = pos.x;
     if ( y )
     if ( y )
-        *y = point.y;
+        *y = pos.y;
 }
 
 void wxWindowMSW::DoScreenToClient(int *x, int *y) const
 }
 
 void wxWindowMSW::DoScreenToClient(int *x, int *y) const
@@ -1495,40 +1702,65 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
         *y = pt.y;
 }
 
         *y = pt.y;
 }
 
-void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
+bool
+wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
 {
 {
-    // TODO: is this consistent with other platforms?
-    // Still, negative width or height shouldn't be allowed
-    if (width < 0)
-        width = 0;
-    if (height < 0)
-        height = 0;
-
+#if USE_DEFERRED_SIZING
     // if our parent had prepared a defer window handle for us, use it (unless
     // we are a top level window)
     // if our parent had prepared a defer window handle for us, use it (unless
     // we are a top level window)
-    wxWindowMSW *parent = GetParent();
-    HDWP hdwp = (parent && !IsTopLevel()) ? (HDWP)parent->m_hDWP : NULL;
+    wxWindowMSW * const parent = IsTopLevel() ? NULL : GetParent();
+
+    HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
     if ( hdwp )
     {
     if ( hdwp )
     {
-        hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL,
-                                x, y, width, height,
-                                SWP_NOZORDER);
+        hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height,
+                                SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
         }
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
         }
+    }
 
 
+    if ( parent )
+    {
         // hdwp must be updated as it may have been changed
         parent->m_hDWP = (WXHANDLE)hdwp;
     }
 
         // hdwp must be updated as it may have been changed
         parent->m_hDWP = (WXHANDLE)hdwp;
     }
 
+    if ( hdwp )
+    {
+        // did deferred move, remember new coordinates of the window as they're
+        // different from what Windows would return for it
+        return true;
+    }
+
     // otherwise (or if deferring failed) move the window in place immediately
     // 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(GetHwnd(), 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)
+{
+    // TODO: is this consistent with other platforms?
+    // Still, negative width or height shouldn't be allowed
+    if (width < 0)
+        width = 0;
+    if (height < 0)
+        height = 0;
+
+    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
     }
 }
 
     }
 }
 
@@ -1544,13 +1776,16 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
     // get the current size and position...
     int currentX, currentY;
 {
     // get the current size and position...
     int currentX, currentY;
+    int currentW, currentH;
+
     GetPosition(&currentX, &currentY);
     GetPosition(&currentX, &currentY);
-    int currentW,currentH;
     GetSize(&currentW, &currentH);
 
     GetSize(&currentW, &currentH);
 
-    // ... and don't do anything (avoiding flicker) if it's already ok
+    // ... and don't do anything (avoiding flicker) if it's already ok unless
+    // we're forced to resize the window
     if ( x == currentX && y == currentY &&
     if ( x == currentX && y == currentY &&
-         width == currentW && height == currentH )
+         width == currentW && height == currentH &&
+            !(sizeFlags & wxSIZE_FORCE) )
     {
         return;
     }
     {
         return;
     }
@@ -1601,11 +1836,12 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 
 void wxWindowMSW::DoSetClientSize(int width, int height)
 {
 
 void wxWindowMSW::DoSetClientSize(int width, int height)
 {
-    // setting the client size is less obvious than it it could have been
+    // setting the client size is less obvious than it could have been
     // because in the result of changing the total size the window scrollbar
     // because in the result of changing the total size the window scrollbar
-    // may [dis]appear and/or its menubar may [un]wrap and so the client size
-    // will not be correct as the difference between the total and client size
-    // changes - so we keep changing it until we get it right
+    // may [dis]appear and/or its menubar may [un]wrap (and AdjustWindowRect()
+    // doesn't take neither into account) and so the client size will not be
+    // correct as the difference between the total and client size changes --
+    // so we keep changing it until we get it right
     //
     // normally this loop shouldn't take more than 3 iterations (usually 1 but
     // if scrollbars [dis]appear as the result of the first call, then 2 and it
     //
     // normally this loop shouldn't take more than 3 iterations (usually 1 but
     // if scrollbars [dis]appear as the result of the first call, then 2 and it
@@ -1618,28 +1854,21 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
         RECT rectClient;
         ::GetClientRect(GetHwnd(), &rectClient);
 
         RECT rectClient;
         ::GetClientRect(GetHwnd(), &rectClient);
 
-        // if the size is already ok, stop here (rectClient.left = top = 0)
+        // if the size is already ok, stop here (NB: rectClient.left = top = 0)
         if ( (rectClient.right == width || width == wxDefaultCoord) &&
              (rectClient.bottom == height || height == wxDefaultCoord) )
         {
             break;
         }
 
         if ( (rectClient.right == width || width == wxDefaultCoord) &&
              (rectClient.bottom == height || height == wxDefaultCoord) )
         {
             break;
         }
 
-        int widthClient = width,
-            heightClient = height;
-
         // Find the difference between the entire window (title bar and all)
         // and the client area; add this to the new client size to move the
         // window
         RECT rectWin;
         ::GetWindowRect(GetHwnd(), &rectWin);
 
         // Find the difference between the entire window (title bar and all)
         // and the client area; add this to the new client size to move the
         // window
         RECT rectWin;
         ::GetWindowRect(GetHwnd(), &rectWin);
 
-        widthClient += rectWin.right - rectWin.left - rectClient.right;
-        heightClient += rectWin.bottom - rectWin.top - rectClient.bottom;
-
-        POINT point;
-        point.x = rectWin.left;
-        point.y = rectWin.top;
+        const int widthWin = rectWin.right - rectWin.left,
+                  heightWin = rectWin.bottom - rectWin.top;
 
         // MoveWindow positions the child windows relative to the parent, so
         // adjust if necessary
 
         // MoveWindow positions the child windows relative to the parent, so
         // adjust if necessary
@@ -1648,11 +1877,23 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
             wxWindow *parent = GetParent();
             if ( parent )
             {
             wxWindow *parent = GetParent();
             if ( parent )
             {
-                ::ScreenToClient(GetHwndOf(parent), &point);
+                ::ScreenToClient(GetHwndOf(parent), (POINT *)&rectWin);
             }
         }
 
             }
         }
 
-        DoMoveWindow(point.x, point.y, widthClient, heightClient);
+        // don't call DoMoveWindow() because we want to move window immediately
+        // and not defer it here as otherwise the value returned by
+        // GetClient/WindowRect() wouldn't change as the window wouldn't be
+        // really resized
+        if ( !::MoveWindow(GetHwnd(),
+                           rectWin.left,
+                           rectWin.top,
+                           width + widthWin - rectClient.right,
+                           height + heightWin - rectClient.bottom,
+                           TRUE) )
+        {
+            wxLogLastError(_T("MoveWindow"));
+        }
     }
 }
 
     }
 }
 
@@ -1695,7 +1936,7 @@ void wxWindowMSW::GetTextExtent(const wxString& string,
 
     SIZE sizeRect;
     TEXTMETRIC tm;
 
     SIZE sizeRect;
     TEXTMETRIC tm;
-    GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+    ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect);
     GetTextMetrics(hdc, &tm);
 
     if ( x )
     GetTextMetrics(hdc, &tm);
 
     if ( x )
@@ -1762,11 +2003,11 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 #if defined(__WXWINCE__)
     UINT flags = 0;
 #else
 #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);
 
 #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
     // sent to wxCurrentPopupMenu from HandleCommand()
     //
     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
@@ -1815,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)
             // WM_GETDLGCODE: ask the control if it wants the key for itself,
             // don't process it if it's the case (except for Ctrl-Tab/Enter
             // combinations which are always processed)
-            LONG lDlgCode = 0;
-            if ( !bCtrlDown )
-            {
-                lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+            LONG lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
 
 
-                // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the
-                // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically,
-                // it, of course, implies them
-                if ( lDlgCode & DLGC_WANTALLKEYS )
-                {
-                    lDlgCode |= DLGC_WANTTAB | DLGC_WANTARROWS;
-                }
+            // surprizingly, DLGC_WANTALLKEYS bit mask doesn't contain the
+            // DLGC_WANTTAB nor DLGC_WANTARROWS bits although, logically,
+            // it, of course, implies them
+            if ( lDlgCode & DLGC_WANTALLKEYS )
+            {
+                lDlgCode |= DLGC_WANTTAB | DLGC_WANTARROWS;
             }
 
             bool bForward = true,
             }
 
             bool bForward = true,
@@ -1863,36 +2100,18 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         bProcess = false;
                     break;
 
                         bProcess = false;
                     break;
 
-                case VK_ESCAPE:
-                    {
-#if wxUSE_BUTTON
-                        wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),wxButton);
-
-                        // our own wxLogDialog should react to Esc
-                        // without Cancel button but this is a private class
-                        // so let's try recognize it by content
-    #if wxUSE_LOG_DIALOG
-                        if ( !btn &&
-                             wxDynamicCast(this,wxDialog) &&
-                             FindWindow(wxID_MORE) &&
-                             FindWindow(wxID_OK) &&
-                             !FindWindow(wxID_CANCEL) &&
-                             GetTitle().MakeLower().StartsWith(wxTheApp->GetAppName().c_str())
-                             )
-                            btn = wxDynamicCast(FindWindow(wxID_OK),wxButton);
-    #endif // wxUSE_LOG_DIALOG
-                        if ( btn && btn->IsEnabled() )
-                        {
-                            // if we do have a cancel button, do press it
-                            btn->MSWCommand(BN_CLICKED, 0 /* unused */);
-
-                            // we consumed the message
-                            return true;
-                        }
-#endif // wxUSE_BUTTON
+                case VK_PRIOR:
+                    bForward = false;
+                    // fall through
 
 
+                case VK_NEXT:
+                    // we treat PageUp/Dn as arrows because chances are that
+                    // a control which needs arrows also needs them for
+                    // navigation (e.g. wxTextCtrl, wxListCtrl, ...)
+                    if ( (lDlgCode & DLGC_WANTARROWS) || !bCtrlDown )
                         bProcess = false;
                         bProcess = false;
-                    }
+                    else
+                        bWindowChange = true;
                     break;
 
                 case VK_RETURN:
                     break;
 
                 case VK_RETURN:
@@ -1904,7 +2123,10 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             // it
                             return false;
                         }
                             // 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
                         {
                             // let IsDialogMessage() handle this for all
                             // buttons except the owner-drawn ones which it
@@ -1913,16 +2135,15 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW )
                             {
                                 // emulate the button click
                             if ( (style & BS_OWNERDRAW) == BS_OWNERDRAW )
                             {
                                 // emulate the button click
-                                wxWindow *btn = wxFindWinFromHandle((WXHWND)msg->hwnd);
+                                wxWindow *
+                                    btn = wxFindWinFromHandle((WXHWND)msg->hwnd);
                                 if ( btn )
                                     btn->MSWCommand(BN_CLICKED, 0 /* unused */);
                             }
 
                             bProcess = false;
                         }
                                 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(),
                         {
 #if wxUSE_BUTTON
                             wxButton *btn = wxDynamicCast(GetDefaultItem(),
@@ -1937,6 +2158,12 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             else // no default button
 #endif // wxUSE_BUTTON
                             {
                             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) )
                                 // this is a quick and dirty test for a text
                                 // control
                                 if ( !(lDlgCode & DLGC_HASSETSEL) )
@@ -1975,6 +2202,11 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                 if ( GetEventHandler()->ProcessEvent(event) )
                 {
 
                 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;
                 }
             }
                     return true;
                 }
             }
@@ -1988,7 +2220,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
         {
             // ::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
             // then
 
             // assume we can call it by default
@@ -2009,7 +2241,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 #if !defined(__WXWINCE__)
             if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
             {
 #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;
                 canSafelyCallIsDlgMsg = false;
                 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
                       node;
@@ -2074,7 +2306,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         // relay mouse move events to the tooltip control
         MSG *msg = (MSG *)pMsg;
         if ( msg->message == WM_MOUSEMOVE )
         // relay mouse move events to the tooltip control
         MSG *msg = (MSG *)pMsg;
         if ( msg->message == WM_MOUSEMOVE )
-            m_tooltip->RelayEvent(pMsg);
+            wxToolTip::RelayEvent(pMsg);
     }
 #endif // wxUSE_TOOLTIPS
 
     }
 #endif // wxUSE_TOOLTIPS
 
@@ -2184,7 +2416,7 @@ LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM w
 
     LRESULT rc;
 
 
     LRESULT rc;
 
-    if ( wnd )
+    if ( wnd && wxEventLoop::AllowProcessing(wnd) )
         rc = wnd->MSWWindowProc(message, wParam, lParam);
     else
         rc = ::DefWindowProc(hWnd, message, wParam, lParam);
         rc = wnd->MSWWindowProc(message, wParam, lParam);
     else
         rc = ::DefWindowProc(hWnd, message, wParam, lParam);
@@ -2301,55 +2533,34 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             processed = HandleKillFocus((WXHWND)(HWND)wParam);
             break;
 
             processed = HandleKillFocus((WXHWND)(HWND)wParam);
             break;
 
-        case WM_PAINT:
-            {
-                if ( wParam )
-                {
-                    // cast to wxWindow is needed for wxUniv
-                    wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
-                    processed = HandlePaint();
-                }
-                else
-                {
-                    processed = HandlePaint();
-                }
-                break;
-            }
-
-#ifdef WM_PRINT
         case WM_PRINTCLIENT:
         case WM_PRINTCLIENT:
-            if ( GetParent() &&
-                  GetParent()->MSWPrintChild((wxWindow *)this, wParam, lParam) )
-            {
-                processed = true;
-            }
+            processed = HandlePrintClient((WXHDC)wParam);
             break;
 
             break;
 
-        case WM_PRINT:
+        case WM_PAINT:
+            if ( wParam )
             {
             {
-                if ( lParam & PRF_ERASEBKGND )
-                    HandleEraseBkgnd((WXHDC)(HDC)wParam);
-
                 wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
 
                 processed = HandlePaint();
             }
                 wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
 
                 processed = HandlePaint();
             }
+            else // no DC given
+            {
+                processed = HandlePaint();
+            }
             break;
             break;
-#endif // WM_PRINT
 
         case WM_CLOSE:
 #ifdef __WXUNIVERSAL__
             // Universal uses its own wxFrame/wxDialog, so we don't receive
             // close events unless we have this.
             Close();
 
         case WM_CLOSE:
 #ifdef __WXUNIVERSAL__
             // Universal uses its own wxFrame/wxDialog, so we don't receive
             // close events unless we have this.
             Close();
-            processed = true;
-            rc.result = TRUE;
-#else
+#endif // __WXUNIVERSAL__
+
             // don't let the DefWindowProc() destroy our window - we'll do it
             // ourselves in ~wxWindow
             processed = true;
             rc.result = TRUE;
             // don't let the DefWindowProc() destroy our window - we'll do it
             // ourselves in ~wxWindow
             processed = true;
             rc.result = TRUE;
-#endif
             break;
 
         case WM_SHOWWINDOW:
             break;
 
         case WM_SHOWWINDOW:
@@ -2418,8 +2629,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
+#ifdef __WXWINCE__
                 // redirect the event to a static control if necessary by
                 // redirect the event to a static control if necessary by
-                // finding one under mouse
+                // finding one under mouse because under CE the static controls
+                // don't generate mouse events (even with SS_NOTIFY)
                 wxWindowMSW *win;
                 if ( GetCapture() == this )
                 {
                 wxWindowMSW *win;
                 if ( GetCapture() == this )
                 {
@@ -2435,6 +2648,39 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
                 }
                     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);
 
 
                 processed = win->HandleMouseEvent(message, x, y, wParam);
 
@@ -2553,7 +2799,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             {
                 switch ( wParam )
                 {
             {
                 switch ( wParam )
                 {
-                    // we consider these message "not interesting" to OnChar, so
+                    // we consider these messages "not interesting" to OnChar, so
                     // just don't do anything more with them
                     case VK_SHIFT:
                     case VK_CONTROL:
                     // just don't do anything more with them
                     case VK_SHIFT:
                     case VK_CONTROL:
@@ -2576,6 +2822,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     case VK_SUBTRACT:
                     case VK_MULTIPLY:
                     case VK_DIVIDE:
                     case VK_SUBTRACT:
                     case VK_MULTIPLY:
                     case VK_DIVIDE:
+                    case VK_NUMPAD0:
+                    case VK_NUMPAD1:
+                    case VK_NUMPAD2:
+                    case VK_NUMPAD3:
+                    case VK_NUMPAD4:
+                    case VK_NUMPAD5:
+                    case VK_NUMPAD6:
+                    case VK_NUMPAD7:
+                    case VK_NUMPAD8:
+                    case VK_NUMPAD9:
                     case VK_OEM_1:
                     case VK_OEM_2:
                     case VK_OEM_3:
                     case VK_OEM_1:
                     case VK_OEM_2:
                     case VK_OEM_3:
@@ -2699,6 +2955,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
             break;
 
             processed = HandleCaptureChanged((WXHWND) (HWND) lParam);
             break;
 
+        case WM_SETTINGCHANGE:
+            processed = HandleSettingChange(wParam, lParam);
+            break;
+
         case WM_QUERYNEWPALETTE:
             processed = HandleQueryNewPalette();
             break;
         case WM_QUERYNEWPALETTE:
             processed = HandleQueryNewPalette();
             break;
@@ -2773,50 +3033,48 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 #if defined(WM_HELP)
         case WM_HELP:
             {
 #if defined(WM_HELP)
         case WM_HELP:
             {
-                // HELPINFO doesn't seem to be supported on WinCE.
+                // by default, WM_HELP is propagated by DefWindowProc() upwards
+                // to the window parent but as we do it ourselves already
+                // (wxHelpEvent is derived from wxCommandEvent), we don't want
+                // to get the other events if we process this message at all
+                processed = true;
+
+                // WM_HELP doesn't use lParam under CE
 #ifndef __WXWINCE__
                 HELPINFO* info = (HELPINFO*) lParam;
 #ifndef __WXWINCE__
                 HELPINFO* info = (HELPINFO*) lParam;
-                // Don't yet process menu help events, just windows
-                if (info->iContextType == HELPINFO_WINDOW)
+                if ( info->iContextType == HELPINFO_WINDOW )
                 {
                 {
-#endif
-                    wxWindowMSW* subjectOfHelp = this;
-                    bool eventProcessed = false;
-                    while (subjectOfHelp && !eventProcessed)
-                    {
-                        wxHelpEvent helpEvent(wxEVT_HELP,
-                                              subjectOfHelp->GetId(),
+#endif // !__WXWINCE__
+                    wxHelpEvent helpEvent
+                                (
+                                    wxEVT_HELP,
+                                    GetId(),
 #ifdef __WXWINCE__
 #ifdef __WXWINCE__
-                                              wxPoint(0,0)
+                                    wxGetMousePosition() // what else?
 #else
 #else
-                                              wxPoint(info->MousePos.x, info->MousePos.y)
+                                    wxPoint(info->MousePos.x, info->MousePos.y)
 #endif
 #endif
-                                              );
-
-                        helpEvent.SetEventObject(this);
-                        eventProcessed =
-                            GetEventHandler()->ProcessEvent(helpEvent);
-
-                        // Go up the window hierarchy until the event is
-                        // handled (or not)
-                        subjectOfHelp = subjectOfHelp->GetParent();
-                    }
+                                );
 
 
-                    processed = eventProcessed;
+                    helpEvent.SetEventObject(this);
+                    GetEventHandler()->ProcessEvent(helpEvent);
 #ifndef __WXWINCE__
                 }
 #ifndef __WXWINCE__
                 }
-                else if (info->iContextType == HELPINFO_MENUITEM)
+                else if ( info->iContextType == HELPINFO_MENUITEM )
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
                 {
                     wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId);
                     helpEvent.SetEventObject(this);
-                    processed = GetEventHandler()->ProcessEvent(helpEvent);
+                    GetEventHandler()->ProcessEvent(helpEvent);
 
                 }
 
                 }
-                //else: processed is already false
-#endif
+                else // unknown help event?
+                {
+                    processed = false;
+                }
+#endif // !__WXWINCE__
             }
             break;
             }
             break;
-#endif
+#endif // WM_HELP
 
 #if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
 
 #if !defined(__WXWINCE__)
         case WM_CONTEXTMENU:
@@ -2857,6 +3115,16 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
                 }
             }
             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 )
     }
 
     if ( !processed )
@@ -3073,8 +3341,6 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
-#ifdef __WIN95__
-
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
@@ -3158,7 +3424,7 @@ bool wxWindowMSW::HandleTooltipNotify(WXUINT code,
         // Truncate tooltip length if needed as otherwise we might not have
         // enough space for it in the buffer and MultiByteToWideChar() would
         // return an error
         // Truncate tooltip length if needed as otherwise we might not have
         // enough space for it in the buffer and MultiByteToWideChar() would
         // return an error
-        size_t tipLength = wxMin(ttip.Len(), WXSIZEOF(buf) - 1);
+        size_t tipLength = wxMin(ttip.length(), WXSIZEOF(buf) - 1);
 
         // Convert to WideChar without adding the NULL character. The NULL
         // character is added afterwards (this is more efficient).
 
         // Convert to WideChar without adding the NULL character. The NULL
         // character is added afterwards (this is more efficient).
@@ -3218,8 +3484,6 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
     return false;
 }
 
     return false;
 }
 
-#endif // __WIN95__
-
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
@@ -3277,7 +3541,8 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 // window creation/destruction
 // ---------------------------------------------------------------------------
 
 // window creation/destruction
 // ---------------------------------------------------------------------------
 
-bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
+bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT WXUNUSED_IN_WINCE(cs),
+                               bool *mayCreate)
 {
     // VZ: why is this commented out for WinCE? If it doesn't support
     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally,
 {
     // VZ: why is this commented out for WinCE? If it doesn't support
     //     WS_EX_CONTROLPARENT at all it should be somehow handled globally,
@@ -3285,14 +3550,8 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
 #ifndef __WXWINCE__
     if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
         EnsureParentHasControlParentStyle(GetParent());
 #ifndef __WXWINCE__
     if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
         EnsureParentHasControlParentStyle(GetParent());
-#else
-    wxUnusedVar(cs);
 #endif // !__WXWINCE__
 
 #endif // !__WXWINCE__
 
-    // TODO: should generate this event from WM_NCCREATE
-    wxWindowCreateEvent event((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(event);
-
     *mayCreate = true;
 
     return true;
     *mayCreate = true;
 
     return true;
@@ -3409,6 +3668,20 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     return GetEventHandler()->ProcessEvent(event);
 }
 
     return GetEventHandler()->ProcessEvent(event);
 }
 
+// ---------------------------------------------------------------------------
+// labels
+// ---------------------------------------------------------------------------
+
+void wxWindowMSW::SetLabel( const wxString& label)
+{
+    SetWindowText(GetHwnd(), label.c_str());
+}
+
+wxString wxWindowMSW::GetLabel() const
+{
+    return wxGetWindowText(GetHWND());
+}
+
 // ---------------------------------------------------------------------------
 // miscellaneous
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // miscellaneous
 // ---------------------------------------------------------------------------
@@ -3494,7 +3767,11 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     // first ask the user code - it may wish to set the cursor in some very
     // specific way (for example, depending on the current position)
     POINT pt;
     // first ask the user code - it may wish to set the cursor in some very
     // specific way (for example, depending on the current position)
     POINT pt;
+#ifdef __WXWINCE__
+    if ( !::GetCursorPosWinCE(&pt))
+#else
     if ( !::GetCursorPos(&pt) )
     if ( !::GetCursorPos(&pt) )
+#endif
     {
         wxLogLastError(wxT("GetCursorPos"));
     }
     {
         wxLogLastError(wxT("GetCursorPos"));
     }
@@ -3555,6 +3832,69 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
     return false;
 }
 
     return false;
 }
 
+bool wxWindowMSW::HandlePower(WXWPARAM WXUNUSED_IN_WINCE(wParam),
+                              WXLPARAM WXUNUSED(lParam),
+                              bool *WXUNUSED_IN_WINCE(vetoed))
+{
+#ifdef __WXWINCE__
+    // FIXME
+    return false;
+#else
+    wxEventType evtType;
+    switch ( wParam )
+    {
+        case PBT_APMQUERYSUSPEND:
+            evtType = wxEVT_POWER_SUSPENDING;
+            break;
+
+        case PBT_APMQUERYSUSPENDFAILED:
+            evtType = wxEVT_POWER_SUSPEND_CANCEL;
+            break;
+
+        case PBT_APMSUSPEND:
+            evtType = wxEVT_POWER_SUSPENDED;
+            break;
+
+        case PBT_APMRESUMESUSPEND:
+#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
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // owner drawn stuff
 // ---------------------------------------------------------------------------
@@ -3579,7 +3919,11 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
-        wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+        // see comment before the same test in MSWOnMeasureItem() below
+        if ( !pMenuItem )
+            return false;
+
+        wxCHECK_MSG( wxDynamicCast(pMenuItem, wxMenuItem),
                          false, _T("MSWOnDrawItem: bad wxMenuItem pointer") );
 
         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
                          false, _T("MSWOnDrawItem: bad wxMenuItem pointer") );
 
         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
@@ -3637,7 +3981,15 @@ wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
-        wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+        // according to Carsten Fuchs the pointer may be NULL under XP if an
+        // MDI child frame is initially maximized, see this for more info:
+        // http://article.gmane.org/gmane.comp.lib.wxwidgets.general/27745
+        //
+        // so silently ignore it instead of asserting
+        if ( !pMenuItem )
+            return false;
+
+        wxCHECK_MSG( wxDynamicCast(pMenuItem, wxMenuItem),
                         false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") );
 
         size_t w, h;
                         false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") );
 
         size_t w, h;
@@ -3688,12 +4040,16 @@ bool wxWindowMSW::HandleDisplayChange()
 
 #ifndef __WXMICROWIN__
 
 
 #ifndef __WXMICROWIN__
 
-bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
+bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC hDC, WXHWND hWnd)
 {
 {
-#if wxUSE_CONTROLS
-    wxWindow *item = FindItemByHWND(pWnd, true);
+#if !wxUSE_CONTROLS || defined(__WXUNIVERSAL__)
+    wxUnusedVar(hDC);
+    wxUnusedVar(hWnd);
+#else
+    wxControl *item = wxDynamicCast(FindItemByHWND(hWnd, true), wxControl);
+
     if ( item )
     if ( item )
-        *brush = item->MSWControlColor(pDC);
+        *brush = item->MSWControlColor(hDC, hWnd);
     else
 #endif // wxUSE_CONTROLS
         *brush = NULL;
     else
 #endif // wxUSE_CONTROLS
         *brush = NULL;
@@ -3703,11 +4059,6 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
 
 #endif // __WXMICROWIN__
 
 
 #endif // __WXMICROWIN__
 
-WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC))
-{
-    return (WXHBRUSH)0;
-}
-
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
 #if wxUSE_PALETTE
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
 #if wxUSE_PALETTE
@@ -3759,6 +4110,30 @@ bool wxWindowMSW::HandleCaptureChanged(WXHWND hWndGainedCapture)
     return GetEventHandler()->ProcessEvent(event);
 }
 
     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()
 {
 
 bool wxWindowMSW::HandleQueryNewPalette()
 {
 
@@ -3837,6 +4212,7 @@ extern wxCOLORMAP *wxGetStdColourMap()
             // we want to avoid Windows' "help" and for this we need to have a
             // reference bitmap which can tell us what the RGB values change
             // to.
             // we want to avoid Windows' "help" and for this we need to have a
             // reference bitmap which can tell us what the RGB values change
             // to.
+            wxLogNull logNo; // suppress error if we couldn't load the bitmap
             wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
             if ( stdColourBitmap.Ok() )
             {
             wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
             if ( stdColourBitmap.Ok() )
             {
@@ -3934,14 +4310,11 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
     dc.SetHDC(hdc);
     dc.SetWindow((wxWindow *)this);
 
     dc.SetHDC(hdc);
     dc.SetWindow((wxWindow *)this);
-    dc.BeginDrawing();
 
     wxEraseEvent event(m_windowId, &dc);
     event.SetEventObject(this);
     bool rc = GetEventHandler()->ProcessEvent(event);
 
 
     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);
 
     // must be called manually as ~wxDC doesn't do anything for wxDCTemp
     dc.SelectOldObjects(hdc);
 
@@ -3969,92 +4342,78 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 
 
     // do default background painting
 
 
     // do default background painting
-    if ( !DoEraseBackground(*event.GetDC()) )
+    if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) )
     {
         // let the system paint the background
         event.Skip();
     }
 }
 
     {
         // let the system paint the background
         event.Skip();
     }
 }
 
-bool wxWindowMSW::DoEraseBackground(wxDC& dc)
+bool wxWindowMSW::DoEraseBackground(WXHDC hDC)
 {
 {
-    HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
-    if ( !hBrush )
+    HBRUSH hbr = (HBRUSH)MSWGetBgBrush(hDC);
+    if ( !hbr )
         return false;
 
         return false;
 
-    RECT rc;
-    ::GetClientRect(GetHwnd(), &rc);
-    ::FillRect(GetHdcOf(dc), &rc, hBrush);
+    wxFillRect(GetHwnd(), (HDC)hDC, hbr);
 
     return true;
 }
 
 
     return true;
 }
 
-WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
-{
-    wxColour col = MSWGetBgColourForChild(child);
-    if ( col.Ok() )
-    {
-        // draw children with the same colour as the parent
-        wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
-
-        return (WXHBRUSH)brush->GetResourceHandle();
-    }
-
-    return 0;
-}
-
-wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow *child)
+WXHBRUSH
+wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), WXHWND hWnd)
 {
     if ( m_hasBgCol )
     {
         // our background colour applies to:
         //  1. this window itself, always
         //  2. all children unless the colour is "not inheritable"
 {
     if ( m_hasBgCol )
     {
         // our background colour applies to:
         //  1. this window itself, always
         //  2. all children unless the colour is "not inheritable"
-        //  3. immediate transparent children which should show the same
-        //     background as we do, but not for transparent grandchildren
-        //     which use the background of their immediate parent instead
-        if ( m_inheritBgCol ||
-                child == this ||
-                    (child->HasTransparentBackground() &&
-                        child->GetParent() == this) )
+        //  3. even if it is not inheritable, our immediate transparent
+        //     children should still inherit it -- but not any transparent
+        //     children because it would look wrong if a child of non
+        //     transparent child would show our bg colour when the child itself
+        //     does not
+        wxWindow *win = wxFindWinFromHandle(hWnd);
+        if ( win == this ||
+                m_inheritBgCol ||
+                    (win && win->HasTransparentBackground() &&
+                        win->GetParent() == this) )
         {
         {
-            return GetBackgroundColour();
+            // draw children with the same colour as the parent
+            wxBrush *
+                brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour());
+
+            return (WXHBRUSH)GetHbrushOf(*brush);
         }
     }
 
         }
     }
 
-    return wxNullColour;
+    return 0;
 }
 
 }
 
-WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, WXHWND hWndToPaint)
 {
 {
-    return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
-}
+    if ( !hWndToPaint )
+        hWndToPaint = GetHWND();
 
 
-WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
-{
-    for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() )
+    for ( wxWindowMSW *win = this; win; win = win->GetParent() )
     {
     {
-        WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC);
+        WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, hWndToPaint);
         if ( hBrush )
             return hBrush;
 
         if ( hBrush )
             return hBrush;
 
-        // background is not inherited beyond the windows which have their own
-        // fixed background such as top level windows and notebooks and for
-        // windows for which a custom colour had been explicitly set with
-        // SetOwnBackgroundColour() and so shouldn't affect its children
-        if ( win->ProvidesBackground() ||
-                (win->UseBgCol() && !win->InheritsBackgroundColour()) )
+        // background is not inherited beyond top level windows
+        if ( win->IsTopLevel() )
             break;
     }
 
     return 0;
 }
 
             break;
     }
 
     return 0;
 }
 
-bool
-wxWindowMSW::MSWPrintChild(wxWindow * WXUNUSED(win),
-                           WXWPARAM WXUNUSED(wParam),
-                           WXLPARAM WXUNUSED(lParam))
+bool wxWindowMSW::HandlePrintClient(WXHDC WXUNUSED(hDC))
 {
 {
+    // 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;
 }
 
     return false;
 }
 
@@ -4100,17 +4459,34 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
+#if USE_DEFERRED_SIZING
     // when we resize this window, its children are probably going to be
     // repositioned as well, prepare to use DeferWindowPos() for them
     // when we resize this window, its children are probably going to be
     // repositioned as well, prepare to use DeferWindowPos() for them
-    const int numChildren = GetChildren().GetCount();
+    int numChildren = 0;
+    for ( HWND child = ::GetWindow(GetHwndOf(this), GW_CHILD);
+          child;
+          child = ::GetWindow(child, GW_HWNDNEXT) )
+    {
+        numChildren ++;
+    }
+
+    // Protect against valid m_hDWP being overwritten
+    bool useDefer = false;
+
     if ( numChildren > 1 )
     {
     if ( numChildren > 1 )
     {
-        m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
-        if ( !m_hDWP )
+        if (!m_hDWP)
         {
         {
-            wxLogLastError(_T("BeginDeferWindowPos"));
+            m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
+            if ( !m_hDWP )
+            {
+                wxLogLastError(_T("BeginDeferWindowPos"));
+            }
+            if (m_hDWP)
+                useDefer = true;
         }
     }
         }
     }
+#endif // USE_DEFERRED_SIZING
 
     // update this window size
     bool processed = false;
 
     // update this window size
     bool processed = false;
@@ -4143,8 +4519,9 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
             processed = GetEventHandler()->ProcessEvent(event);
     }
 
             processed = GetEventHandler()->ProcessEvent(event);
     }
 
+#if USE_DEFERRED_SIZING
     // and finally change the positions of all child windows at once
     // and finally change the positions of all child windows at once
-    if ( m_hDWP )
+    if ( useDefer && m_hDWP )
     {
         // reset m_hDWP to NULL so that child windows don't try to use our
         // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't
     {
         // reset m_hDWP to NULL so that child windows don't try to use our
         // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't
@@ -4158,7 +4535,18 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
         {
             wxLogLastError(_T("EndDeferWindowPos"));
         }
         {
             wxLogLastError(_T("EndDeferWindowPos"));
         }
+
+        // Reset our children's pending pos/size values.
+        for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
+              node;
+              node = node->GetNext() )
+        {
+            wxWindowMSW *child = node->GetData();
+            child->m_pendingPosition = wxDefaultPosition;
+            child->m_pendingSize = wxDefaultSize;
+        }
     }
     }
+#endif // USE_DEFERRED_SIZING
 
     return processed;
 }
 
     return processed;
 }
@@ -4174,10 +4562,9 @@ bool wxWindowMSW::HandleSizing(wxRect& rect)
     return rc;
 }
 
     return rc;
 }
 
-bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
+bool wxWindowMSW::HandleGetMinMaxInfo(void *WXUNUSED_IN_WINCE(mmInfo))
 {
 #ifdef __WXWINCE__
 {
 #ifdef __WXWINCE__
-    wxUnusedVar(mmInfo);
     return false;
 #else
     MINMAXINFO *info = (MINMAXINFO *)mmInfo;
     return false;
 #else
     MINMAXINFO *info = (MINMAXINFO *)mmInfo;
@@ -4322,12 +4709,12 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX = x;
-    m_lastMouseY = y;
-    m_lastMouseEvent = event.GetEventType();
+    gs_lastMouseEvent.pos = ClientToScreen(wxPoint(x, y));
+    gs_lastMouseEvent.type = event.GetEventType();
 #endif // wxUSE_MOUSEEVENT_HACK
 }
 
 #endif // wxUSE_MOUSEEVENT_HACK
 }
 
+#ifdef __WXWINCE__
 // Windows doesn't send the mouse events to the static controls (which are
 // transparent in the sense that their WM_NCHITTEST handler returns
 // HTTRANSPARENT) at all but we want all controls to receive the mouse events
 // Windows doesn't send the mouse events to the static controls (which are
 // transparent in the sense that their WM_NCHITTEST handler returns
 // HTTRANSPARENT) at all but we want all controls to receive the mouse events
@@ -4338,7 +4725,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
 // Notice that this is not done for the mouse move events because this could
 // (would?) be too slow, but only for clicks which means that the static texts
 // still don't get move, enter nor leave events.
 // Notice that this is not done for the mouse move events because this could
 // (would?) be too slow, but only for clicks which means that the static texts
 // still don't get move, enter nor leave events.
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y)
 {
     wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
 
 {
     wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
 
@@ -4391,6 +4778,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
 
     return win;
 }
 
     return win;
 }
+#endif // __WXWINCE__
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
@@ -4448,19 +4836,36 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             (void)GetEventHandler()->ProcessEvent(event);
         }
     }
             (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
 
 #if wxUSE_MOUSEEVENT_HACK
-    // Window gets a click down message followed by a mouse move message even
-    // if position isn't changed!  We want to discard the trailing move event
-    // if x and y are the same.
-    if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN ||
-          m_lastMouseEvent == wxEVT_LEFT_DOWN ||
-          m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
-         (m_lastMouseX == x && m_lastMouseY == y) )
-    {
-        m_lastMouseEvent = wxEVT_MOTION;
+    // Windows often generates mouse events even if mouse position hasn't
+    // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576)
+    //
+    // Filter this out as it can result in unexpected behaviour compared to
+    // other platforms
+    if ( gs_lastMouseEvent.type == wxEVT_RIGHT_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_LEFT_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_MIDDLE_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_MOTION )
+    {
+        if ( ClientToScreen(wxPoint(x, y)) == gs_lastMouseEvent.pos )
+        {
+            gs_lastMouseEvent.type = wxEVT_MOTION;
 
 
-        return false;
+            return false;
+        }
     }
 #endif // wxUSE_MOUSEEVENT_HACK
 
     }
 #endif // wxUSE_MOUSEEVENT_HACK
 
@@ -4471,11 +4876,14 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
 {
 #if wxUSE_MOUSEWHEEL
 bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
 {
 #if wxUSE_MOUSEWHEEL
+    // notice that WM_MOUSEWHEEL position is in screen coords (as it's
+    // forwarded up to the parent by DefWindowProc()) and not in the client
+    // ones as all the other messages, translate them to the client coords for
+    // consistency
+    const wxPoint
+        pt = ScreenToClient(wxPoint(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
     wxMouseEvent event(wxEVT_MOUSEWHEEL);
     wxMouseEvent event(wxEVT_MOUSEWHEEL);
-    InitMouseEvent(event,
-                   GET_X_LPARAM(lParam),
-                   GET_Y_LPARAM(lParam),
-                   LOWORD(wParam));
+    InitMouseEvent(event, pt.x, pt.y, LOWORD(wParam));
     event.m_wheelRotation = (short)HIWORD(wParam);
     event.m_wheelDelta = WHEEL_DELTA;
 
     event.m_wheelRotation = (short)HIWORD(wParam);
     event.m_wheelDelta = WHEEL_DELTA;
 
@@ -4523,7 +4931,11 @@ void wxWindowMSW::GenerateMouseLeave()
         state |= MK_RBUTTON;
 
     POINT pt;
         state |= MK_RBUTTON;
 
     POINT pt;
+#ifdef __WXWINCE__
+    if ( !::GetCursorPosWinCE(&pt) )
+#else
     if ( !::GetCursorPos(&pt) )
     if ( !::GetCursorPos(&pt) )
+#endif
     {
         wxLogLastError(_T("GetCursorPos"));
     }
     {
         wxLogLastError(_T("GetCursorPos"));
     }
@@ -4570,7 +4982,11 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
 
     // translate the position to client coords
     POINT pt;
 
     // translate the position to client coords
     POINT pt;
+#ifdef __WXWINCE__
+    GetCursorPosWinCE(&pt);
+#else
     GetCursorPos(&pt);
     GetCursorPos(&pt);
+#endif
     RECT rect;
     GetWindowRect(GetHwnd(),&rect);
     pt.x -= rect.left;
     RECT rect;
     GetWindowRect(GetHwnd(),&rect);
     pt.x -= rect.left;
@@ -4589,35 +5005,14 @@ bool wxWindowMSW::HandleChar(WXWPARAM wParam, WXLPARAM lParam, bool isASCII)
     int id;
     if ( isASCII )
     {
     int id;
     if ( isASCII )
     {
-        // If 1 -> 26, translate to either special keycode or just set
-        // ctrlDown.  IOW, Ctrl-C should result in keycode == 3 and
-        // ControlDown() == true.
         id = wParam;
         id = wParam;
-        if ( (id > 0) && (id < 27) )
-        {
-            switch (id)
-            {
-                case 13:
-                    id = WXK_RETURN;
-                    break;
-
-                case 8:
-                    id = WXK_BACK;
-                    break;
-
-                case 9:
-                    id = WXK_TAB;
-                    break;
-
-                default:
-                    //ctrlDown = true;
-                    break;
-            }
-        }
     }
     else // we're called from WM_KEYDOWN
     {
     }
     else // we're called from WM_KEYDOWN
     {
-        id = wxCharCodeMSWToWX(wParam, lParam);
+        // don't pass lParam to wxCharCodeMSWToWX() here because we don't want
+        // to get numpad key codes: CHAR events should use the logical keys
+        // such as WXK_HOME instead of WXK_NUMPAD_HOME which is for KEY events
+        id = wxCharCodeMSWToWX(wParam);
         if ( id == 0 )
         {
             // it's ASCII and will be processed here only when called from
         if ( id == 0 )
         {
             // it's ASCII and will be processed here only when called from
@@ -4654,16 +5049,8 @@ bool wxWindowMSW::HandleKeyDown(WXWPARAM wParam, WXLPARAM lParam)
         id = wParam;
     }
 
         id = wParam;
     }
 
-    if ( id != -1 ) // VZ: does this ever happen (FIXME)?
-    {
-        wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
-        if ( GetEventHandler()->ProcessEvent(event) )
-        {
-            return true;
-        }
-    }
-
-    return false;
+    wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_DOWN, id, lParam, wParam));
+    return GetEventHandler()->ProcessEvent(event);
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
 }
 
 bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
@@ -4676,17 +5063,12 @@ bool wxWindowMSW::HandleKeyUp(WXWPARAM wParam, WXLPARAM lParam)
         id = wParam;
     }
 
         id = wParam;
     }
 
-    if ( id != -1 ) // VZ: does this ever happen (FIXME)?
-    {
-        wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
-        if ( GetEventHandler()->ProcessEvent(event) )
-            return true;
-    }
-
-    return false;
+    wxKeyEvent event(CreateKeyEvent(wxEVT_KEY_UP, id, lParam, wParam));
+    return GetEventHandler()->ProcessEvent(event);
 }
 
 }
 
-int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
+int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
+                                WXLPARAM WXUNUSED_IN_WINCE(lParam))
 {
     // FIXME: implement GetMenuItemCount for WinCE, possibly
     // in terms of GetMenuItemInfo
 {
     // FIXME: implement GetMenuItemCount for WinCE, possibly
     // in terms of GetMenuItemInfo
@@ -4696,12 +5078,20 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
+
+    // we could use MIIM_FTYPE here as we only need to know if the item is
+    // ownerdrawn or not and not dwTypeData which MIIM_TYPE also returns, but
+    // MIIM_FTYPE is not supported under Win95
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
+        // previous loop iteration could modify it, reset it back before
+        // calling GetMenuItemInfo() to prevent it from overflowing dwTypeData
+        mii.cch = 0;
+
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
@@ -4739,18 +5129,26 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
         }
         else // failed to get the menu text?
         {
         }
         else // failed to get the menu text?
         {
-            // it's not fatal, so don't show error, but still log
-            // it
+            // it's not fatal, so don't show error, but still log it
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
-#else
-    wxUnusedVar(chAccel);
-    wxUnusedVar(lParam);
 #endif
     return wxNOT_FOUND;
 }
 
 #endif
     return wxNOT_FOUND;
 }
 
+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
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // joystick
 // ---------------------------------------------------------------------------
@@ -4904,7 +5302,7 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
                                                               : SB_VERT,
                                   &scrollInfo) )
             {
                                                               : SB_VERT,
                                   &scrollInfo) )
             {
-                // Not neccessarily an error, if there are no scrollbars yet.
+                // Not necessarily an error, if there are no scrollbars yet.
                 // wxLogLastError(_T("GetScrollInfo"));
             }
 
                 // wxLogLastError(_T("GetScrollInfo"));
             }
 
@@ -4954,226 +5352,313 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont& the_font)
     //   the_font.ReleaseResource();
 }
 
     //   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.
 // 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
         // 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:
 
         case VK_RETURN:
-            // the same key is sent for both the "return" key on the main
-            // keyboard and the numeric keypad but we want to distinguish
-            // between them: we do this using the "extended" bit (24) of lParam
-            id = lParam & (1 << 24) ? WXK_NUMPAD_ENTER : WXK_RETURN;
+            // don't use ChooseNormalOrExtended() here as the keys are reversed
+            // here: numpad enter is the extended one
+            wxk = lParam && (lParam & (1 << 24)) ? WXK_NUMPAD_ENTER : WXK_RETURN;
             break;
 
         default:
             break;
 
         default:
-            id = 0;
-    }
-
-    return id;
-}
-
-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;
             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 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();
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
@@ -5317,413 +5802,413 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
 #endif // !__WXMICROWIN__
 
 #ifdef __WXDEBUG__
 #endif // !__WXMICROWIN__
 
 #ifdef __WXDEBUG__
-const char *wxGetMessageName(int message)
+const wxChar *wxGetMessageName(int message)
 {
     switch ( message )
     {
 {
     switch ( message )
     {
-        case 0x0000: return "WM_NULL";
-        case 0x0001: return "WM_CREATE";
-        case 0x0002: return "WM_DESTROY";
-        case 0x0003: return "WM_MOVE";
-        case 0x0005: return "WM_SIZE";
-        case 0x0006: return "WM_ACTIVATE";
-        case 0x0007: return "WM_SETFOCUS";
-        case 0x0008: return "WM_KILLFOCUS";
-        case 0x000A: return "WM_ENABLE";
-        case 0x000B: return "WM_SETREDRAW";
-        case 0x000C: return "WM_SETTEXT";
-        case 0x000D: return "WM_GETTEXT";
-        case 0x000E: return "WM_GETTEXTLENGTH";
-        case 0x000F: return "WM_PAINT";
-        case 0x0010: return "WM_CLOSE";
-        case 0x0011: return "WM_QUERYENDSESSION";
-        case 0x0012: return "WM_QUIT";
-        case 0x0013: return "WM_QUERYOPEN";
-        case 0x0014: return "WM_ERASEBKGND";
-        case 0x0015: return "WM_SYSCOLORCHANGE";
-        case 0x0016: return "WM_ENDSESSION";
-        case 0x0017: return "WM_SYSTEMERROR";
-        case 0x0018: return "WM_SHOWWINDOW";
-        case 0x0019: return "WM_CTLCOLOR";
-        case 0x001A: return "WM_WININICHANGE";
-        case 0x001B: return "WM_DEVMODECHANGE";
-        case 0x001C: return "WM_ACTIVATEAPP";
-        case 0x001D: return "WM_FONTCHANGE";
-        case 0x001E: return "WM_TIMECHANGE";
-        case 0x001F: return "WM_CANCELMODE";
-        case 0x0020: return "WM_SETCURSOR";
-        case 0x0021: return "WM_MOUSEACTIVATE";
-        case 0x0022: return "WM_CHILDACTIVATE";
-        case 0x0023: return "WM_QUEUESYNC";
-        case 0x0024: return "WM_GETMINMAXINFO";
-        case 0x0026: return "WM_PAINTICON";
-        case 0x0027: return "WM_ICONERASEBKGND";
-        case 0x0028: return "WM_NEXTDLGCTL";
-        case 0x002A: return "WM_SPOOLERSTATUS";
-        case 0x002B: return "WM_DRAWITEM";
-        case 0x002C: return "WM_MEASUREITEM";
-        case 0x002D: return "WM_DELETEITEM";
-        case 0x002E: return "WM_VKEYTOITEM";
-        case 0x002F: return "WM_CHARTOITEM";
-        case 0x0030: return "WM_SETFONT";
-        case 0x0031: return "WM_GETFONT";
-        case 0x0037: return "WM_QUERYDRAGICON";
-        case 0x0039: return "WM_COMPAREITEM";
-        case 0x0041: return "WM_COMPACTING";
-        case 0x0044: return "WM_COMMNOTIFY";
-        case 0x0046: return "WM_WINDOWPOSCHANGING";
-        case 0x0047: return "WM_WINDOWPOSCHANGED";
-        case 0x0048: return "WM_POWER";
-
-        case 0x004A: return "WM_COPYDATA";
-        case 0x004B: return "WM_CANCELJOURNAL";
-        case 0x004E: return "WM_NOTIFY";
-        case 0x0050: return "WM_INPUTLANGCHANGEREQUEST";
-        case 0x0051: return "WM_INPUTLANGCHANGE";
-        case 0x0052: return "WM_TCARD";
-        case 0x0053: return "WM_HELP";
-        case 0x0054: return "WM_USERCHANGED";
-        case 0x0055: return "WM_NOTIFYFORMAT";
-        case 0x007B: return "WM_CONTEXTMENU";
-        case 0x007C: return "WM_STYLECHANGING";
-        case 0x007D: return "WM_STYLECHANGED";
-        case 0x007E: return "WM_DISPLAYCHANGE";
-        case 0x007F: return "WM_GETICON";
-        case 0x0080: return "WM_SETICON";
-
-        case 0x0081: return "WM_NCCREATE";
-        case 0x0082: return "WM_NCDESTROY";
-        case 0x0083: return "WM_NCCALCSIZE";
-        case 0x0084: return "WM_NCHITTEST";
-        case 0x0085: return "WM_NCPAINT";
-        case 0x0086: return "WM_NCACTIVATE";
-        case 0x0087: return "WM_GETDLGCODE";
-        case 0x00A0: return "WM_NCMOUSEMOVE";
-        case 0x00A1: return "WM_NCLBUTTONDOWN";
-        case 0x00A2: return "WM_NCLBUTTONUP";
-        case 0x00A3: return "WM_NCLBUTTONDBLCLK";
-        case 0x00A4: return "WM_NCRBUTTONDOWN";
-        case 0x00A5: return "WM_NCRBUTTONUP";
-        case 0x00A6: return "WM_NCRBUTTONDBLCLK";
-        case 0x00A7: return "WM_NCMBUTTONDOWN";
-        case 0x00A8: return "WM_NCMBUTTONUP";
-        case 0x00A9: return "WM_NCMBUTTONDBLCLK";
-        case 0x0100: return "WM_KEYDOWN";
-        case 0x0101: return "WM_KEYUP";
-        case 0x0102: return "WM_CHAR";
-        case 0x0103: return "WM_DEADCHAR";
-        case 0x0104: return "WM_SYSKEYDOWN";
-        case 0x0105: return "WM_SYSKEYUP";
-        case 0x0106: return "WM_SYSCHAR";
-        case 0x0107: return "WM_SYSDEADCHAR";
-        case 0x0108: return "WM_KEYLAST";
-
-        case 0x010D: return "WM_IME_STARTCOMPOSITION";
-        case 0x010E: return "WM_IME_ENDCOMPOSITION";
-        case 0x010F: return "WM_IME_COMPOSITION";
-
-        case 0x0110: return "WM_INITDIALOG";
-        case 0x0111: return "WM_COMMAND";
-        case 0x0112: return "WM_SYSCOMMAND";
-        case 0x0113: return "WM_TIMER";
-        case 0x0114: return "WM_HSCROLL";
-        case 0x0115: return "WM_VSCROLL";
-        case 0x0116: return "WM_INITMENU";
-        case 0x0117: return "WM_INITMENUPOPUP";
-        case 0x011F: return "WM_MENUSELECT";
-        case 0x0120: return "WM_MENUCHAR";
-        case 0x0121: return "WM_ENTERIDLE";
-        case 0x0200: return "WM_MOUSEMOVE";
-        case 0x0201: return "WM_LBUTTONDOWN";
-        case 0x0202: return "WM_LBUTTONUP";
-        case 0x0203: return "WM_LBUTTONDBLCLK";
-        case 0x0204: return "WM_RBUTTONDOWN";
-        case 0x0205: return "WM_RBUTTONUP";
-        case 0x0206: return "WM_RBUTTONDBLCLK";
-        case 0x0207: return "WM_MBUTTONDOWN";
-        case 0x0208: return "WM_MBUTTONUP";
-        case 0x0209: return "WM_MBUTTONDBLCLK";
-        case 0x020A: return "WM_MOUSEWHEEL";
-        case 0x0210: return "WM_PARENTNOTIFY";
-        case 0x0211: return "WM_ENTERMENULOOP";
-        case 0x0212: return "WM_EXITMENULOOP";
-
-        case 0x0213: return "WM_NEXTMENU";
-        case 0x0214: return "WM_SIZING";
-        case 0x0215: return "WM_CAPTURECHANGED";
-        case 0x0216: return "WM_MOVING";
-        case 0x0218: return "WM_POWERBROADCAST";
-        case 0x0219: return "WM_DEVICECHANGE";
-
-        case 0x0220: return "WM_MDICREATE";
-        case 0x0221: return "WM_MDIDESTROY";
-        case 0x0222: return "WM_MDIACTIVATE";
-        case 0x0223: return "WM_MDIRESTORE";
-        case 0x0224: return "WM_MDINEXT";
-        case 0x0225: return "WM_MDIMAXIMIZE";
-        case 0x0226: return "WM_MDITILE";
-        case 0x0227: return "WM_MDICASCADE";
-        case 0x0228: return "WM_MDIICONARRANGE";
-        case 0x0229: return "WM_MDIGETACTIVE";
-        case 0x0230: return "WM_MDISETMENU";
-        case 0x0233: return "WM_DROPFILES";
-
-        case 0x0281: return "WM_IME_SETCONTEXT";
-        case 0x0282: return "WM_IME_NOTIFY";
-        case 0x0283: return "WM_IME_CONTROL";
-        case 0x0284: return "WM_IME_COMPOSITIONFULL";
-        case 0x0285: return "WM_IME_SELECT";
-        case 0x0286: return "WM_IME_CHAR";
-        case 0x0290: return "WM_IME_KEYDOWN";
-        case 0x0291: return "WM_IME_KEYUP";
-
-        case 0x0300: return "WM_CUT";
-        case 0x0301: return "WM_COPY";
-        case 0x0302: return "WM_PASTE";
-        case 0x0303: return "WM_CLEAR";
-        case 0x0304: return "WM_UNDO";
-        case 0x0305: return "WM_RENDERFORMAT";
-        case 0x0306: return "WM_RENDERALLFORMATS";
-        case 0x0307: return "WM_DESTROYCLIPBOARD";
-        case 0x0308: return "WM_DRAWCLIPBOARD";
-        case 0x0309: return "WM_PAINTCLIPBOARD";
-        case 0x030A: return "WM_VSCROLLCLIPBOARD";
-        case 0x030B: return "WM_SIZECLIPBOARD";
-        case 0x030C: return "WM_ASKCBFORMATNAME";
-        case 0x030D: return "WM_CHANGECBCHAIN";
-        case 0x030E: return "WM_HSCROLLCLIPBOARD";
-        case 0x030F: return "WM_QUERYNEWPALETTE";
-        case 0x0310: return "WM_PALETTEISCHANGING";
-        case 0x0311: return "WM_PALETTECHANGED";
+        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
 #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
 #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
 
         // tree view
-        case 0x1100 + 0: return "TVM_INSERTITEMA";
-        case 0x1100 + 50: return "TVM_INSERTITEMW";
-        case 0x1100 + 1: return "TVM_DELETEITEM";
-        case 0x1100 + 2: return "TVM_EXPAND";
-        case 0x1100 + 4: return "TVM_GETITEMRECT";
-        case 0x1100 + 5: return "TVM_GETCOUNT";
-        case 0x1100 + 6: return "TVM_GETINDENT";
-        case 0x1100 + 7: return "TVM_SETINDENT";
-        case 0x1100 + 8: return "TVM_GETIMAGELIST";
-        case 0x1100 + 9: return "TVM_SETIMAGELIST";
-        case 0x1100 + 10: return "TVM_GETNEXTITEM";
-        case 0x1100 + 11: return "TVM_SELECTITEM";
-        case 0x1100 + 12: return "TVM_GETITEMA";
-        case 0x1100 + 62: return "TVM_GETITEMW";
-        case 0x1100 + 13: return "TVM_SETITEMA";
-        case 0x1100 + 63: return "TVM_SETITEMW";
-        case 0x1100 + 14: return "TVM_EDITLABELA";
-        case 0x1100 + 65: return "TVM_EDITLABELW";
-        case 0x1100 + 15: return "TVM_GETEDITCONTROL";
-        case 0x1100 + 16: return "TVM_GETVISIBLECOUNT";
-        case 0x1100 + 17: return "TVM_HITTEST";
-        case 0x1100 + 18: return "TVM_CREATEDRAGIMAGE";
-        case 0x1100 + 19: return "TVM_SORTCHILDREN";
-        case 0x1100 + 20: return "TVM_ENSUREVISIBLE";
-        case 0x1100 + 21: return "TVM_SORTCHILDRENCB";
-        case 0x1100 + 22: return "TVM_ENDEDITLABELNOW";
-        case 0x1100 + 23: return "TVM_GETISEARCHSTRINGA";
-        case 0x1100 + 64: return "TVM_GETISEARCHSTRINGW";
-        case 0x1100 + 24: return "TVM_SETTOOLTIPS";
-        case 0x1100 + 25: return "TVM_GETTOOLTIPS";
+        case 0x1100 + 0: return wxT("TVM_INSERTITEMA");
+        case 0x1100 + 50: return wxT("TVM_INSERTITEMW");
+        case 0x1100 + 1: return wxT("TVM_DELETEITEM");
+        case 0x1100 + 2: return wxT("TVM_EXPAND");
+        case 0x1100 + 4: return wxT("TVM_GETITEMRECT");
+        case 0x1100 + 5: return wxT("TVM_GETCOUNT");
+        case 0x1100 + 6: return wxT("TVM_GETINDENT");
+        case 0x1100 + 7: return wxT("TVM_SETINDENT");
+        case 0x1100 + 8: return wxT("TVM_GETIMAGELIST");
+        case 0x1100 + 9: return wxT("TVM_SETIMAGELIST");
+        case 0x1100 + 10: return wxT("TVM_GETNEXTITEM");
+        case 0x1100 + 11: return wxT("TVM_SELECTITEM");
+        case 0x1100 + 12: return wxT("TVM_GETITEMA");
+        case 0x1100 + 62: return wxT("TVM_GETITEMW");
+        case 0x1100 + 13: return wxT("TVM_SETITEMA");
+        case 0x1100 + 63: return wxT("TVM_SETITEMW");
+        case 0x1100 + 14: return wxT("TVM_EDITLABELA");
+        case 0x1100 + 65: return wxT("TVM_EDITLABELW");
+        case 0x1100 + 15: return wxT("TVM_GETEDITCONTROL");
+        case 0x1100 + 16: return wxT("TVM_GETVISIBLECOUNT");
+        case 0x1100 + 17: return wxT("TVM_HITTEST");
+        case 0x1100 + 18: return wxT("TVM_CREATEDRAGIMAGE");
+        case 0x1100 + 19: return wxT("TVM_SORTCHILDREN");
+        case 0x1100 + 20: return wxT("TVM_ENSUREVISIBLE");
+        case 0x1100 + 21: return wxT("TVM_SORTCHILDRENCB");
+        case 0x1100 + 22: return wxT("TVM_ENDEDITLABELNOW");
+        case 0x1100 + 23: return wxT("TVM_GETISEARCHSTRINGA");
+        case 0x1100 + 64: return wxT("TVM_GETISEARCHSTRINGW");
+        case 0x1100 + 24: return wxT("TVM_SETTOOLTIPS");
+        case 0x1100 + 25: return wxT("TVM_GETTOOLTIPS");
 
         // header
 
         // header
-        case 0x1200 + 0: return "HDM_GETITEMCOUNT";
-        case 0x1200 + 1: return "HDM_INSERTITEMA";
-        case 0x1200 + 10: return "HDM_INSERTITEMW";
-        case 0x1200 + 2: return "HDM_DELETEITEM";
-        case 0x1200 + 3: return "HDM_GETITEMA";
-        case 0x1200 + 11: return "HDM_GETITEMW";
-        case 0x1200 + 4: return "HDM_SETITEMA";
-        case 0x1200 + 12: return "HDM_SETITEMW";
-        case 0x1200 + 5: return "HDM_LAYOUT";
-        case 0x1200 + 6: return "HDM_HITTEST";
-        case 0x1200 + 7: return "HDM_GETITEMRECT";
-        case 0x1200 + 8: return "HDM_SETIMAGELIST";
-        case 0x1200 + 9: return "HDM_GETIMAGELIST";
-        case 0x1200 + 15: return "HDM_ORDERTOINDEX";
-        case 0x1200 + 16: return "HDM_CREATEDRAGIMAGE";
-        case 0x1200 + 17: return "HDM_GETORDERARRAY";
-        case 0x1200 + 18: return "HDM_SETORDERARRAY";
-        case 0x1200 + 19: return "HDM_SETHOTDIVIDER";
+        case 0x1200 + 0: return wxT("HDM_GETITEMCOUNT");
+        case 0x1200 + 1: return wxT("HDM_INSERTITEMA");
+        case 0x1200 + 10: return wxT("HDM_INSERTITEMW");
+        case 0x1200 + 2: return wxT("HDM_DELETEITEM");
+        case 0x1200 + 3: return wxT("HDM_GETITEMA");
+        case 0x1200 + 11: return wxT("HDM_GETITEMW");
+        case 0x1200 + 4: return wxT("HDM_SETITEMA");
+        case 0x1200 + 12: return wxT("HDM_SETITEMW");
+        case 0x1200 + 5: return wxT("HDM_LAYOUT");
+        case 0x1200 + 6: return wxT("HDM_HITTEST");
+        case 0x1200 + 7: return wxT("HDM_GETITEMRECT");
+        case 0x1200 + 8: return wxT("HDM_SETIMAGELIST");
+        case 0x1200 + 9: return wxT("HDM_GETIMAGELIST");
+        case 0x1200 + 15: return wxT("HDM_ORDERTOINDEX");
+        case 0x1200 + 16: return wxT("HDM_CREATEDRAGIMAGE");
+        case 0x1200 + 17: return wxT("HDM_GETORDERARRAY");
+        case 0x1200 + 18: return wxT("HDM_SETORDERARRAY");
+        case 0x1200 + 19: return wxT("HDM_SETHOTDIVIDER");
 
         // tab control
 
         // tab control
-        case 0x1300 + 2: return "TCM_GETIMAGELIST";
-        case 0x1300 + 3: return "TCM_SETIMAGELIST";
-        case 0x1300 + 4: return "TCM_GETITEMCOUNT";
-        case 0x1300 + 5: return "TCM_GETITEMA";
-        case 0x1300 + 60: return "TCM_GETITEMW";
-        case 0x1300 + 6: return "TCM_SETITEMA";
-        case 0x1300 + 61: return "TCM_SETITEMW";
-        case 0x1300 + 7: return "TCM_INSERTITEMA";
-        case 0x1300 + 62: return "TCM_INSERTITEMW";
-        case 0x1300 + 8: return "TCM_DELETEITEM";
-        case 0x1300 + 9: return "TCM_DELETEALLITEMS";
-        case 0x1300 + 10: return "TCM_GETITEMRECT";
-        case 0x1300 + 11: return "TCM_GETCURSEL";
-        case 0x1300 + 12: return "TCM_SETCURSEL";
-        case 0x1300 + 13: return "TCM_HITTEST";
-        case 0x1300 + 14: return "TCM_SETITEMEXTRA";
-        case 0x1300 + 40: return "TCM_ADJUSTRECT";
-        case 0x1300 + 41: return "TCM_SETITEMSIZE";
-        case 0x1300 + 42: return "TCM_REMOVEIMAGE";
-        case 0x1300 + 43: return "TCM_SETPADDING";
-        case 0x1300 + 44: return "TCM_GETROWCOUNT";
-        case 0x1300 + 45: return "TCM_GETTOOLTIPS";
-        case 0x1300 + 46: return "TCM_SETTOOLTIPS";
-        case 0x1300 + 47: return "TCM_GETCURFOCUS";
-        case 0x1300 + 48: return "TCM_SETCURFOCUS";
-        case 0x1300 + 49: return "TCM_SETMINTABWIDTH";
-        case 0x1300 + 50: return "TCM_DESELECTALL";
+        case 0x1300 + 2: return wxT("TCM_GETIMAGELIST");
+        case 0x1300 + 3: return wxT("TCM_SETIMAGELIST");
+        case 0x1300 + 4: return wxT("TCM_GETITEMCOUNT");
+        case 0x1300 + 5: return wxT("TCM_GETITEMA");
+        case 0x1300 + 60: return wxT("TCM_GETITEMW");
+        case 0x1300 + 6: return wxT("TCM_SETITEMA");
+        case 0x1300 + 61: return wxT("TCM_SETITEMW");
+        case 0x1300 + 7: return wxT("TCM_INSERTITEMA");
+        case 0x1300 + 62: return wxT("TCM_INSERTITEMW");
+        case 0x1300 + 8: return wxT("TCM_DELETEITEM");
+        case 0x1300 + 9: return wxT("TCM_DELETEALLITEMS");
+        case 0x1300 + 10: return wxT("TCM_GETITEMRECT");
+        case 0x1300 + 11: return wxT("TCM_GETCURSEL");
+        case 0x1300 + 12: return wxT("TCM_SETCURSEL");
+        case 0x1300 + 13: return wxT("TCM_HITTEST");
+        case 0x1300 + 14: return wxT("TCM_SETITEMEXTRA");
+        case 0x1300 + 40: return wxT("TCM_ADJUSTRECT");
+        case 0x1300 + 41: return wxT("TCM_SETITEMSIZE");
+        case 0x1300 + 42: return wxT("TCM_REMOVEIMAGE");
+        case 0x1300 + 43: return wxT("TCM_SETPADDING");
+        case 0x1300 + 44: return wxT("TCM_GETROWCOUNT");
+        case 0x1300 + 45: return wxT("TCM_GETTOOLTIPS");
+        case 0x1300 + 46: return wxT("TCM_SETTOOLTIPS");
+        case 0x1300 + 47: return wxT("TCM_GETCURFOCUS");
+        case 0x1300 + 48: return wxT("TCM_SETCURFOCUS");
+        case 0x1300 + 49: return wxT("TCM_SETMINTABWIDTH");
+        case 0x1300 + 50: return wxT("TCM_DESELECTALL");
 
         // toolbar
 
         // toolbar
-        case WM_USER+1: return "TB_ENABLEBUTTON";
-        case WM_USER+2: return "TB_CHECKBUTTON";
-        case WM_USER+3: return "TB_PRESSBUTTON";
-        case WM_USER+4: return "TB_HIDEBUTTON";
-        case WM_USER+5: return "TB_INDETERMINATE";
-        case WM_USER+9: return "TB_ISBUTTONENABLED";
-        case WM_USER+10: return "TB_ISBUTTONCHECKED";
-        case WM_USER+11: return "TB_ISBUTTONPRESSED";
-        case WM_USER+12: return "TB_ISBUTTONHIDDEN";
-        case WM_USER+13: return "TB_ISBUTTONINDETERMINATE";
-        case WM_USER+17: return "TB_SETSTATE";
-        case WM_USER+18: return "TB_GETSTATE";
-        case WM_USER+19: return "TB_ADDBITMAP";
-        case WM_USER+20: return "TB_ADDBUTTONS";
-        case WM_USER+21: return "TB_INSERTBUTTON";
-        case WM_USER+22: return "TB_DELETEBUTTON";
-        case WM_USER+23: return "TB_GETBUTTON";
-        case WM_USER+24: return "TB_BUTTONCOUNT";
-        case WM_USER+25: return "TB_COMMANDTOINDEX";
-        case WM_USER+26: return "TB_SAVERESTOREA";
-        case WM_USER+76: return "TB_SAVERESTOREW";
-        case WM_USER+27: return "TB_CUSTOMIZE";
-        case WM_USER+28: return "TB_ADDSTRINGA";
-        case WM_USER+77: return "TB_ADDSTRINGW";
-        case WM_USER+29: return "TB_GETITEMRECT";
-        case WM_USER+30: return "TB_BUTTONSTRUCTSIZE";
-        case WM_USER+31: return "TB_SETBUTTONSIZE";
-        case WM_USER+32: return "TB_SETBITMAPSIZE";
-        case WM_USER+33: return "TB_AUTOSIZE";
-        case WM_USER+35: return "TB_GETTOOLTIPS";
-        case WM_USER+36: return "TB_SETTOOLTIPS";
-        case WM_USER+37: return "TB_SETPARENT";
-        case WM_USER+39: return "TB_SETROWS";
-        case WM_USER+40: return "TB_GETROWS";
-        case WM_USER+42: return "TB_SETCMDID";
-        case WM_USER+43: return "TB_CHANGEBITMAP";
-        case WM_USER+44: return "TB_GETBITMAP";
-        case WM_USER+45: return "TB_GETBUTTONTEXTA";
-        case WM_USER+75: return "TB_GETBUTTONTEXTW";
-        case WM_USER+46: return "TB_REPLACEBITMAP";
-        case WM_USER+47: return "TB_SETINDENT";
-        case WM_USER+48: return "TB_SETIMAGELIST";
-        case WM_USER+49: return "TB_GETIMAGELIST";
-        case WM_USER+50: return "TB_LOADIMAGES";
-        case WM_USER+51: return "TB_GETRECT";
-        case WM_USER+52: return "TB_SETHOTIMAGELIST";
-        case WM_USER+53: return "TB_GETHOTIMAGELIST";
-        case WM_USER+54: return "TB_SETDISABLEDIMAGELIST";
-        case WM_USER+55: return "TB_GETDISABLEDIMAGELIST";
-        case WM_USER+56: return "TB_SETSTYLE";
-        case WM_USER+57: return "TB_GETSTYLE";
-        case WM_USER+58: return "TB_GETBUTTONSIZE";
-        case WM_USER+59: return "TB_SETBUTTONWIDTH";
-        case WM_USER+60: return "TB_SETMAXTEXTROWS";
-        case WM_USER+61: return "TB_GETTEXTROWS";
-        case WM_USER+41: return "TB_GETBITMAPFLAGS";
+        case WM_USER+1: return wxT("TB_ENABLEBUTTON");
+        case WM_USER+2: return wxT("TB_CHECKBUTTON");
+        case WM_USER+3: return wxT("TB_PRESSBUTTON");
+        case WM_USER+4: return wxT("TB_HIDEBUTTON");
+        case WM_USER+5: return wxT("TB_INDETERMINATE");
+        case WM_USER+9: return wxT("TB_ISBUTTONENABLED");
+        case WM_USER+10: return wxT("TB_ISBUTTONCHECKED");
+        case WM_USER+11: return wxT("TB_ISBUTTONPRESSED");
+        case WM_USER+12: return wxT("TB_ISBUTTONHIDDEN");
+        case WM_USER+13: return wxT("TB_ISBUTTONINDETERMINATE");
+        case WM_USER+17: return wxT("TB_SETSTATE");
+        case WM_USER+18: return wxT("TB_GETSTATE");
+        case WM_USER+19: return wxT("TB_ADDBITMAP");
+        case WM_USER+20: return wxT("TB_ADDBUTTONS");
+        case WM_USER+21: return wxT("TB_INSERTBUTTON");
+        case WM_USER+22: return wxT("TB_DELETEBUTTON");
+        case WM_USER+23: return wxT("TB_GETBUTTON");
+        case WM_USER+24: return wxT("TB_BUTTONCOUNT");
+        case WM_USER+25: return wxT("TB_COMMANDTOINDEX");
+        case WM_USER+26: return wxT("TB_SAVERESTOREA");
+        case WM_USER+76: return wxT("TB_SAVERESTOREW");
+        case WM_USER+27: return wxT("TB_CUSTOMIZE");
+        case WM_USER+28: return wxT("TB_ADDSTRINGA");
+        case WM_USER+77: return wxT("TB_ADDSTRINGW");
+        case WM_USER+29: return wxT("TB_GETITEMRECT");
+        case WM_USER+30: return wxT("TB_BUTTONSTRUCTSIZE");
+        case WM_USER+31: return wxT("TB_SETBUTTONSIZE");
+        case WM_USER+32: return wxT("TB_SETBITMAPSIZE");
+        case WM_USER+33: return wxT("TB_AUTOSIZE");
+        case WM_USER+35: return wxT("TB_GETTOOLTIPS");
+        case WM_USER+36: return wxT("TB_SETTOOLTIPS");
+        case WM_USER+37: return wxT("TB_SETPARENT");
+        case WM_USER+39: return wxT("TB_SETROWS");
+        case WM_USER+40: return wxT("TB_GETROWS");
+        case WM_USER+42: return wxT("TB_SETCMDID");
+        case WM_USER+43: return wxT("TB_CHANGEBITMAP");
+        case WM_USER+44: return wxT("TB_GETBITMAP");
+        case WM_USER+45: return wxT("TB_GETBUTTONTEXTA");
+        case WM_USER+75: return wxT("TB_GETBUTTONTEXTW");
+        case WM_USER+46: return wxT("TB_REPLACEBITMAP");
+        case WM_USER+47: return wxT("TB_SETINDENT");
+        case WM_USER+48: return wxT("TB_SETIMAGELIST");
+        case WM_USER+49: return wxT("TB_GETIMAGELIST");
+        case WM_USER+50: return wxT("TB_LOADIMAGES");
+        case WM_USER+51: return wxT("TB_GETRECT");
+        case WM_USER+52: return wxT("TB_SETHOTIMAGELIST");
+        case WM_USER+53: return wxT("TB_GETHOTIMAGELIST");
+        case WM_USER+54: return wxT("TB_SETDISABLEDIMAGELIST");
+        case WM_USER+55: return wxT("TB_GETDISABLEDIMAGELIST");
+        case WM_USER+56: return wxT("TB_SETSTYLE");
+        case WM_USER+57: return wxT("TB_GETSTYLE");
+        case WM_USER+58: return wxT("TB_GETBUTTONSIZE");
+        case WM_USER+59: return wxT("TB_SETBUTTONWIDTH");
+        case WM_USER+60: return wxT("TB_SETMAXTEXTROWS");
+        case WM_USER+61: return wxT("TB_GETTEXTROWS");
+        case WM_USER+41: return wxT("TB_GETBITMAPFLAGS");
 
         default:
 
         default:
-            static char s_szBuf[128];
-            sprintf(s_szBuf, "<unknown message = %d>", message);
-            return s_szBuf;
+            static wxString s_szBuf;
+            s_szBuf.Printf(wxT("<unknown message = %d>"), message);
+            return s_szBuf.c_str();
     }
 }
 #endif //__WXDEBUG__
     }
 }
 #endif //__WXDEBUG__
@@ -5773,25 +6258,21 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
     POINT pt2;
     pt2.x = pt.x;
     pt2.y = pt.y;
     POINT pt2;
     pt2.x = pt.x;
     pt2.y = pt.y;
-    HWND hWndHit = ::WindowFromPoint(pt2);
 
 
-    wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ;
-    HWND hWnd = hWndHit;
+    HWND hWnd = ::WindowFromPoint(pt2);
 
 
-    // Try to find a window with a wxWindow associated with it
-    while (!win && (hWnd != 0))
-    {
-        hWnd = ::GetParent(hWnd);
-        win = wxFindWinFromHandle((WXHWND) hWnd) ;
-    }
-    return win;
+    return wxGetWindowFromHWND((WXHWND)hWnd);
 }
 
 // Get the current mouse position.
 wxPoint wxGetMousePosition()
 {
     POINT pt;
 }
 
 // Get the current mouse position.
 wxPoint wxGetMousePosition()
 {
     POINT pt;
+#ifdef __WXWINCE__
+    GetCursorPosWinCE(&pt);
+#else
     GetCursorPos( & pt );
     GetCursorPos( & pt );
+#endif
 
     return wxPoint(pt.x, pt.y);
 }
 
     return wxPoint(pt.x, pt.y);
 }
@@ -5978,4 +6459,3 @@ void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event )
     event.Skip();
 }
 #endif
     event.Skip();
 }
 #endif
-