]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
added test for wxScopeGuard
[wxWidgets.git] / src / msw / window.cpp
index 65fafd055a687fea2aaf7462648fe12958281095..315f7bdd6d7f46fd68e8b4f8c12ef3e5b021d5cf 100644 (file)
@@ -47,6 +47,7 @@
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
     #include "wx/statbox.h"
+    #include "wx/sizer.h"
 #endif
 
 #if wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
@@ -54,6 +55,7 @@
 #endif
 
 #include "wx/module.h"
+#include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.h"
     #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"
-#endif
+#include <commctrl.h>
 
 #include "wx/msw/missing.h"
 
 #if defined(__WXWINCE__)
-#include "wx/msw/wince/missing.h"
+    #include "wx/msw/wince/missing.h"
 #endif
 
+#if defined(TME_LEAVE) && defined(WM_MOUSELEAVE)
+    #define HAVE_TRACKMOUSEEVENT
+#endif // everything needed for TrackMouseEvent()
+
+#define USE_DEFERRED_SIZING 1
+#define USE_DEFER_BUG_WORKAROUND 1
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
@@ -213,6 +216,21 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
 
 #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
 // ---------------------------------------------------------------------------
@@ -287,7 +305,7 @@ wxBEGIN_PROPERTIES_TABLE(wxWindow)
     // Always constructor Properties first
 
     wxREADONLY_PROPERTY( Parent,wxWindow*, GetParent, EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
-    wxPROPERTY( Id,wxWindowID, SetId, GetId, wxID_ANY, 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
+    wxPROPERTY( Id,wxWindowID, SetId, GetId, -1 /*wxID_ANY*/ , 0 /*flags*/ , wxT("Helpstring") , wxT("group") )
     wxPROPERTY( Position,wxPoint, SetPosition , GetPosition, wxDefaultPosition , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // pos
     wxPROPERTY( Size,wxSize, SetSize, GetSize, wxDefaultSize , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // size
     wxPROPERTY( WindowStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , EMPTY_MACROVALUE , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style
@@ -305,9 +323,9 @@ wxBEGIN_PROPERTIES_TABLE(wxWindow)
     wxPROPERTY( Shown , bool , Show , IsShown , wxxVariant((bool)true) , 0 /*flags*/ , wxT("Helpstring") , wxT("group"))
 #if 0
     // possible property candidates (not in xrc) or not valid in all subclasses
-    wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxT("") )
+    wxPROPERTY( Title,wxString, SetTitle, GetTitle, wxEmptyString )
     wxPROPERTY( Font , wxFont , SetFont , GetWindowFont  , )
-    wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxT("") )
+    wxPROPERTY( Label,wxString, SetLabel, GetLabel, wxEmptyString )
     // MaxHeight, Width , MinHeight , Width
     // TODO switch label to control and title to toplevels
 
@@ -436,10 +454,8 @@ void wxWindowMSW::Init()
     m_childrenDisabled = NULL;
     m_frozenness = 0;
 
-    // wxWnd
-    m_hMenu = 0;
-
     m_hWnd = 0;
+    m_hDWP = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
@@ -449,6 +465,9 @@ void wxWindowMSW::Init()
     m_lastMouseY = -1;
     m_lastMouseEvent = -1;
 #endif // wxUSE_MOUSEEVENT_HACK
+
+    m_pendingPosition = wxDefaultPosition;
+    m_pendingSize = wxDefaultSize;
 }
 
 // Destructor
@@ -467,7 +486,12 @@ wxWindowMSW::~wxWindowMSW()
             {
                 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__
@@ -491,6 +515,7 @@ wxWindowMSW::~wxWindowMSW()
     }
 
     delete m_childrenDisabled;
+
 }
 
 // real construction (Init() must have been called before!)
@@ -754,7 +779,11 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
 
         // Change the cursor NOW if we're within the correct window
         POINT point;
+#ifdef __WXWINCE__
+        ::GetCursorPosWinCE(&point);
+#else
         ::GetCursorPos(&point);
+#endif
 
         RECT rect = wxGetWindowRect(hWnd);
 
@@ -779,12 +808,6 @@ void wxWindowMSW::WarpPointer (int x, int y)
 // scrolling stuff
 // ---------------------------------------------------------------------------
 
-// convert wxHORIZONTAL/wxVERTICAL to SB_HORZ/SB_VERT
-static inline int wxDirToWinStyle(int orient)
-{
-    return orient == wxHORIZONTAL ? SB_HORZ : SB_VERT;
-}
-
 inline int GetScrollPosition(HWND hWnd, int wOrient)
 {
 #ifdef __WXMICROWIN__
@@ -797,7 +820,7 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
                           wOrient,
                           &scrollInfo) )
     {
-        // Not neccessarily an error, if there are no scrollbars yet.
+        // Not necessarily an error, if there are no scrollbars yet.
         // wxLogLastError(_T("GetScrollInfo"));
     }
     return scrollInfo.nPos;
@@ -1049,6 +1072,8 @@ bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
     // On WinCE (at least), the wndproc comparison doesn't work,
     // so have to use something like this.
 #ifdef __WXWINCE__
+    wxUnusedVar(wndProc);
+
     extern       wxChar *wxCanvasClassName;
     extern       wxChar *wxCanvasClassNameNR;
     extern const wxChar *wxMDIFrameClassName;
@@ -1123,7 +1148,7 @@ void wxWindowMSW::SetWindowStyleFlag(long flags)
 
         ::SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyleReal);
 
