]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Make sure -DNO_GCC_PRAGMA is in wx-config output regardless of the reason.
[wxWidgets.git] / src / msw / window.cpp
index 998b15822d2274f6d47e820ca5ee2928288dbcac..0597f96da22a822fe9f209fe42cf55a34f172a09 100644 (file)
@@ -155,11 +155,6 @@ void wxRemoveHandleAssociation(wxWindowMSW *win);
 extern void wxAssociateWinWithHandle(HWND hWnd, wxWindowMSW *win);
 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
-// this magical function is used to translate VK_APPS key presses to right
-// mouse clicks
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
-                                     int *x, int *y, WPARAM *flags);
-
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
@@ -264,7 +259,7 @@ wxBEGIN_FLAGS( wxWindowStyle )
     wxFLAGS_MEMBER(wxBORDER_RAISED)
     wxFLAGS_MEMBER(wxBORDER_STATIC)
     wxFLAGS_MEMBER(wxBORDER_NONE)
-    
+
     // old style border flags
     wxFLAGS_MEMBER(wxSIMPLE_BORDER)
     wxFLAGS_MEMBER(wxSUNKEN_BORDER)
@@ -337,9 +332,11 @@ wxCONSTRUCTOR_DUMMY(wxWindow)
 #endif // __WXUNIVERSAL__/__WXMSW__
 
 BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
-    EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
+    EVT_ERASE_BACKGROUND(wxWindowMSW::OnEraseBackground)
+#ifdef __WXWINCE__
     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
+#endif
 END_EVENT_TABLE()
 
 // ===========================================================================
@@ -439,10 +436,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;
@@ -528,7 +523,12 @@ bool wxWindowMSW::Create(wxWindow *parent,
         msflags |= WS_VISIBLE;
     }
 
-    return MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle);
+    if ( !MSWCreate(wxCanvasClassName, NULL, pos, size, msflags, exstyle) )
+        return false;
+
+    InheritAttributes();
+
+    return true;
 }
 
 // ---------------------------------------------------------------------------
@@ -579,7 +579,7 @@ void wxWindowMSW::SetFocusFromKbd()
 }
 
 // Get the window with the focus
-wxWindow *wxWindowBase::FindFocus()
+wxWindow *wxWindowBase::DoFindFocus()
 {
     HWND hWnd = ::GetFocus();
     if ( hWnd )
@@ -998,7 +998,7 @@ void wxWindowMSW::UnsubclassWin()
     HWND hwnd = GetHwnd();
     if ( hwnd )
     {
-        m_hWnd = 0;
+        SetHWND(0);
 
         wxCHECK_RET( ::IsWindow(hwnd), wxT("invalid HWND in UnsubclassWin") );
 
@@ -1014,6 +1014,27 @@ void wxWindowMSW::UnsubclassWin()
     }
 }
 
+void wxWindowMSW::AssociateHandle(WXWidget handle)
+{
+    if ( m_hWnd )
+    {
+      if ( !::DestroyWindow(GetHwnd()) )
+        wxLogLastError(wxT("DestroyWindow"));
+    }
+
+    WXHWND wxhwnd = (WXHWND)handle;
+
+    SetHWND(wxhwnd);
+    SubclassWin(wxhwnd);
+}
+
+void wxWindowMSW::DissociateHandle()
+{
+    // this also calls SetHWND(0) for us
+    UnsubclassWin();
+}
+
+
 bool wxCheckWindowWndProc(WXHWND hWnd, WXFARPROC wndProc)
 {
     // Unicows note: the code below works, but only because WNDCLASS contains
@@ -1122,11 +1143,16 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
     // wxTopLevelWindow) should remove WS_CHILD in their MSWGetStyle()
     WXDWORD style = WS_CHILD;
 
-    if ( flags & wxCLIP_CHILDREN )
-        style |= WS_CLIPCHILDREN;
+    // 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;
+
+    // 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 & wxCLIP_SIBLINGS )
-        style |= WS_CLIPSIBLINGS;
 
     if ( flags & wxVSCROLL )
         style |= WS_VSCROLL;
@@ -1217,6 +1243,7 @@ bool wxWindowMSW::IsMouseInWindow() const
 
 void wxWindowMSW::OnInternalIdle()
 {
+#ifdef __WXWINCE__
     // Check if we need to send a LEAVE event
     if ( m_mouseInWindow )
     {
@@ -1224,42 +1251,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;
-            if ( GetKeyState( VK_LBUTTON ) )
-                state |= MK_LBUTTON;
-            if ( GetKeyState( VK_MBUTTON ) )
-                state |= MK_MBUTTON;
-            if ( GetKeyState( VK_RBUTTON ) )
-                state |= MK_RBUTTON;
-
-            POINT pt;
-            if ( !::GetCursorPos(&pt) )
-            {
-                wxLogLastError(_T("GetCursorPos"));
-            }
-
-            // we need to have client coordinates here for symmetry with
-            // wxEVT_ENTER_WINDOW
-            RECT rect = wxGetWindowRect(GetHwnd());
-            pt.x -= rect.left;
-            pt.y -= rect.top;
-
-            wxMouseEvent event2(wxEVT_LEAVE_WINDOW);
-            InitMouseEvent(event2, pt.x, pt.y, state);
-
-            (void)GetEventHandler()->ProcessEvent(event2);
+            GenerateMouseLeave();
         }
     }
+#endif // !__WXWINCE__
 
     if (wxUpdateUIEvent::CanUpdate(this))
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
@@ -1376,6 +1371,8 @@ void wxWindowMSW::DragAcceptFiles(bool accept)
     HWND hWnd = GetHwnd();
     if ( hWnd )
         ::DragAcceptFiles(hWnd, (BOOL)accept);
+#else
+    wxUnusedVar(accept);
 #endif
 }
 
