]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
GetParent() was always used in test for wxHSCROLL checked in in last commit; use...
[wxWidgets.git] / src / msw / window.cpp
index f7b7c2f9820aab85e2d3f43ded62876c0d5b37bb..43d21ba44d0f071501891a7c2456b4d803ccedec 100644 (file)
@@ -54,6 +54,7 @@
 #endif
 
 #include "wx/module.h"
+#include "wx/sysopt.h"
 
 #if wxUSE_DRAG_AND_DROP
     #include "wx/dnd.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()
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
@@ -287,7 +292,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 +310,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
 
@@ -777,12 +782,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__
@@ -1047,6 +1046,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;
@@ -1121,7 +1122,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,8 +1146,12 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 
     // using this flag results in very significant reduction in flicker,
     // especially with controls inside the static boxes (as the interior of the
-    // box is not redrawn twice)
-    style |= WS_CLIPCHILDREN;
+    // 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;
 
     // 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,
@@ -1243,7 +1248,7 @@ bool wxWindowMSW::IsMouseInWindow() const
 
 void wxWindowMSW::OnInternalIdle()
 {
-#ifdef __WXWINCE__
+#ifndef HAVE_TRACKMOUSEEVENT
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
@@ -1254,7 +1259,7 @@ void wxWindowMSW::OnInternalIdle()
             GenerateMouseLeave();
         }
     }
-#endif // !__WXWINCE__
+#endif // !HAVE_TRACKMOUSEEVENT
 
     if (wxUpdateUIEvent::CanUpdate(this))
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
@@ -1292,7 +1297,8 @@ void wxWindowMSW::Freeze()
 {
     if ( !m_frozenness++ )
     {
-        SendSetRedraw(GetHwnd(), false);
+        if ( IsShown() )
+            SendSetRedraw(GetHwnd(), false);
     }
 }
 
@@ -1302,11 +1308,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();
+        }
     }
 }
 
@@ -1315,18 +1324,31 @@ 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;
+        }
+
+#ifndef __SMARTPHONE__
+        UINT flags = RDW_INVALIDATE | RDW_ALLCHILDREN;
+        if ( eraseBack )
+            flags |= RDW_ERASE;
+
+        ::RedrawWindow(hWnd, pRect, NULL, flags);
+#else
+        ::InvalidateRect(hWnd, pRect, eraseBack);
+#endif
     }
 }
 
@@ -1502,12 +1524,12 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
     // 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;
+    HDWP hdwp = parent && !IsTopLevel() ? (HDWP)parent->m_hDWP : NULL;
     if ( hdwp )
     {
         hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL,
-                                x, y, width, height,
-                                SWP_NOZORDER);
+                            x, y, width, height,
+                            SWP_NOZORDER);
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
@@ -1520,7 +1542,7 @@ void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
     // otherwise (or if deferring failed) move the window in place immediately
     if ( !hdwp )
     {
-        if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+        if ( !::MoveWindow(GetHwnd(), x, y, width, height, IsShown()) )
         {
             wxLogLastError(wxT("MoveWindow"));
         }
@@ -1651,13 +1673,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
 // ---------------------------------------------------------------------------
@@ -1832,7 +1847,8 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
             }
 
             bool bForward = true,
-                 bWindowChange = false;
+                 bWindowChange = false,
+                 bFromTab = false;
 
             // should we process this message specially?
             bool bProcess = true;
@@ -1846,6 +1862,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                         // Ctrl-Tab cycles thru notebook pages
                         bWindowChange = bCtrlDown;
                         bForward = !bShiftDown;
+                        bFromTab = true;
                     }
                     break;
 
@@ -1970,6 +1987,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 wxNavigationKeyEvent event;
                 event.SetDirection(bForward);
                 event.SetWindowChange(bWindowChange);
+                event.SetFromTab(bFromTab);
                 event.SetEventObject(this);
 
                 if ( GetEventHandler()->ProcessEvent(event) )
@@ -2201,7 +2219,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
     {
         bool        allow;
         WXLRESULT   result;
-        WXHICON     hIcon;
         WXHBRUSH    hBrush;
     } rc;
 
@@ -2230,49 +2247,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             (void)HandleDestroy();
             break;
 
-#ifndef __SMARTPHONE__ // or wxWinCE in general ?
-        case WM_WINDOWPOSCHANGING:
-            {
-                WINDOWPOS *wp = wx_reinterpret_cast(WINDOWPOS *, lParam);
-
-                if ( wp->flags & SWP_NOSIZE )
-                    break;
-
-                // 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();
-                if ( numChildren > 1 )
-                {
-                    m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
-                    if ( !m_hDWP )
-                    {
-                        wxLogLastError(_T("BeginDeferWindowPos"));
-                    }
-                }
-            }
-            break;
-
-        case WM_WINDOWPOSCHANGED:
-            // first let DefWindowProc() handle the message: it will generate
-            // WM_MOVE and WM_SIZE as needed
-            processed = MSWDefWindowProc(message, wParam, lParam) == 0;
-
-            // then change the positions of all child windows at once
-            if ( m_hDWP )
-            {
-                HDWP hDWP = (HDWP)m_hDWP;
-                m_hDWP = NULL;
-
-                // put all child controls in place at once now
-                if ( !::EndDeferWindowPos(hDWP) )
-                {
-                    wxLogLastError(_T("EndDeferWindowPos"));
-                }
-            }
-            break;
-#endif // __SMARTPHONE__
-
         case WM_SIZE:
             processed = HandleSize(LOWORD(lParam), HIWORD(lParam), wParam);
             break;