-        // we must call SetWindowPos() to flash the cached extended style and
+        // 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(),
@@ -1145,11 +1170,20 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle()
     WXDWORD style = WS_CHILD;
 
-    if ( flags & wxCLIP_CHILDREN )
+    // using this flag results in very significant reduction in flicker,
+    // especially with controls inside the static boxes (as the interior of the
+    // box is not redrawn twice).but sometimes results in redraw problems, so
+    // optionally allow the old code to continue to use it provided a special
+    // system option is turned on
+    if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children"))
+            || (flags & wxCLIP_CHILDREN) )
         style |= WS_CLIPCHILDREN;
 
-    if ( flags & wxCLIP_SIBLINGS )
-        style |= WS_CLIPSIBLINGS;
+    // it doesn't seem useful to use WS_CLIPSIBLINGS here as we officially
+    // don't support overlapping windows and it only makes sense for them and,
+    // presumably, gives the system some extra work (to manage more clipping
+    // regions), so avoid it alltogether
+
 
     if ( flags & wxVSCROLL )
         style |= WS_VSCROLL;
@@ -1227,7 +1261,11 @@ bool wxWindowMSW::IsMouseInWindow() const
 {
     // get the mouse position
     POINT pt;
+#ifdef __WXWINCE__
+    ::GetCursorPosWinCE(&pt);
+#else
     ::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
@@ -1240,6 +1278,7 @@ bool wxWindowMSW::IsMouseInWindow() const
 
 void wxWindowMSW::OnInternalIdle()
 {
+#ifndef HAVE_TRACKMOUSEEVENT
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
@@ -1247,44 +1286,10 @@ void wxWindowMSW::OnInternalIdle()
         // or doesn't have mouse capture
         if ( !IsMouseInWindow() )
         {
-            // Generate a LEAVE event
-            m_mouseInWindow = false;
-
-            // Unfortunately the mouse button and keyboard state may have
-            // changed by the time the OnInternalIdle function is called, so 'state'
-            // may be meaningless.
-            int state = 0;
-                       if ( wxIsShiftDown() )
-                state |= MK_SHIFT;
-            if ( wxIsCtrlDown() )
-                state |= MK_CONTROL;
-
-            // Only the high-order bit should be tested
-            if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
-                state |= MK_LBUTTON;
-            if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
-                state |= MK_MBUTTON;
-            if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
-                state |= MK_RBUTTON;
-
-            POINT pt;
-            if ( !::GetCursorPos(&pt) )
-            {
-                wxLogLastError(_T("GetCursorPos"));
-            }
-
-            // we need to have client coordinates here for symmetry with
-            // wxEVT_ENTER_WINDOW
-            RECT rect = wxGetWindowRect(GetHwnd());
-            pt.x -= rect.left;
-            pt.y -= rect.top;
-
-            wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-            InitMouseEvent(event2, pt.x, pt.y, state);
-
-            (void)GetEventHandler()->ProcessEvent(event2);
+            GenerateMouseLeave();
         }
     }
+#endif // !HAVE_TRACKMOUSEEVENT
 
     if (wxUpdateUIEvent::CanUpdate(this))
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
@@ -1322,7 +1327,8 @@ void wxWindowMSW::Freeze()
 {
     if ( !m_frozenness++ )
     {
-        SendSetRedraw(GetHwnd(), false);
+        if ( IsShown() )
+            SendSetRedraw(GetHwnd(), false);
     }
 }
 
@@ -1332,11 +1338,14 @@ void wxWindowMSW::Thaw()
 
     if ( !--m_frozenness )
     {
-        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();
+        }
     }
 }
 
@@ -1345,18 +1354,32 @@ void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
+        RECT mswRect;
+        const RECT *pRect;
         if ( rect )
         {
-            RECT mswRect;
             mswRect.left = rect->x;
             mswRect.top = rect->y;
             mswRect.right = rect->x + rect->width;
             mswRect.bottom = rect->y + rect->height;
 
-            ::InvalidateRect(hWnd, &mswRect, eraseBack);
+            pRect = &mswRect;
         }
         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
     }
 }
 
@@ -1528,10 +1551,24 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
         width = 0;
     if (height < 0)
         height = 0;
-    if ( !::MoveWindow(GetHwnd(), x, y, width, height, IsShown() /*Repaint?*/) )
-    {
-        wxLogLastError(wxT("MoveWindow"));
-    }
+
+    // if our parent had prepared a defer window handle for us, use it (unless
+    // we are a top level window)
+    wxWindowMSW *parent = GetParent();
+
+#if USE_DEFERRED_SIZING
+    HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
+#else
+    HDWP hdwp = 0;
+#endif
+
+    wxMoveWindowDeferred(hdwp, this, GetHwnd(), x, y, width, height);
+
+#if USE_DEFERRED_SIZING
+    if ( parent )
+        // hdwp must be updated as it may have been changed
+        parent->m_hDWP = (WXHANDLE)hdwp;
+#endif
 }
 
 // set the size of the window: if the dimensions are positive, just use them,