@@ -1501,9 +1498,31 @@ 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?*/) )
+
+    // if our parent had prepared a defer window handle for us, use it
+    wxWindowMSW *parent = GetParent();
+    HDWP hdwp = parent ? (HDWP)parent->m_hDWP : NULL;
+    if ( hdwp )
     {
-        wxLogLastError(wxT("MoveWindow"));
+        hdwp = ::DeferWindowPos(hdwp, GetHwnd(), NULL,
+                                x, y, width, height,
+                                SWP_NOZORDER);
+        if ( !hdwp )
+        {
+            wxLogLastError(_T("DeferWindowPos"));
+        }
+
+        // hdwp must be updated as it may have been changed
+        parent->m_hDWP = (WXHANDLE)hdwp;
+    }
+
+    // otherwise (or if deferring failed) move the window in place immediately
+    if ( !hdwp )
+    {
+        if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
+        {
+            wxLogLastError(wxT("MoveWindow"));
+        }
     }
 }
 
@@ -1530,15 +1549,15 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
         return;
     }
 
-    if ( x == wxDefaultPosition.x && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+    if ( x == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
         x = currentX;
-    if ( y == wxDefaultPosition.y && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
+    if ( y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) )
         y = currentY;
 
     AdjustForParentClientOrigin(x, y, sizeFlags);
 
     wxSize size = wxDefaultSize;
-    if ( width == wxDefaultSize.x )
+    if ( width == wxDefaultCoord )
     {
         if ( sizeFlags & wxSIZE_AUTO_WIDTH )
         {
@@ -1552,11 +1571,11 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
         }
     }
 
-    if ( height == wxDefaultSize.y )
+    if ( height == wxDefaultCoord )
     {
         if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
         {
-            if ( size.x == wxDefaultSize.x )
+            if ( size.x == wxDefaultCoord )
             {
                 size = DoGetBestSize();
             }
@@ -1594,8 +1613,8 @@ void wxWindowMSW::DoSetClientSize(int width, int height)
         ::GetClientRect(GetHwnd(), &rectClient);
 
         // if the size is already ok, stop here (rectClient.left = top = 0)
-        if ( (rectClient.right == width || width == wxDefaultSize.x) &&
-             (rectClient.bottom == height || height == wxDefaultSize.y) )
+        if ( (rectClient.right == width || width == wxDefaultCoord) &&
+             (rectClient.bottom == height || height == wxDefaultCoord) )
         {
             break;
         }
@@ -1663,31 +1682,22 @@ void wxWindowMSW::GetTextExtent(const wxString& string,
                              int *descent, int *externalLeading,
                              const wxFont *theFont) const
 {
-    const wxFont *fontToUse = theFont;
-    if ( !fontToUse )
-        fontToUse = &m_font;
+    wxASSERT_MSG( !theFont || theFont->Ok(),
+                    _T("invalid font in GetTextExtent()") );
 
-    HWND hWnd = GetHwnd();
-    HDC dc = ::GetDC(hWnd);
+    wxFont fontToUse;
+    if (theFont)
+        fontToUse = *theFont;
+    else
+        fontToUse = GetFont();
 
-    HFONT fnt = 0;
-    HFONT hfontOld = 0;
-    if ( fontToUse && fontToUse->Ok() )
-    {
-        fnt = (HFONT)((wxFont *)fontToUse)->GetResourceHandle(); // const_cast
-        if ( fnt )
-            hfontOld = (HFONT)SelectObject(dc,fnt);
-    }
+    WindowHDC hdc(GetHwnd());
+    SelectInHDC selectFont(hdc, GetHfontOf(fontToUse));
 
     SIZE sizeRect;
     TEXTMETRIC tm;
-    GetTextExtentPoint(dc, string, (int)string.Length(), &sizeRect);
-    GetTextMetrics(dc, &tm);
-
-    if ( fontToUse && fnt && hfontOld )
-        SelectObject(dc, hfontOld);
-
-    ReleaseDC(hWnd, dc);
+    GetTextExtentPoint(hdc, string, string.length(), &sizeRect);
+    GetTextMetrics(hdc, &tm);
 
     if ( x )
         *x = sizeRect.cx;
@@ -1737,7 +1747,7 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     menu->SetInvokingWindow(this);
     menu->UpdateUI();
 
-    if ( x == -1 && y == -1 )
+    if ( x == wxDefaultCoord && y == wxDefaultCoord )
     {
         wxPoint mouse = ScreenToClient(wxGetMousePosition());
         x = mouse.x; y = mouse.y;
@@ -1750,9 +1760,10 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
     point.y = y;
     ::ClientToScreen(hWnd, &point);
     wxCurrentPopupMenu = menu;
+#if defined(__WXWINCE__)
     UINT flags = 0;
-#if !defined(__WXWINCE__)
-    flags = TPM_RIGHTBUTTON;
+#else
+    UINT flags = TPM_RIGHTBUTTON;
 #endif
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
@@ -1797,7 +1808,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
         // here we try to do all the job which ::IsDialogMessage() usually does
         // internally
-#if 1
         if ( msg->message == WM_KEYDOWN )
         {
             bool bCtrlDown = wxIsCtrlDown();
@@ -1855,8 +1865,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
@@ -1897,7 +1920,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
@@ -1954,35 +1977,6 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 }
             }
         }
-#else // 0
-        // let ::IsDialogMessage() do almost everything and handle just the
-        // things it doesn't here: Ctrl-TAB for switching notebook pages
-        if ( msg->message == WM_KEYDOWN )
-        {
-            // don't process system keys here
-            if ( !(HIWORD(msg->lParam) & KF_ALTDOWN) )
-            {
-                if ( (msg->wParam == VK_TAB) && wxIsCtrlDown() )
-                {
-                    // find the first notebook parent and change its page
-                    wxWindow *win = this;
-                    wxNotebook *nbook = NULL;
-                    while ( win && !nbook )
-                    {
-                        nbook = wxDynamicCast(win, wxNotebook);
-                        win = win->GetParent();
-                    }
-
-                    if ( nbook )
-                    {
-                        bool forward = !wxIsShiftDown();
-
-                        nbook->AdvanceSelection(forward);
-                    }
-                }
-            }
-        }
-#endif // 1/0
 
         // don't let IsDialogMessage() get VK_ESCAPE as it _always_ eats the
         // message even when there is no cancel button and when the message is
@@ -2130,13 +2124,10 @@ void wxWindowMSW::UnpackScroll(WXWPARAM wParam, WXLPARAM lParam,
 }
 
 void wxWindowMSW::UnpackCtlColor(WXWPARAM wParam, WXLPARAM lParam,
-                              WXWORD *nCtlColor, WXHDC *hdc, WXHWND *hwnd)
+                                 WXHDC *hdc, WXHWND *hwnd)
 {
-#ifndef __WXMICROWIN__
-    *nCtlColor = CTLCOLOR_BTN;
     *hwnd = (WXHWND)lParam;
     *hdc = (WXHDC)wParam;
-#endif
 }
 
 void wxWindowMSW::UnpackMenuSelect(WXWPARAM wParam, WXLPARAM lParam,
@@ -2238,11 +2229,59 @@ 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;
+
         case WM_MOVE:
             processed = HandleMove(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
             break;
 
 #if !defined(__WXWINCE__)
+        // TODO: move those in WM_WINDOWPOSCHANGING case above
         case WM_MOVING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2260,37 +2299,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
-
-        case WM_SIZE:
-            switch ( wParam )
-            {
-                case SIZE_MAXHIDE:
-                case SIZE_MAXSHOW:
-                    // we're not interested in these messages at all
-                    break;
-
-                case SIZE_MINIMIZED:
-                    // we shouldn't send sizev events for these messages as the
-                    // client size may be negative which breaks existing code
-                    //
-                    // OTOH we might send another (wxMinimizedEvent?) one or
-                    // add an additional parameter to wxSizeEvent if this is
-                    // useful to anybody
-                    break;
-
-                default:
-                    wxFAIL_MSG( _T("unexpected WM_SIZE parameter") );
-                    // fall through nevertheless
-
-                case SIZE_MAXIMIZED:
-                case SIZE_RESTORED:
-                    processed = HandleSize(LOWORD(lParam), HIWORD(lParam),
-                                           wParam);
-            }
-            break;
 
-#if !defined(__WXWINCE__)
         case WM_SIZING:
             {
                 LPRECT pRect = (LPRECT)lParam;
@@ -2308,7 +2317,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 }
             }
             break;
-#endif
+#endif // !__WXWINCE__
 
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
@@ -2392,62 +2401,24 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                                         wParam);
             break;
 
-            // Seems to be broken currently
-#if 0 // ndef __WXWINCE__
+#ifdef WM_MOUSELEAVE
         case WM_MOUSELEAVE:
-           {
-            wxASSERT_MSG( !m_mouseInWindow, wxT("the mouse should be in a window to generate this event!") );
-           
-            // only process this message if the mouse is not in the window,
-            // This can also check for children in composite windows. 
-            // however, this may mean the the wxEVT_LEAVE_WINDOW is never sent
-            // if the mouse does not enter the window from it's child before 
-            // leaving the scope of the window. ( perhaps this can be picked
-            // up in the OnIdle code as before, for this special case )
-            if ( /*IsComposite() && */ !IsMouseInWindow() )
             {
-                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) )
+                // filter out excess WM_MOUSELEAVE events sent after PopupMenu() (on XP at least)
+                if ( m_mouseInWindow )
                 {
-                    wxLogLastError(_T("GetCursorPos"));
+                    GenerateMouseLeave();
                 }
 
-                // 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);
+                // 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;
             }
-            // 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__
-           
+            break;
+#endif // WM_MOUSELEAVE
+
 #if wxUSE_MOUSEWHEEL
         case WM_MOUSEWHEEL:
             processed = HandleMouseWheel(wParam, lParam);
@@ -2505,19 +2476,23 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // this should never happen
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
+                }
 
+                processed = win->HandleMouseEvent(message, x, y, wParam);
+
+                // if the app didn't eat the event, handle it in the default
+                // way, that is by giving this window the focus
+                if ( !processed )
+                {
                     // for the standard classes their WndProc sets the focus to
                     // them anyhow and doing it from here results in some weird
-                    // problems, but for our windows we want them to acquire
-                    // focus when clicked
+                    // problems, so don't do it for them (unnecessary anyhow)
                     if ( !win->IsOfStandardClass() )
                     {
                         if ( message == WM_LBUTTONDOWN && win->AcceptsFocus() )
                             win->SetFocus();
                     }
                 }
-
-                processed = win->HandleMouseEvent(message, x, y, wParam);
             }
             break;
 