@@ -2282,7 +2256,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 
 #if !defined(__WXWINCE__)
-        // TODO: move those in WM_WINDOWPOSCHANGING case above
         case WM_MOVING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2322,6 +2295,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
+            // This implicitly sends a wxEVT_ACTIVATE_APP event
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
 #endif
@@ -2344,52 +2318,57 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             processed = HandleKillFocus((WXHWND)(HWND)wParam);
             break;
 
-        case WM_PAINT:
+        case WM_PRINTCLIENT:
+            // 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 ( wParam )
+                for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
                 {
-                    // cast to wxWindow is needed for wxUniv
-                    wxPaintDCEx dc((wxWindow *)this, (WXHDC)wParam);
-                    processed = HandlePaint();
-                }
-                else
-                {
-                    processed = HandlePaint();
+                    if ( win->MSWPrintChild((WXHDC)wParam, (wxWindow *)this) )
+                    {
+                        processed = true;
+                        break;
+                    }
+
+                    if ( win->IsTopLevel() || win->InheritsBackgroundColour() )
+                        break;
                 }
-                break;
             }
+            break;
 
-#ifndef __WXWINCE__
-        case WM_PRINT:
+        case WM_PAINT:
+            if ( wParam )
             {
-#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();
+            }
+            else // no DC given
+            {
                 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:
@@ -2402,23 +2381,20 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                         wParam);
             break;
 
-#ifdef WM_MOUSELEAVE
+#ifdef HAVE_TRACKMOUSEEVENT
         case WM_MOUSELEAVE:
+            // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
+            if ( m_mouseInWindow )
             {
-                // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
-                if ( m_mouseInWindow )
-                {
-                    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;
+                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. So don't set processed to true here.
             break;
-#endif // WM_MOUSELEAVE
+#endif // HAVE_TRACKMOUSEEVENT
 
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
@@ -2830,7 +2806,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
@@ -3083,42 +3059,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;
     }
@@ -3289,7 +3245,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);
@@ -3306,13 +3262,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;
@@ -3328,6 +3286,8 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
 
     return wxTheApp->ProcessEvent(event);
 #else
+    wxUnusedVar(endSession);
+    wxUnusedVar(logOff);
     return false;
 #endif
 }
@@ -3750,7 +3710,8 @@ bool wxWindowMSW::HandleDisplayChange()
 bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
 {
 #if wxUSE_CONTROLS
-    wxWindow *item = FindItemByHWND(pWnd, true);
+    wxControl *item = wxDynamicCast(FindItemByHWND(pWnd, true), wxControl);
+
     if ( item )
         *brush = item->MSWControlColor(pDC);
     else
@@ -3762,11 +3723,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
@@ -4028,81 +3984,66 @@ void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 
 
     // do default background painting
-    if ( !DoEraseBackground(*event.GetDC()) )
+    if ( !DoEraseBackground(GetHdcOf(*event.GetDC())) )
     {
         // 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;
 
-    RECT rc;
-    ::GetClientRect(GetHwnd(), &rc);
-    ::FillRect(GetHdcOf(dc), &rc, hBrush);
+    wxFillRect(GetHwnd(), (HDC)hDC, hbr);
 
     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), wxWindow *child)
 {
     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 ||
+        //  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
+        if ( child == this ||
+                m_inheritBgCol ||
                     (child->HasTransparentBackground() &&
                         child->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, wxWindow *winToPaint)
 {
-    return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
-}
+    if ( !winToPaint )
+        winToPaint = this;
 
-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, winToPaint);
         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->m_hasBgCol && !win->m_inheritBgCol) )
+        // background is not inherited beyond top level windows
+        if ( win->IsTopLevel() )
             break;
     }
 
@@ -4151,8 +4092,20 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
 
 bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
-    bool processed = false;
+    // 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();
+    if ( numChildren > 1 )
+    {
+        m_hDWP = (WXHANDLE)::BeginDeferWindowPos(numChildren);
+        if ( !m_hDWP )
+        {
+            wxLogLastError(_T("BeginDeferWindowPos"));
+        }
+    }
 
+    // update this window size
+    bool processed = false;
     switch ( wParam )
     {
         default:
@@ -4182,6 +4135,23 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
             processed = GetEventHandler()->ProcessEvent(event);
     }
 
+    // and finally change the positions of all child windows at once
+    if ( 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"));
+        }
+    }
+
     return processed;
 }
 
@@ -4292,18 +4262,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;
 }
 
@@ -4443,17 +4422,18 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         {
             // Generate an ENTER event
             m_mouseInWindow = true;
-#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 // __WXWINCE__
+#endif // HAVE_TRACKMOUSEEVENT
+
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
@@ -4979,7 +4959,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;
@@ -5085,7 +5065,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;
@@ -5157,6 +5136,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
@@ -5808,6 +5790,25 @@ wxPoint wxGetMousePosition()
 
 #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;
@@ -5820,6 +5821,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"));
@@ -5832,6 +5839,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"));