@@ -1546,9 +1583,28 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 {
     // get the current size and position...
     int currentX, currentY;
+    int currentW, currentH;
+
+#if USE_DEFER_BUG_WORKAROUND
+    currentX = m_pendingPosition.x;
+    if (currentX == wxDefaultCoord)
+        GetPosition(&currentX, NULL);
+
+    currentY = m_pendingPosition.y;
+    if (currentY == wxDefaultCoord)
+        GetPosition(NULL, &currentY);
+
+    currentW = m_pendingSize.x;
+    if (currentW == wxDefaultCoord)
+        GetSize(&currentW, NULL);
+
+    currentH = m_pendingSize.y;
+    if (currentH == wxDefaultCoord)
+        GetSize(NULL, &currentH);
+#else
     GetPosition(&currentX, &currentY);
-    int currentW,currentH;
     GetSize(&currentW, &currentH);
+#endif
 
     // ... and don't do anything (avoiding flicker) if it's already ok
     if ( x == currentX && y == currentY &&
@@ -1598,6 +1654,25 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
         }
     }
 
+#if USE_DEFER_BUG_WORKAROUND
+    // We don't actually use the hdwp here, but we need to know whether to
+    // save the pending dimensions or not.  This isn't done in DoMoveWindow
+    // (where the hdwp is used) because some controls have thier own
+    // DoMoveWindow so it is easier to catch it here.
+    wxWindowMSW *parent = GetParent();
+    HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
+    if (hdwp)
+    {
+        m_pendingPosition = wxPoint(x, y);
+        m_pendingSize = wxSize(width, height);
+    }
+    else
+    {
+        m_pendingPosition = wxDefaultPosition;
+        m_pendingSize = wxDefaultSize;
+    }
+#endif
+
     DoMoveWindow(x, y, width, height);
 }
 
@@ -1658,13 +1733,6 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
     }
 }
 
-// For implementation purposes - sometimes decorations make the client area
-// smaller
-wxPoint wxWindowMSW::GetClientAreaOrigin() const
-{
-    return wxPoint(0, 0);
-}
-
 // ---------------------------------------------------------------------------
 // text metrics
 // ---------------------------------------------------------------------------
@@ -1704,7 +1772,7 @@ void wxWindowMSW::GetTextExtent(const wxString& string,
 
     SIZE sizeRect;
     TEXTMETRIC tm;
-    GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+    ::GetTextExtentPoint32(hdc, string, string.length(), &sizeRect);
     GetTextMetrics(hdc, &tm);
 
     if ( x )
@@ -1839,7 +1907,8 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
             }
 
             bool bForward = true,
-                 bWindowChange = false;
+                 bWindowChange = false,
+                 bFromTab = false;
 
             // should we process this message specially?
             bool bProcess = true;
@@ -1853,6 +1922,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         // Ctrl-Tab cycles thru notebook pages
                         bWindowChange = bCtrlDown;
                         bForward = !bShiftDown;
+                        bFromTab = true;
                     }
                     break;
 
@@ -1873,8 +1943,21 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 case VK_ESCAPE:
                     {
 #if wxUSE_BUTTON
-                        wxButton *btn = wxDynamicCast(FindWindow(wxID_CANCEL),
-                                                      wxButton);
+                        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
@@ -1915,7 +1998,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             bProcess = false;
                         }
                         // FIXME: this should be handled by
-                        //        wxNavigationKeyEvent handler and not here!!
+                        //        wxNavigationKeyEvent handler and not here!
                         else
                         {
 #if wxUSE_BUTTON
@@ -1964,6 +2047,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 wxNavigationKeyEvent event;
                 event.SetDirection(bForward);
                 event.SetWindowChange(bWindowChange);
+                event.SetFromTab(bFromTab);
                 event.SetEventObject(this);
 
                 if ( GetEventHandler()->ProcessEvent(event) )
@@ -2195,7 +2279,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
     {
         bool        allow;
         WXLRESULT   result;
-        WXHICON     hIcon;
         WXHBRUSH    hBrush;
     } rc;
 
@@ -2224,6 +2307,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             (void)HandleDestroy();
             break;
 
+        case WM_SIZE:
+            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
+            break;
+
         case WM_MOVE:
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
@@ -2246,13 +2333,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
-
-        case WM_SIZE:
-            processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
-            break;
 
-#if !defined(__WXWINCE__)
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2270,10 +2351,36 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
+#endif // !__WXWINCE__
+
+        case WM_WINDOWPOSCHANGED:
+            {
+                WINDOWPOS *lpPos = (WINDOWPOS *)lParam;
+
+                if ( !(lpPos->flags & SWP_NOSIZE) )
+                {
+                    RECT rc;
+                    ::GetClientRect(GetHwnd(), &rc);
+
+                    AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc));
+                    AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x,  lpPos->y,
+                                                     lpPos->cx, lpPos->cy));
+                    AutoHRGN hrgn(::CreateRectRgn(0, 0, 0, 0));
+
+                    // we need to invalidate any new exposed areas here
+                    // to force them to repaint
+                    if ( ::CombineRgn(hrgn, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION )
+                        ::InvalidateRgn(GetHwnd(), hrgn, TRUE);
+                    if ( ::CombineRgn(hrgn, hrgnClient, hrgnNew, RGN_DIFF) != NULLREGION )
+                        ::InvalidateRgn(GetHwnd(), hrgn, TRUE);
+
+                }
+            }
+            break;
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
+            // This implicitly sends a wxEVT_ACTIVATE_APP event
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
 #endif
@@ -2296,52 +2403,34 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             processed = HandleKillFocus((WXHWND)(HWND)wParam);
             break;
 
+        case WM_PRINTCLIENT:
+            processed = HandlePrintClient((WXHDC)wParam);
+            break;
+
         case WM_PAINT:
+            if ( wParam )
             {
-                if ( wParam )
-                {
-                    // cast to wxWindow is needed for wxUniv
-                    wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
-                    processed = HandlePaint();
-                }
-                else
-                {
-                    processed = HandlePaint();
-                }
-                break;
-            }
+                wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
 
-#ifndef __WXWINCE__
-        case WM_PRINT:
+                processed = HandlePaint();
+            }
+            else // no DC given
             {
-#if wxUSE_LISTCTRL
-                // Don't call the wx handlers in this case
-                if ( wxIsKindOf(this, wxListCtrl) )
-                    break;
-#endif
-
-                if ( lParam & PRF_ERASEBKGND )
-                    HandleEraseBkgnd((WXHDC)(HDC)wParam);
-
-                wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
                 processed = HandlePaint();
             }
             break;
-#endif
 
         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;
-#endif
             break;
 
         case WM_SHOWWINDOW:
@@ -2354,61 +2443,20 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                         wParam);
             break;
 
-            // Seems to be broken currently
-#if 0 // ndef __WXWINCE__
+#ifdef HAVE_TRACKMOUSEEVENT
         case WM_MOUSELEAVE:
-           {
-            wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
-
-            // only process this message if the mouse is not in the window,
-            // This can also check for children in composite windows.
-            // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
-            // if the mouse does not enter the window from it's child before
-            // leaving the scope of the window. ( perhaps this can be picked
-            // up in the OnIdle code as before, for this special case )
-            if ( /*IsComposite() && */ !IsMouseInWindow() )
+            // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
+            if ( m_mouseInWindow )
             {
-                m_mouseInWindow = false;
-
-                // Unfortunately no mouse state is passed with a WM_MOUSE_LEAVE
-                int state = 0;
-                if ( wxIsShiftDown() )
-                    state |= MK_SHIFT;
-                if ( wxIsCtrlDown() )
-                    state |= MK_CONTROL;
-                if ( GetKeyState( VK_LBUTTON ) )
-                    state |= MK_LBUTTON;
-                if ( GetKeyState( VK_MBUTTON ) )
-                    state |= MK_MBUTTON;
-                if ( GetKeyState( VK_RBUTTON ) )
-                    state |= MK_RBUTTON;
-
-                POINT pt;
-                if ( !::GetCursorPos(&pt) )
-                {
-                    wxLogLastError(_T("GetCursorPos"));
-                }
-
-                // we need to have client coordinates here for symmetry with
-                // wxEVT_ENTER_WINDOW
-                RECT rect = wxGetWindowRect(GetHwnd());
-                pt.x -= rect.left;
-                pt.y -= rect.top;
-
-                wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-                InitMouseEvent(event2, pt.x, pt.y, state);
-
-                (void)GetEventHandler()->ProcessEvent(event2);
+                GenerateMouseLeave();
             }
+
             // always pass processed back as false, this allows the window
-            // manager to process the message too.  This is needed to ensure
-            // windows XP themes work properly as the mouse moves over widgets
-            // like buttons.
-            processed = false;
-           }
-           break;
-#endif
- // __WXWINCE__
+            // manager to process the message too.  This is needed to
+            // ensure windows XP themes work properly as the mouse moves
+            // over widgets like buttons. So don't set processed to true here.
+            break;
+#endif // HAVE_TRACKMOUSEEVENT
 
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
@@ -2820,7 +2868,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                         wxHelpEvent helpEvent(wxEVT_HELP,
                                               subjectOfHelp->GetId(),
 #ifdef __WXWINCE__
-                                              wxPoint(0, 0)
+                                              wxPoint(0,0)
 #else
                                               wxPoint(info->MousePos.x, info->MousePos.y)
 #endif
@@ -3073,42 +3121,22 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     // do create the window
     wxWindowCreationHook hook(this);
 
-    // VZ: anyone care to explain why this is done for CE?
-#ifdef __WXWINCE__
-    if (extendedStyle == 0)
-    {
-        m_hWnd = (WXHWND)::CreateWindow
-            (
-            className,
-            title ? title : wxEmptyString,
-            style,
-            x, y, w, h,
-            (HWND)MSWGetParent(),
-            (HMENU)controlId,
-            wxGetInstance(),
-            NULL                        // no extra data
-            );
-    }
-    else
-#endif // __WXWINCE__
-    {
-        m_hWnd = (WXHWND)::CreateWindowEx
-            (
-            extendedStyle,
-            className,
-            title ? title : wxEmptyString,
-            style,
-            x, y, w, h,
-            (HWND)MSWGetParent(),
-            (HMENU)controlId,
-            wxGetInstance(),
-            NULL                        // no extra data
-            );
-    }
+    m_hWnd = (WXHWND)::CreateWindowEx
+                       (
+                        extendedStyle,
+                        className,
+                        title ? title : m_windowName.c_str(),
+                        style,
+                        x, y, w, h,
+                        (HWND)MSWGetParent(),
+                        (HMENU)controlId,
+                        wxGetInstance(),
+                        NULL                        // no extra data
+                       );
 
     if ( !m_hWnd )
     {
-        wxLogSysError(_("Can't create window of class %s"), wclass);
+        wxLogSysError(_("Can't create window of class %s"), className.c_str());
 
         return false;
     }
@@ -3279,7 +3307,7 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
 
 bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
 {
-#ifndef __WXWINCE__
+#ifdef ENDSESSION_LOGOFF
     wxCloseEvent event(wxEVT_QUERY_END_SESSION, wxID_ANY);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(true);
@@ -3296,13 +3324,15 @@ bool wxWindowMSW::HandleQueryEndSession(long logOff, bool *mayEnd)
 
     return rc;
 #else
+    wxUnusedVar(logOff);
+    wxUnusedVar(mayEnd);
     return false;
 #endif
 }
 
 bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 {
-#ifndef __WXWINCE__
+#ifdef ENDSESSION_LOGOFF
     // do nothing if the session isn't ending
     if ( !endSession )
         return false;
@@ -3318,6 +3348,8 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 
     return wxTheApp->ProcessEvent(event);
 #else
+    wxUnusedVar(endSession);
+    wxUnusedVar(logOff);
     return false;
 #endif
 }
@@ -3465,7 +3497,7 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
 bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
 {
     wxShowEvent event(GetId(), show);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
 }
@@ -3473,7 +3505,7 @@ bool wxWindowMSW::HandleShow(bool show, int WXUNUSED(status))
 bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 {
     wxInitDialogEvent event(GetId());
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
 }
@@ -3508,7 +3540,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
     DragFinish (hFilesInfo);
 
     wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     POINT dropPoint;
     DragQueryPoint(hFilesInfo, (LPPOINT) &dropPoint);
@@ -3543,7 +3575,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;
+#ifdef __WXWINCE__
+    if ( !::GetCursorPosWinCE(&pt))
+#else
     if ( !::GetCursorPos(&pt) )
+#endif
     {
         wxLogLastError(wxT("GetCursorPos"));
     }
@@ -3628,7 +3664,11 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         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
@@ -3686,7 +3726,15 @@ wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
     {
         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;
@@ -3737,12 +3785,16 @@ bool wxWindowMSW::HandleDisplayChange()
 
 #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 )
-        *brush = item->MSWControlColor(pDC);
+        *brush = item->MSWControlColor(hDC, hWnd);
     else
 #endif // wxUSE_CONTROLS
         *brush = NULL;
@@ -3752,11 +3804,6 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
 
 #endif // __WXMICROWIN__
 
-WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC))
-{
-    return (WXHBRUSH)0;
-}
-
 bool wxWindowMSW::HandlePaletteChanged(WXHWND hWndPalChange)
 {
 #if wxUSE_PALETTE
@@ -3886,6 +3933,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.
+            wxLogNull logNo; // suppress error if we couldn't load the bitmap
             wxBitmap stdColourBitmap(_T("wxBITMAP_STD_COLOURS"));
             if ( stdColourBitmap.Ok() )
             {
@@ -3999,9 +4047,10 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
 void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 {
-    // standard controls always erase their background themselves (although the
-    // user may try to override it in a derived class)
-    if ( IsOfStandardClass() )
+    // standard non top level controls (i.e. except the dialogs) always erase
+    // their background themselves in HandleCtlColor() or have some control-
+    // specific ways to set the colours (common controls)
+    if ( IsOfStandardClass() && !IsTopLevel() )
     {
         event.Skip();
         return;
@@ -4017,59 +4066,105 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 
 
     // do default background painting
-    wxDC& dc = *event.GetDC();
-    HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
-    if ( hBrush )
-    {
-        RECT rc;
-        ::GetClientRect(GetHwnd(), &rc);
-        ::FillRect(GetHdcOf(dc), &rc, hBrush);
-    }
-    else
+    if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) )
     {
         // let the system paint the background
         event.Skip();
     }
 }
 
-WXHBRUSH wxWindowMSW::MSWGetSolidBgBrushForChild(wxWindow *child)
+bool wxWindowMSW::DoEraseBackground(WXHDC hDC)
 {
-    wxColour col = MSWGetBgColourForChild(child);
-    if ( col.Ok() )
-    {
-        // draw children with the same colour as the parent
-        wxBrush *brush = wxTheBrushList->FindOrCreateBrush(col, wxSOLID);
+    HBRUSH hbr = (HBRUSH)MSWGetBgBrush(hDC);
+    if ( !hbr )
+        return false;
+
+    wxFillRect(GetHwnd(), (HDC)hDC, hbr);
+
+    return true;
+}
 
-        return (WXHBRUSH)brush->GetResourceHandle();
+WXHBRUSH
+wxWindowMSW::MSWGetBgBrushForChild(WXHDC WXUNUSED(hDC), WXHWND hWnd)
+{
+    if ( m_hasBgCol )
+    {
+        // our background colour applies to:
+        //  1. this window itself, always
+        //  2. all children unless the colour is "not inheritable"
+        //  3. even if it is not inheritable, our immediate transparent
+        //     children should still inherit it -- but not any transparent
+        //     children because it would look wrong if a child of non
+        //     transparent child would show our bg colour when the child itself
+        //     does not
+        wxWindow *win = wxFindWinFromHandle(hWnd);
+        if ( win == this ||
+                m_inheritBgCol ||
+                    (win && win->HasTransparentBackground() &&
+                        win->GetParent() == this) )
+        {
+            // draw children with the same colour as the parent
+            wxBrush *
+                brush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour());
+
+            return (WXHBRUSH)GetHbrushOf(*brush);
+        }
     }
 
     return 0;
 }
 
-wxColour wxWindowMSW::MSWGetBgColourForChild(wxWindow * WXUNUSED(child))
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC, WXHWND hWndToPaint)
 {
-    return m_hasBgCol ? GetBackgroundColour() : wxNullColour;
-}
+    if ( !hWndToPaint )
+        hWndToPaint = GetHWND();
 
-WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
-{
-    return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
+    for ( wxWindowMSW *win = this; win; win = win->GetParent() )
+    {
+        WXHBRUSH hBrush = win->MSWGetBgBrushForChild(hDC, hWndToPaint);
+        if ( hBrush )
+            return hBrush;
+
+        // background is not inherited beyond top level windows
+        if ( win->IsTopLevel() )
+            break;
+    }
+
+    return 0;
 }
 
-WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
+bool wxWindowMSW::HandlePrintClient(WXHDC hDC)
 {
-    for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() )
+    // we receive this message when DrawThemeParentBackground() is
+    // called from def window proc of several controls under XP and we
+    // must draw properly themed background here
+    //
+    // note that naively I'd expect filling the client rect with the
+    // brush returned by MSWGetBgBrush() work -- but for some reason it
+    // doesn't and we have to call parents MSWPrintChild() which is
+    // supposed to call DrawThemeBackground() with appropriate params
+    //
+    // also note that in this case lParam == PRF_CLIENT but we're
+    // clearly expected to paint the background and nothing else!
+
+    if ( IsTopLevel() || InheritsBackgroundColour() )
+        return false;
+
+    // sometimes we don't want the parent to handle it at all, instead
+    // return whatever value this window wants
+    if ( !MSWShouldPropagatePrintChild() )
+        return MSWPrintChild(hDC, (wxWindow *)this);
+
+    for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
     {
-        // background is not inherited beyond the containing TLW
-        if ( win->IsTopLevel() )
-            break;
+        if ( win->MSWPrintChild(hDC, (wxWindow *)this) )
+            return true;
 
-        WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC);
-        if ( hBrush )
-            return hBrush;
+        if ( win->IsTopLevel() || win->InheritsBackgroundColour() )
+            break;
     }
 