@@ -2664,13 +2639,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     // special case of VK_APPS: treat it the same as right mouse
                     // click because both usually pop up a context menu
                     case VK_APPS:
-                        {
-                            WPARAM flags;
-                            int x, y;
-
-                            TranslateKbdEventToMouse(this, &x, &y, &flags);
-                            processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
-                        }
+                        processed = HandleMouseEvent(WM_RBUTTONDOWN, -1, -1, 0);
                         break;
 #endif // VK_APPS
 
@@ -2689,11 +2658,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             // special case of VK_APPS: treat it the same as right mouse button
             if ( wParam == VK_APPS )
             {
-                WPARAM flags;
-                int x, y;
-
-                TranslateKbdEventToMouse(this, &x, &y, &flags);
-                processed = HandleMouseEvent(WM_RBUTTONUP, x, y, flags);
+                processed = HandleMouseEvent(WM_RBUTTONUP, -1, -1, 0);
             }
             else
 #endif // VK_APPS
@@ -2738,7 +2703,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 
         // CTLCOLOR messages are sent by children to query the parent for their
-        // colors#ifndef __WXMICROWIN__
+        // colors
 #ifndef __WXMICROWIN__
         case WM_CTLCOLORMSGBOX:
         case WM_CTLCOLOREDIT:
@@ -2748,18 +2713,11 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
         case WM_CTLCOLORSCROLLBAR:
         case WM_CTLCOLORSTATIC:
             {
-                WXWORD nCtlColor;
                 WXHDC hdc;
                 WXHWND hwnd;
-                UnpackCtlColor(wParam, lParam, &nCtlColor, &hdc, &hwnd);
-
-                processed = HandleCtlColor(&rc.hBrush,
-                                           (WXHDC)hdc,
-                                           (WXHWND)hwnd,
-                                           nCtlColor,
-                                           message,
-                                           wParam,
-                                           lParam);
+                UnpackCtlColor(wParam, lParam, &hdc, &hwnd);
+
+                processed = HandleCtlColor(&rc.hBrush, (WXHDC)hdc, (WXHWND)hwnd);
             }
             break;
 #endif // !__WXMICROWIN__
@@ -3013,7 +2971,7 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
 
     bool nonDefault = false;
 
-    if ( pos.x == wxDefaultPosition.x )
+    if ( pos.x == wxDefaultCoord )
     {
         // if x is set to CW_USEDEFAULT, y parameter is ignored anyhow so we
         // can just as well set it to CW_USEDEFAULT as well
@@ -3026,7 +2984,7 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
         // neither because it is not handled as a special value by Windows then
         // and so we have to choose some default value for it
         x = pos.x;
-        y = pos.y == wxDefaultPosition.y ? DEFAULT_Y : pos.y;
+        y = pos.y == wxDefaultCoord ? DEFAULT_Y : pos.y;
 
         nonDefault = true;
     }
@@ -3048,7 +3006,7 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
           already has - so no WM_SIZE would be sent.
      */
 
-    
+
     // we don't use CW_USEDEFAULT here for several reasons:
     //
     //  1. it results in huge frames on modern screens (1000*800 is not
@@ -3070,16 +3028,16 @@ bool wxWindowMSW::MSWGetCreateWindowCoords(const wxPoint& pos,
     // However, on PocketPC devices, we must use the default
     // size if possible.
 #ifdef _WIN32_WCE
-    if (size.x == wxDefaultSize.x)
+    if (size.x == wxDefaultCoord)
         w = CW_USEDEFAULT;
     else
         w = size.x;
-    if (size.y == wxDefaultSize.y)
+    if (size.y == wxDefaultCoord)
         h = CW_USEDEFAULT;
     else
         h = size.y;
 #else
-    if ( size.x == wxDefaultSize.x || size.y == wxDefaultSize.y)
+    if ( size.x == wxDefaultCoord || size.y == wxDefaultCoord)
     {
         nonDefault = true;
     }
@@ -3124,7 +3082,7 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
     // do create the window
     wxWindowCreationHook hook(this);
 
-    // VZ: anyonce cares to explain why is this done for CE?
+    // VZ: anyone care to explain why this is done for CE?
 #ifdef __WXWINCE__
     if (extendedStyle == 0)
     {
@@ -3315,6 +3273,8 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
             return true;
         }
     }
+#else
+    wxUnusedVar(lParam);
 #endif // wxUSE_TOOLTIPS
 
     return false;
@@ -3383,6 +3343,8 @@ bool wxWindowMSW::HandleCreate(WXLPCREATESTRUCT cs, bool *mayCreate)
 #ifndef __WXWINCE__
     if ( ((CREATESTRUCT *)cs)->dwExStyle & WS_EX_CONTROLPARENT )
         EnsureParentHasControlParentStyle(GetParent());
+#else
+    wxUnusedVar(cs);
 #endif // !__WXWINCE__
 
     // TODO: should generate this event from WM_NCCREATE