-    return 0;
+    return false;
 }
 
 // ---------------------------------------------------------------------------
@@ -4114,8 +4209,37 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
-    bool processed = false;
+#if USE_DEFERRED_SIZING
+    // when we resize this window, its children are probably going to be
+    // repositioned as well, prepare to use DeferWindowPos() for them
+    int numChildren = 0;
+    for ( HWND child = ::GetWindow(GetHwndOf(this), GW_CHILD);
+          child;
+          child = ::GetWindow(child, GW_HWNDNEXT) )
+    {
+        numChildren ++;
+    }
 
+    // Protect against valid m_hDWP being overwritten
+    bool useDefer = false;
+
+    if ( numChildren > 1 )
+    {
+        if (!m_hDWP)
+        {
+            m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
+            if ( !m_hDWP )
+            {
+                wxLogLastError(_T("BeginDeferWindowPos"));
+            }
+            if (m_hDWP)
+                useDefer = true;
+        }
+    }
+#endif
+
+    // update this window size
+    bool processed = false;
     switch ( wParam )
     {
         default:
@@ -4145,6 +4269,37 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
             processed = GetEventHandler()->ProcessEvent(event);
     }
 
+#if USE_DEFERRED_SIZING
+    // and finally change the positions of all child windows at once
+    if ( useDefer && m_hDWP )
+    {
+        // reset m_hDWP to NULL so that child windows don't try to use our
+        // m_hDWP after we call EndDeferWindowPos() on it (this shouldn't
+        // happen anyhow normally but who knows what weird flow of control we
+        // may have depending on what the users EVT_SIZE handler does...)
+        HDWP hDWP = (HDWP)m_hDWP;
+        m_hDWP = NULL;
+
+        // do put all child controls in place at once
+        if ( !::EndDeferWindowPos(hDWP) )
+        {
+            wxLogLastError(_T("EndDeferWindowPos"));
+        }
+
+#if USE_DEFER_BUG_WORKAROUND
+        // 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
+    }
+#endif
+
     return processed;
 }
 
@@ -4255,18 +4410,27 @@ bool wxWindowMSW::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control)
 
         return GetEventHandler()->ProcessEvent(event);
     }
-#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
     else
     {
+#if wxUSE_SPINCTRL && !defined(__WXUNIVERSAL__)
         // the text ctrl which is logically part of wxSpinCtrl sends WM_COMMAND
         // notifications to its parent which we want to reflect back to
         // wxSpinCtrl
         wxSpinCtrl *spin = wxSpinCtrl::GetSpinForTextCtrl(control);
         if ( spin && spin->ProcessTextCommand(cmd, id) )
             return true;
-    }
 #endif // wxUSE_SPINCTRL
 
+#if wxUSE_CHOICE && defined(__SMARTPHONE__)
+        // the listbox ctrl which is logically part of wxChoice sends WM_COMMAND
+        // notifications to its parent which we want to reflect back to
+        // wxChoice
+        wxChoice *choice = wxChoice::GetChoiceForListBox(control);
+        if ( choice && choice->MSWCommand(cmd, id) )
+            return true;
+#endif
+    }
+
     return false;
 }
 
@@ -4288,16 +4452,13 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.m_leftDown = (flags & MK_LBUTTON) != 0;
     event.m_middleDown = (flags & MK_MBUTTON) != 0;
     event.m_rightDown = (flags & MK_RBUTTON) != 0;
- //   event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
-    // Returns different negative values on WinME and WinNT,
-    // so simply test for negative value.
     event.m_altDown = ::GetKeyState(VK_MENU) < 0;
 
 #ifndef __WXWINCE__
     event.SetTimestamp(::GetMessageTime());
 #endif
 
-    event.m_eventObject = this;
+    event.SetEventObject(this);
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
@@ -4409,19 +4570,18 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         {
             // Generate an ENTER event
             m_mouseInWindow = true;
-#if _WIN32_WINNT >= 0x0400
-#ifndef __WXWINCE__
-            TRACKMOUSEEVENT trackinfo;
 
-            trackinfo.cbSize = sizeof(trackinfo);
+#ifdef HAVE_TRACKMOUSEEVENT
+            WinStruct<TRACKMOUSEEVENT> trackinfo;
+
             trackinfo.dwFlags = TME_LEAVE;
             trackinfo.hwndTrack = GetHwnd();
-            //Use the commctrl.h _TrackMouseEvent, which will call the
-            // appropriate TrackMouseEvent or emulate it ( win95 )
-            // else we need _WIN32_WINNT >= 0x0400
+
+            // Use the commctrl.h _TrackMouseEvent(), which will call the real
+            // TrackMouseEvent() if available or emulate it
             _TrackMouseEvent(&trackinfo);
-#endif
-#endif
+#endif // HAVE_TRACKMOUSEEVENT
+
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
@@ -4476,14 +4636,53 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
     event.m_linesPerAction = s_linesPerRotation;
     return GetEventHandler()->ProcessEvent(event);
 
-#else
-    (void) wParam;
-    (void) lParam;
+#else // !wxUSE_MOUSEWHEEL
+    wxUnusedVar(wParam);
+    wxUnusedVar(lParam);
 
     return false;
-#endif
+#endif // wxUSE_MOUSEWHEEL/!wxUSE_MOUSEWHEEL
 }
 
+void wxWindowMSW::GenerateMouseLeave()
+{
+    m_mouseInWindow = false;
+
+    int state = 0;
+    if ( wxIsShiftDown() )
+        state |= MK_SHIFT;
+    if ( wxIsCtrlDown() )
+        state |= MK_CONTROL;
+
+    // Only the high-order bit should be tested
+    if ( GetKeyState( VK_LBUTTON ) & (1<<15) )
+        state |= MK_LBUTTON;
+    if ( GetKeyState( VK_MBUTTON ) & (1<<15) )
+        state |= MK_MBUTTON;
+    if ( GetKeyState( VK_RBUTTON ) & (1<<15) )
+        state |= MK_RBUTTON;
+
+    POINT pt;
+#ifdef __WXWINCE__
+    if ( !::GetCursorPosWinCE(&pt) )
+#else
+    if ( !::GetCursorPos(&pt) )
+#endif
+    {
+        wxLogLastError(_T("GetCursorPos"));
+    }
+
+    // we need to have client coordinates here for symmetry with
+    // wxEVT_ENTER_WINDOW
+    RECT rect = wxGetWindowRect(GetHwnd());
+    pt.x -= rect.left;
+    pt.y -= rect.top;
+
+    wxMouseEvent event(wxEVT_LEAVE_WINDOW);
+    InitMouseEvent(event, pt.x, pt.y, state);
+
+    (void)GetEventHandler()->ProcessEvent(event);
+}
 
 // ---------------------------------------------------------------------------
 // keyboard handling
@@ -4502,7 +4701,7 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
     event.m_controlDown = wxIsCtrlDown();
     event.m_altDown = (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN;
 
-    event.m_eventObject = (wxWindow *)this; // const_cast
+    event.SetEventObject((wxWindow *)this); // const_cast
     event.m_keyCode = id;
 #if wxUSE_UNICODE
     event.m_uniChar = (wxChar) wParam;
@@ -4515,7 +4714,11 @@ wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
 
     // translate the position to client coords
     POINT pt;
+#ifdef __WXWINCE__
+    GetCursorPosWinCE(&pt);
+#else
     GetCursorPos(&pt);
+#endif
     RECT rect;
     GetWindowRect(GetHwnd(),&rect);
     pt.x -= rect.left;
@@ -4805,32 +5008,32 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
     wxScrollWinEvent event;
     event.SetPosition(pos);
     event.SetOrientation(orientation);
-    event.m_eventObject = this;
+    event.SetEventObject(this);
 
     switch ( wParam )
     {
     case SB_TOP:
-        event.m_eventType = wxEVT_SCROLLWIN_TOP;
+        event.SetEventType(wxEVT_SCROLLWIN_TOP);
         break;
 
     case SB_BOTTOM:
-        event.m_eventType = wxEVT_SCROLLWIN_BOTTOM;
+        event.SetEventType(wxEVT_SCROLLWIN_BOTTOM);
         break;
 
     case SB_LINEUP:
-        event.m_eventType = wxEVT_SCROLLWIN_LINEUP;
+        event.SetEventType(wxEVT_SCROLLWIN_LINEUP);
         break;
 
     case SB_LINEDOWN:
-        event.m_eventType = wxEVT_SCROLLWIN_LINEDOWN;
+        event.SetEventType(wxEVT_SCROLLWIN_LINEDOWN);
         break;
 
     case SB_PAGEUP:
-        event.m_eventType = wxEVT_SCROLLWIN_PAGEUP;
+        event.SetEventType(wxEVT_SCROLLWIN_PAGEUP);
         break;
 
     case SB_PAGEDOWN:
-        event.m_eventType = wxEVT_SCROLLWIN_PAGEDOWN;
+        event.SetEventType(wxEVT_SCROLLWIN_PAGEDOWN);
         break;
 
     case SB_THUMBPOSITION:
@@ -4849,16 +5052,16 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
                                                               : 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"));
             }
 
             event.SetPosition(scrollInfo.nTrackPos);
         }
 