@@ -3431,6 +3393,13 @@ bool wxWindowMSW::HandleActivate(int state,
 
 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
 {
+    // Strangly enough, some controls get set focus events when they are being
+    // deleted, even if they already had focus before.
+    if ( m_isBeingDeleted )
+    {
+        return false;
+    }
+
     // notify the parent keeping track of focus for the kbd navigation
     // purposes that we got it
     wxChildFocusEvent eventFocus((wxWindow *)this);
@@ -3505,7 +3474,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);
 }
@@ -3513,7 +3482,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);
 }
@@ -3521,6 +3490,7 @@ bool wxWindowMSW::HandleInitDialog(WXHWND WXUNUSED(hWndFocus))
 bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
 {
 #if defined (__WXMICROWIN__) || defined(__WXWINCE__)
+    wxUnusedVar(wParam);
     return false;
 #else // __WXMICROWIN__
     HDROP hFilesInfo = (HDROP) wParam;
@@ -3547,7 +3517,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);
@@ -3667,7 +3637,8 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+        wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+                         false, _T("MSWOnDrawItem: bad wxMenuItem pointer") );
 
         // prepare to call OnDrawItem(): notice using of wxDCTemp to prevent
         // the DC from being released
@@ -3695,7 +3666,7 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
 #else // !wxUSE_OWNER_DRAWN
     // we may still have owner-drawn buttons internally because we have to make
     // them owner-drawn to support colour change
-    wxControl *item = 
+    wxControl *item =
 #                     if wxUSE_BUTTON
                          wxDynamicCast(FindItem(id), wxButton)
 #                     else
@@ -3715,9 +3686,7 @@ wxWindowMSW::MSWOnDrawItem(int WXUNUSED_UNLESS_ODRAWN(id),
 }
 
 bool
-wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
-                              WXMEASUREITEMSTRUCT *
-                                  WXUNUSED_UNLESS_ODRAWN(itemStruct))
+wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
 {
 #if wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
     // is it a menu item?
@@ -3726,7 +3695,8 @@ wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
-        wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), false );
+        wxCHECK_MSG( pMenuItem && pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)),
+                        false, _T("MSWOnMeasureItem: bad wxMenuItem pointer") );
 
         size_t w, h;
         bool rc = pMenuItem->OnMeasureItem(&w, &h);
@@ -3742,7 +3712,10 @@ wxWindowMSW::MSWOnMeasureItem(int WXUNUSED_UNLESS_ODRAWN(id),
     {
         return item->MSWOnMeasure(itemStruct);
     }
-#endif // wxUSE_OWNER_DRAWN
+#else
+    wxUnusedVar(id);
+    wxUnusedVar(itemStruct);
+#endif // wxUSE_OWNER_DRAWN && wxUSE_MENUS_NATIVE
 
     return false;
 }
@@ -3771,50 +3744,24 @@ bool wxWindowMSW::HandleDisplayChange()
     return GetEventHandler()->ProcessEvent(event);
 }
 
-bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush,
-                              WXHDC pDC,
-                              WXHWND pWnd,
-                              WXUINT nCtlColor,
-                              WXUINT message,
-                              WXWPARAM wParam,
-                              WXLPARAM lParam)
-{
 #ifndef __WXMICROWIN__
-    WXHBRUSH hBrush = 0;
 
-#ifdef __WXWINCE__
-    if (false)
-#else
-    if ( nCtlColor == CTLCOLOR_DLG )
-#endif
-    {
-        hBrush = OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
-    }
+bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush, WXHDC pDC, WXHWND pWnd)
+{
 #if wxUSE_CONTROLS
+    wxWindow *item = FindItemByHWND(pWnd, true);
+    if ( item )
+        *brush = item->MSWControlColor(pDC);
     else
-    {
-        wxControl *item = (wxControl *)FindItemByHWND(pWnd, true);
-        if ( item )
-            hBrush = item->OnCtlColor(pDC, pWnd, nCtlColor, message, wParam, lParam);
-    }
 #endif // wxUSE_CONTROLS
+        *brush = NULL;
 
-    if ( hBrush )
-        *brush = hBrush;
-
-    return hBrush != 0;
-#else // __WXMICROWIN__
-    return false;
-#endif
+    return *brush != NULL;
 }
 
-// Define for each class of dialog and control
-WXHBRUSH wxWindowMSW::OnCtlColor(WXHDC WXUNUSED(hDC),
-                                 WXHWND WXUNUSED(hWnd),
-                                 WXUINT WXUNUSED(nCtlColor),
-                                 WXUINT WXUNUSED(message),
-                                 WXWPARAM WXUNUSED(wParam),
-                                 WXLPARAM WXUNUSED(lParam))
+#endif // __WXMICROWIN__
+
+WXHBRUSH wxWindowMSW::MSWControlColor(WXHDC WXUNUSED(hDC))
 {
     return (WXHBRUSH)0;
 }
@@ -3928,18 +3875,6 @@ void wxWindowMSW::OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event))
 
         node = node->GetNext();
     }
-
-    // update the colours we use if they were not set explicitly by the user:
-    // this must be done or OnCtlColor() would continue to use the old colours
-    if ( !m_hasFgCol || !m_hasBgCol )
-    {
-        wxVisualAttributes attrs = GetDefaultAttributes();
-        if ( !m_hasFgCol )
-            m_foregroundColour = attrs.colFg;
-
-        if ( !m_hasBgCol )
-            m_backgroundColour = attrs.colBg;
-    }
 }
 
 extern wxCOLORMAP *wxGetStdColourMap()
@@ -4014,9 +3949,6 @@ extern wxCOLORMAP *wxGetStdColourMap()
 
 bool wxWindowMSW::HandlePaint()
 {
-//    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
-//        return FALSE;
-
     HRGN hRegion = ::CreateRectRgn(0, 0, 0, 0); // Dummy call to get a handle
     if ( !hRegion )
         wxLogLastError(wxT("CreateRectRgn"));
@@ -4056,33 +3988,6 @@ void wxWindowMSW::OnPaint(wxPaintEvent& event)
 
 bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 {
-    // Prevents flicker when dragging
-    if ( ::IsIconic(GetHwnd()) )
-        return true;
-
-#if 0
-    if (GetParent() && GetParent()->GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
-    {
-        return false;
-    }
-
-    if (GetExtraStyle() & wxWS_EX_THEMED_BACKGROUND)
-    {
-        if (wxUxThemeEngine::Get())
-        {
-            WXHTHEME hTheme = wxUxThemeEngine::Get()->m_pfnOpenThemeData(GetHWND(), L"TAB");
-            if (hTheme)
-            {
-                WXURECT rect;
-                ::GetClientRect((HWND) GetHWND(), (RECT*) & rect);
-                wxUxThemeEngine::Get()->m_pfnDrawThemeBackground(hTheme, hdc, 10 /* TABP_BODY */, 0, &rect, &rect);
-                wxUxThemeEngine::Get()->m_pfnCloseThemeData(hTheme);
-                return true;
-            }
-        }
-    }
-#endif
-
     wxDCTemp dc(hdc);
 
     dc.SetHDC(hdc);
@@ -4103,29 +4008,104 @@ bool wxWindowMSW::HandleEraseBkgnd(WXHDC hdc)
 
 void wxWindowMSW::OnEraseBackground(wxEraseEvent& event)
 {
-    RECT rect;
-    ::GetClientRect(GetHwnd(), &rect);
-    
-    wxColour backgroundColour( GetBackgroundColour());
-    COLORREF ref = PALETTERGB(backgroundColour.Red(),
-                              backgroundColour.Green(),
-                              backgroundColour.Blue());
-    HBRUSH hBrush = ::CreateSolidBrush(ref);
+    // 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;
+    }
+
+    if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
+    {
+        // don't skip the event here, custom background means that the app
+        // is drawing it itself in its OnPaint(), so don't draw it at all
+        // now to avoid flicker
+        return;
+    }
+
+
+    // do default background painting
+    if ( !DoEraseBackground(*event.GetDC()) )
+    {
+        // let the system paint the background
+        event.Skip();
+    }
+}
+
+bool wxWindowMSW::DoEraseBackground(wxDC& dc)
+{
+    HBRUSH hBrush = (HBRUSH)MSWGetBgBrush(dc.GetHDC());
     if ( !hBrush )
-        wxLogLastError(wxT("CreateSolidBrush"));
+        return false;
 
-    HDC hdc = (HDC)event.GetDC()->GetHDC();
+    RECT rc;
+    ::GetClientRect(GetHwnd(), &rc);
+    ::FillRect(GetHdcOf(dc), &rc, hBrush);
 
-#ifndef __WXWINCE__
-    int mode = ::SetMapMode(hdc, MM_TEXT);
-#endif
+    return true;
+}
 
-    ::FillRect(hdc, &rect, hBrush);
-    ::DeleteObject(hBrush);
+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);
 
-#ifndef __WXWINCE__
-    ::SetMapMode(hdc, mode);
-#endif
+        return (WXHBRUSH)brush->GetResourceHandle();
+    }
+
+    return 0;
+}
+
+wxColour wxWindowMSW::MSWGetBgColourForChild(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 ||
+                    (child->HasTransparentBackground() &&
+                        child->GetParent() == this) )
+        {
+            return GetBackgroundColour();
+        }
+    }
+
+    return wxNullColour;
+}
+
+WXHBRUSH wxWindowMSW::MSWGetBgBrushForSelf(wxWindow *parent, WXHDC hDC)
+{
+    return parent->MSWGetBgBrushForChild(hDC, (wxWindow *)this);
+}
+
+WXHBRUSH wxWindowMSW::MSWGetBgBrush(WXHDC hDC)
+{
+    for ( wxWindow *win = (wxWindow *)this; win; win = win->GetParent() )
+    {
+        WXHBRUSH hBrush = MSWGetBgBrushForSelf(win, hDC);
+        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) )
+            break;
+    }
+
+    return 0;
 }
 
 // ---------------------------------------------------------------------------
@@ -4150,7 +4130,8 @@ bool wxWindowMSW::HandleMaximize()
 
 bool wxWindowMSW::HandleMove(int x, int y)
 {
-    wxMoveEvent event(wxPoint(x, y), m_windowId);
+    wxPoint point(x,y);
+    wxMoveEvent event(point, m_windowId);
     event.SetEventObject(this);
 
     return GetEventHandler()->ProcessEvent(event);
@@ -4167,16 +4148,40 @@ bool wxWindowMSW::HandleMoving(wxRect& rect)
     return rc;
 }
 
-bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h),
-                             WXUINT WXUNUSED(flag))
+bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
 {
-    // don't use w and h parameters as they specify the client size while
-    // according to the docs EVT_SIZE handler is supposed to receive the total
-    // size
-    wxSizeEvent event(GetSize(), m_windowId);
-    event.SetEventObject(this);
+    bool processed = false;
 
-    return GetEventHandler()->ProcessEvent(event);
+    switch ( wParam )
+    {
+        default:
+            wxFAIL_MSG( _T("unexpected WM_SIZE parameter") );
+            // fall through nevertheless
+
+        case SIZE_MAXHIDE:
+        case SIZE_MAXSHOW:
+            // we're not interested in these messages at all
+            break;
+
+        case SIZE_MINIMIZED:
+            processed = HandleMinimize();
+            break;
+
+        case SIZE_MAXIMIZED:
+            /* processed = */ HandleMaximize();
+            // fall through to send a normal size event as well
+
+        case SIZE_RESTORED:
+            // don't use w and h parameters as they specify the client size
+            // while according to the docs EVT_SIZE handler is supposed to
+            // receive the total size
+            wxSizeEvent event(GetSize(), m_windowId);
+            event.SetEventObject(this);
+
+            processed = GetEventHandler()->ProcessEvent(event);
+    }
+
+    return processed;
 }
 
 bool wxWindowMSW::HandleSizing(wxRect& rect)
@@ -4193,6 +4198,7 @@ bool wxWindowMSW::HandleSizing(wxRect& rect)
 bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
 {
 #ifdef __WXWINCE__
+    wxUnusedVar(mmInfo);
     return false;
 #else
     MINMAXINFO *info = (MINMAXINFO *)mmInfo;
@@ -4204,25 +4210,25 @@ bool wxWindowMSW::HandleGetMinMaxInfo(void *mmInfo)
         maxWidth = GetMaxWidth(),
         maxHeight = GetMaxHeight();
 
-    if ( minWidth != wxDefaultSize.x )
+    if ( minWidth != wxDefaultCoord )
     {
         info->ptMinTrackSize.x = minWidth;
         rc = true;
     }
 
-    if ( minHeight != wxDefaultSize.y )
+    if ( minHeight != wxDefaultCoord )
     {
         info->ptMinTrackSize.y = minHeight;
         rc = true;
     }
 
-    if ( maxWidth != wxDefaultSize.x )
+    if ( maxWidth != wxDefaultCoord )
     {
         info->ptMaxTrackSize.x = maxWidth;
         rc = true;
     }
 
-    if ( maxHeight != wxDefaultSize.y )
+    if ( maxHeight != wxDefaultCoord )
     {
         info->ptMaxTrackSize.y = maxHeight;
         rc = true;
@@ -4318,16 +4324,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
@@ -4404,7 +4407,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
     // the mouse events take consecutive IDs from WM_MOUSEFIRST to
-    // WM_MOUSELAST, so it's enough to substract WM_MOUSEMOVE == WM_MOUSEFIRST
+    // WM_MOUSELAST, so it's enough to subtract WM_MOUSEMOVE == WM_MOUSEFIRST
     // from the message id and take the value in the table to get wxWin event
     // id
     static const wxEventType eventsMouse[] =
@@ -4439,7 +4442,6 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
         {
             // Generate an ENTER event
             m_mouseInWindow = true;
-#if _WIN32_WINNT >= 0x0400
 #ifndef __WXWINCE__
             TRACKMOUSEEVENT trackinfo;
 
@@ -4448,10 +4450,9 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             trackinfo.hwndTrack = GetHwnd();
             //Use the commctrl.h _TrackMouseEvent, which will call the
             // appropriate TrackMouseEvent or emulate it ( win95 )
-            // else we need _WIN32_WINNT >= 0x0400 
+            // else we need _WIN32_WINNT >= 0x0400
             _TrackMouseEvent(&trackinfo);
-#endif
-#endif
+#endif // __WXWINCE__
             wxMouseEvent event(wxEVT_ENTER_WINDOW);
             InitMouseEvent(event, x, y, flags);
 
@@ -4506,14 +4507,49 @@ 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;
+    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 event(wxEVT_LEAVE_WINDOW);
+    InitMouseEvent(event, pt.x, pt.y, state);
+
+    (void)GetEventHandler()->ProcessEvent(event);
+}
 
 // ---------------------------------------------------------------------------
 // keyboard handling
@@ -4532,8 +4568,11 @@ 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;
+#endif
     event.m_rawCode = (wxUint32) wParam;
     event.m_rawFlags = (wxUint32) lParam;
 #ifndef __WXWINCE__
@@ -4696,7 +4735,7 @@ int wxWindowMSW::HandleMenuChar(int chAccel, WXLPARAM lParam)
                         // FIXME-UNICODE: this comparison doesn't risk to work
                         // for non ASCII accelerator characters I'm afraid, but
                         // what can we do?
-                        if ( wxToupper(*p) == chAccel )
+                        if ( (wchar_t)wxToupper(*p) == (wchar_t)chAccel )
                         {
                             return i;
                         }
@@ -4821,7 +4860,7 @@ bool wxWindowMSW::HandleJoystickEvent(WXUINT msg, int x, int y, WXUINT flags)
 
 bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
                               WXWORD pos, WXHWND control)
-{    
+{
     if ( control && control != m_hWnd ) // Prevent infinite recursion
     {
         wxWindow *child = wxFindWinFromHandle(control);
@@ -4832,32 +4871,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:
@@ -4883,9 +4922,9 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
             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:
@@ -4899,22 +4938,20 @@ bool wxWindowMSW::MSWOnScroll(int orientation, WXWORD wParam,
 // global functions
 // ===========================================================================
 
-void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font)
+void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFontthe_font)
 {
     TEXTMETRIC tm;
     HDC dc = ::GetDC((HWND) wnd);
-    HFONT fnt =0;
     HFONT was = 0;
-    if ( the_font )
-    {
-        //    the_font->UseResource();
-        //    the_font->RealizeResource();
-        fnt = (HFONT)((wxFont *)the_font)->GetResourceHandle(); // const_cast
-        if ( fnt )
-            was = (HFONT) SelectObject(dc,fnt);
-    }
+
+    //    the_font.UseResource();
+    //    the_font.RealizeResource();
+    HFONT fnt = (HFONT)the_font.GetResourceHandle(); // const_cast
+    if ( fnt )
+        was = (HFONT) SelectObject(dc,fnt);
+
     GetTextMetrics(dc, &tm);
-    if ( the_font && fnt && was )
+    if ( fnt && was )
     {
         SelectObject(dc,was);
     }
@@ -4925,8 +4962,7 @@ void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font)
     if ( y )
         *y = tm.tmHeight + tm.tmExternalLeading;
 
-    //  if ( the_font )
-    //    the_font->ReleaseResource();
+    //   the_font.ReleaseResource();
 }
 
 // Returns 0 if was a normal ASCII value, not a special key. This indicates that
@@ -5003,6 +5039,8 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
         case VK_NUMLOCK:    id = WXK_NUMLOCK; break;
         case VK_SCROLL:     id = WXK_SCROLL; break;
 
+        // 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;
@@ -5035,10 +5073,10 @@ int wxCharCodeMSWToWX(int keySym, WXLPARAM lParam)
     return id;
 }
 
-int wxCharCodeWXToMSW(int id, bool *isVirtual)
+WXWORD wxCharCodeWXToMSW(int id, bool *isVirtual)
 {
     *isVirtual = true;
-    int keySym;
+    WXWORD keySym;
     switch (id)
     {
     case WXK_CANCEL:    keySym = VK_CANCEL; break;
@@ -5107,7 +5145,7 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual)
     default:
         {
             *isVirtual = false;
-            keySym = id;
+            keySym = (WORD)id;
             break;
         }
     }
@@ -5117,25 +5155,32 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual)
 bool wxGetKeyState(wxKeyCode key)
 {
     bool bVirtual;
-    int vkey = wxCharCodeWXToMSW(key, &bVirtual);
-    SHORT state;
 
-    switch (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)
     {
-    case WXK_NUMLOCK:
-    case WXK_CAPITAL:
-    case WXK_SCROLL:
-        // get the toggle state of the special key
-        state = GetKeyState(vkey);
-        break;
-        
-    default:
-        // Get the current state of the physical key
-        state = GetAsyncKeyState(vkey);
-        break;
+#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;
+
+#ifdef __WIN32__
+    }
+    else
+    {
+        //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;
     }
-    // if the most significant bit is set then the key is down
-    return ( state & 0x0001 ) != 0;
+#endif
 }
 
 wxWindow *wxGetActiveWindow()