-        event.m_eventType = wParam == SB_THUMBPOSITION
+        event.SetEventType( wParam == SB_THUMBPOSITION
                                 ? wxEVT_SCROLLWIN_THUMBRELEASE
-                                : wxEVT_SCROLLWIN_THUMBTRACK;
+                                : wxEVT_SCROLLWIN_THUMBTRACK );
         break;
 
     default:
@@ -4912,7 +5115,7 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
         case VK_CLEAR:      id = WXK_CLEAR; break;
         case VK_SHIFT:      id = WXK_SHIFT; break;
         case VK_CONTROL:    id = WXK_CONTROL; break;
-        case VK_MENU :      id = WXK_MENU; break;
+        case VK_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;
@@ -5018,7 +5221,6 @@ WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual)
     case WXK_SHIFT:     keySym = VK_SHIFT; break;
     case WXK_CONTROL:   keySym = VK_CONTROL; break;
     case WXK_ALT:       keySym = VK_MENU; break;
-    case WXK_MENU :     keySym = VK_MENU; break;
     case WXK_PAUSE:     keySym = VK_PAUSE; break;
     case WXK_CAPITAL:   keySym = VK_CAPITAL; break;
     case WXK_PRIOR:     keySym = VK_PRIOR; break;
@@ -5090,6 +5292,9 @@ bool wxGetKeyState(wxKeyCode key)
 {
     bool bVirtual;
 
+    wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
+        WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
+
 //High order with GetAsyncKeyState only available on WIN32
 #ifdef __WIN32__
     //If the requested key is a LED key, return
@@ -5226,7 +5431,7 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
             if ( (HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN )
                 event.m_altDown = true;
 
-            event.m_eventObject = NULL;
+            event.SetEventObject(NULL);
             event.m_keyCode = id;
             event.m_shiftDown = wxIsShiftDown();
             event.m_controlDown = wxIsCtrlDown();
@@ -5734,13 +5939,36 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
 wxPoint wxGetMousePosition()
 {
     POINT pt;
+#ifdef __WXWINCE__
+    GetCursorPosWinCE(&pt);
+#else
     GetCursorPos( & pt );
+#endif
 
     return wxPoint(pt.x, pt.y);
 }
 
 #if wxUSE_HOTKEY
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+static void WinCEUnregisterHotKey(int modifiers, int id)
+{
+    // Register hotkeys for the hardware buttons
+    HINSTANCE hCoreDll;
+    typedef BOOL (WINAPI *UnregisterFunc1Proc)(UINT, UINT);
+
+    UnregisterFunc1Proc procUnregisterFunc;
+    hCoreDll = LoadLibrary(_T("coredll.dll"));
+    if (hCoreDll)
+    {
+        procUnregisterFunc = (UnregisterFunc1Proc)GetProcAddress(hCoreDll, _T("UnregisterFunc1"));
+        if (procUnregisterFunc)
+            procUnregisterFunc(modifiers, id);
+        FreeLibrary(hCoreDll);
+    }
+}
+#endif
+
 bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 {
     UINT win_modifiers=0;
@@ -5753,6 +5981,12 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
     if ( modifiers & wxMOD_WIN )
         win_modifiers |= MOD_WIN;
 
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    // Required for PPC and Smartphone hardware buttons
+    if (keycode >= WXK_SPECIAL1 && keycode <= WXK_SPECIAL20)
+        WinCEUnregisterHotKey(win_modifiers, hotkeyId);
+#endif
+
     if ( !::RegisterHotKey(GetHwnd(), hotkeyId, win_modifiers, keycode) )
     {
         wxLogLastError(_T("RegisterHotKey"));
@@ -5765,6 +5999,10 @@ bool wxWindowMSW::RegisterHotKey(int hotkeyId, int modifiers, int keycode)
 
 bool wxWindowMSW::UnregisterHotKey(int hotkeyId)
 {
+#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
+    WinCEUnregisterHotKey(MOD_WIN, hotkeyId);
+#endif
+
     if ( !::UnregisterHotKey(GetHwnd(), hotkeyId) )
     {
         wxLogLastError(_T("UnregisterHotKey"));
@@ -5797,6 +6035,31 @@ bool wxWindowMSW::HandleHotKey(WXWPARAM wParam, WXLPARAM lParam)
 
 #endif // wxUSE_HOTKEY
 
+// Moves a window by deferred method or normal method
+bool wxMoveWindowDeferred(HDWP& hdwp, wxWindowBase* win, HWND hWnd, int x, int y, int width, int height)
+{
+    if ( hdwp )
+    {
+        hdwp = ::DeferWindowPos(hdwp, hWnd, NULL,
+                            x, y, width, height,
+                            SWP_NOZORDER);
+        if ( !hdwp )
+        {
+            wxLogLastError(_T("DeferWindowPos"));
+        }
+    }
+
+    // otherwise (or if deferring failed) move the window in place immediately
+    if ( !hdwp )
+    {
+        if ( !::MoveWindow(hWnd, x, y, width, height, win->IsShown()) )
+        {
+            wxLogLastError(wxT("MoveWindow"));
+        }
+    }
+    return hdwp != NULL;
+}
+
 // Not tested under WinCE
 #ifndef __WXWINCE__