@@ -5247,7 +5292,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();
@@ -5692,26 +5737,6 @@ const char *wxGetMessageName(int message)
 }
 #endif //__WXDEBUG__
 
-static void TranslateKbdEventToMouse(wxWindowMSW *win,
-                                     int *x, int *y, WPARAM *flags)
-{
-    // construct the key mask
-    WPARAM& fwKeys = *flags;
-
-    fwKeys = MK_RBUTTON;
-    if ( wxIsCtrlDown() )
-        fwKeys |= MK_CONTROL;
-    if ( wxIsShiftDown() )
-        fwKeys |= MK_SHIFT;
-
-    // simulate right mouse button click
-    DWORD dwPos = ::GetMessagePos();
-    *x = GET_X_LPARAM(dwPos);
-    *y = GET_Y_LPARAM(dwPos);
-
-    win->ScreenToClient(x, y);
-}
-
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win)
 {
     // prepare the DC
@@ -5877,7 +5902,11 @@ public:
     static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
     {
         MSG *msg = (MSG*)lParam;
-        if ( msg->message == WM_NULL )
+
+        // only process the message if it is actually going to be removed from
+        // the message queue, this prevents that the same event from being
+        // processed multiple times if now someone just called PeekMessage()
+        if ( msg->message == WM_NULL && wParam == PM_REMOVE )
         {
             wxTheApp->ProcessPendingEvents();
         }
@@ -5897,3 +5926,36 @@ IMPLEMENT_DYNAMIC_CLASS(wxIdleWakeUpModule, wxModule)
 
 #endif // __WXWINCE__
 
+#ifdef __WXWINCE__
+
+#if wxUSE_STATBOX
+static void wxAdjustZOrder(wxWindow* parent)
+{
+    if (parent->IsKindOf(CLASSINFO(wxStaticBox)))
+    {
+        // Set the z-order correctly
+        SetWindowPos((HWND) parent->GetHWND(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+    }
+
+    wxWindowList::compatibility_iterator current = parent->GetChildren().GetFirst();
+    while (current)
+    {
+        wxWindow *childWin = current->GetData();
+        wxAdjustZOrder(childWin);
+        current = current->GetNext();
+    }
+}
+#endif
+
+// We need to adjust the z-order of static boxes in WinCE, to
+// make 'contained' controls visible
+void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event )
+{
+#if wxUSE_STATBOX
+    wxAdjustZOrder(this);
+#endif
+
+    event.Skip();
+}
+#endif
+