]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Applied patch [ 1399013 ] More removals of extraneous semicolons
[wxWidgets.git] / src / msw / window.cpp
index ca9fe433c6042f2d741e11a75fc66f5bd3614184..08567e34a4507132a99a1393038082f4964e4134 100644 (file)
@@ -1,6 +1,6 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/msw/windows.cpp
-// Purpose:     wxWindow
+// Name:        src/msw/window.cpp
+// Purpose:     wxWindowMSW
 // Author:      Julian Smart
 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
 // Created:     04/01/98
 // Author:      Julian Smart
 // Modified by: VZ on 13.05.99: no more Default(), MSWOnXXX() reorganisation
 // Created:     04/01/98
 // headers
 // ---------------------------------------------------------------------------
 
 // headers
 // ---------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "window.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // by setting this to 0 (in the future this should be removed completely)
 #define USE_DEFERRED_SIZING 1
 
 // by setting this to 0 (in the future this should be removed completely)
 #define USE_DEFERRED_SIZING 1
 
+// set this to 1 to filter out duplicate mouse events, e.g. mouse move events
+// when mouse position didnd't change
+#ifdef __WXWINCE__
+    #define wxUSE_MOUSEEVENT_HACK 0
+#else
+    #define wxUSE_MOUSEEVENT_HACK 1
+#endif
+
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // global variables
 // ---------------------------------------------------------------------------
@@ -145,6 +149,18 @@ extern const wxChar *wxCanvasClassName;
 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT)
 static bool gs_hasStdCmap = false;
 
 // wxGetStdColourMap() and wxWindow::OnSysColourChanged()           (FIXME-MT)
 static bool gs_hasStdCmap = false;
 
+// last mouse event information we need to filter out the duplicates
+#if wxUSE_MOUSEEVENT_HACK
+static struct MouseEventInfoDummy
+{
+    // mouse position (in screen coordinates)
+    wxPoint pos;
+
+    // last mouse event type
+    wxEventType type;
+} gs_lastMouseEvent;
+#endif // wxUSE_MOUSEEVENT_HACK
+
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // private functions
 // ---------------------------------------------------------------------------
@@ -165,8 +181,10 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
 // get the text metrics for the current font
 static TEXTMETRIC wxGetTextMetrics(const wxWindowMSW *win);
 
+#ifdef __WXWINCE__
 // find the window for the mouse event at the specified position
 // find the window for the mouse event at the specified position
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y); //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y);
+#endif // __WXWINCE__
 
 // wrapper around BringWindowToTop() API
 static inline void wxBringWindowToTop(HWND hwnd)
 
 // wrapper around BringWindowToTop() API
 static inline void wxBringWindowToTop(HWND hwnd)
@@ -202,7 +220,7 @@ static void EnsureParentHasControlParentStyle(wxWindow *parent)
        get back to the initial (focused) window: as we do have this style,
        GetNextDlgTabItem() will leave this window and continue in its parent,
        but if the parent doesn't have it, it wouldn't recurse inside it later
        get back to the initial (focused) window: as we do have this style,
        GetNextDlgTabItem() will leave this window and continue in its parent,
        but if the parent doesn't have it, it wouldn't recurse inside it later
-       on and so wouldn't have a chance of getting back to this window neither.
+       on and so wouldn't have a chance of getting back to this window either.
      */
     while ( parent && !parent->IsTopLevel() )
     {
      */
     while ( parent && !parent->IsTopLevel() )
     {
@@ -376,7 +394,7 @@ wxWindow *wxWindowMSW::FindItem(long id) const
     wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
     wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
-        // is it we or one of our "internal" children?
+        // is it us or one of our "internal" children?
         if ( item->GetId() == id
 #ifndef __WXUNIVERSAL__
                 || (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
         if ( item->GetId() == id
 #ifndef __WXUNIVERSAL__
                 || (item->GetSubcontrols().Index(id) != wxNOT_FOUND)
@@ -464,12 +482,6 @@ void wxWindowMSW::Init()
     m_xThumbSize = 0;
     m_yThumbSize = 0;
 
     m_xThumbSize = 0;
     m_yThumbSize = 0;
 
-#if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX =
-    m_lastMouseY = -1;
-    m_lastMouseEvent = -1;
-#endif // wxUSE_MOUSEEVENT_HACK
-
     m_pendingPosition = wxDefaultPosition;
     m_pendingSize = wxDefaultSize;
 }
     m_pendingPosition = wxDefaultPosition;
     m_pendingSize = wxDefaultSize;
 }
@@ -501,7 +513,7 @@ wxWindowMSW::~wxWindowMSW()
 #endif // __WXUNIVERSAL__
 
     // VS: destroy children first and _then_ detach *this from its parent.
 #endif // __WXUNIVERSAL__
 
     // VS: destroy children first and _then_ detach *this from its parent.
-    //     If we'd do it the other way around, children wouldn't be able
+    //     If we did it the other way around, children wouldn't be able
     //     find their parent frame (see above).
     DestroyChildren();
 
     //     find their parent frame (see above).
     DestroyChildren();
 
@@ -653,7 +665,7 @@ bool wxWindowMSW::Enable(bool enable)
 
         if ( enable )
         {
 
         if ( enable )
         {
-            // enable the child back unless it had been disabled before us
+            // re-enable the child unless it had been disabled before us
             if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
                 child->Enable();
         }
             if ( !m_childrenDisabled || !m_childrenDisabled->Find(child) )
                 child->Enable();
         }
@@ -692,12 +704,18 @@ bool wxWindowMSW::Show(bool show)
         return false;
 
     HWND hWnd = GetHwnd();
         return false;
 
     HWND hWnd = GetHwnd();
-    int cshow = show ? SW_SHOW : SW_HIDE;
-    ::ShowWindow(hWnd, cshow);
 
 
-    if ( show && IsTopLevel() )
+    // we could be called before the underlying window is created (this is
+    // actually useful to prevent it from being initially shown), e.g.
+    //
+    //      wxFoo *foo = new wxFoo;
+    //      foo->Hide();
+    //      foo->Create(parent, ...);
+    //
+    // should work without errors
+    if ( hWnd )
     {
     {
-        wxBringWindowToTop(hWnd);
+        ::ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
     }
 
     return true;
     }
 
     return true;
@@ -716,16 +734,6 @@ void wxWindowMSW::Lower()
                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 }
 
                    SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 }
 
-void wxWindowMSW::SetTitle( const wxString& title)
-{
-    SetWindowText(GetHwnd(), title.c_str());
-}
-
-wxString wxWindowMSW::GetTitle() const
-{
-    return wxGetWindowText(GetHWND());
-}
-
 void wxWindowMSW::DoCaptureMouse()
 {
     HWND hWnd = GetHwnd();
 void wxWindowMSW::DoCaptureMouse()
 {
     HWND hWnd = GetHwnd();
@@ -798,7 +806,7 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
     return true;
 }
 
     return true;
 }
 
-void wxWindowMSW::WarpPointer (int x, int y)
+void wxWindowMSW::WarpPointer(int x, int y)
 {
     ClientToScreen(&x, &y);
 
 {
     ClientToScreen(&x, &y);
 
@@ -808,6 +816,26 @@ void wxWindowMSW::WarpPointer (int x, int y)
     }
 }
 
     }
 }
 
+void wxWindowMSW::MSWUpdateUIState(int action, int state)
+{
+    // WM_CHANGEUISTATE only appeared in Windows 2000 so it can do us no good
+    // to use it on older systems -- and could possibly do some harm
+    static int s_needToUpdate = -1;
+    if ( s_needToUpdate == -1 )
+    {
+        int verMaj, verMin;
+        s_needToUpdate = wxGetOsVersion(&verMaj, &verMin) == wxWINDOWS_NT &&
+                            verMaj >= 5;
+    }
+
+    if ( s_needToUpdate )
+    {
+        // we send WM_CHANGEUISTATE so if nothing needs changing then the system
+        // won't send WM_UPDATEUISTATE
+        ::SendMessage(GetHwnd(), WM_CHANGEUISTATE, MAKEWPARAM(action, state), 0);
+    }
+}
+
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // scrolling stuff
 // ---------------------------------------------------------------------------
@@ -820,15 +848,10 @@ inline int GetScrollPosition(HWND hWnd, int wOrient)
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
     WinStruct<SCROLLINFO> scrollInfo;
     scrollInfo.cbSize = sizeof(SCROLLINFO);
     scrollInfo.fMask = SIF_POS;
-    if ( !::GetScrollInfo(hWnd,
-                          wOrient,
-                          &scrollInfo) )
-    {
-        // Not necessarily an error, if there are no scrollbars yet.
-        // wxLogLastError(_T("GetScrollInfo"));
-    }
+    ::GetScrollInfo(hWnd, wOrient, &scrollInfo );
+
     return scrollInfo.nPos;
     return scrollInfo.nPos;
-//    return ::GetScrollPos(hWnd, wOrient);
+
 #endif
 }
 
 #endif
 }
 
@@ -915,11 +938,13 @@ void wxWindowMSW::SetScrollbar(int orient,
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
     HWND hWnd = GetHwnd();
     if ( hWnd )
     {
+        // We have to set the variables here to make them valid in events
+        // triggered by ::SetScrollInfo()
+        *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
+        
         ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
                         &info, refresh);
     }
         ::SetScrollInfo(hWnd, orient == wxHORIZONTAL ? SB_HORZ : SB_VERT,
                         &info, refresh);
     }
-
-    *(orient == wxHORIZONTAL ? &m_xThumbSize : &m_yThumbSize) = pageSize;
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
 }
 
 void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
@@ -1011,7 +1036,7 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     }
     else
     {
     }
     else
     {
-        // don't bother restoring it neither: this also makes it easy to
+        // don't bother restoring it either: this also makes it easy to
         // implement IsOfStandardClass() method which returns true for the
         // standard controls and false for the wxWidgets own windows as it can
         // simply check m_oldWndProc
         // implement IsOfStandardClass() method which returns true for the
         // standard controls and false for the wxWidgets own windows as it can
         // simply check m_oldWndProc
@@ -1092,8 +1117,8 @@ bool wxCheckWindowWndProc(WXHWND hWnd,
         str == wxMDIChildFrameClassNameNoRedraw ||
         str == _T("wxTLWHiddenParent"))
         return true; // Effectively means don't subclass
         str == wxMDIChildFrameClassNameNoRedraw ||
         str == _T("wxTLWHiddenParent"))
         return true; // Effectively means don't subclass
-    else
-        return false;
+
+    return false;
 #else
     WNDCLASS cls;
     if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
 #else
     WNDCLASS cls;
     if ( !::GetClassInfo(wxGetInstance(), wxGetWindowClass(hWnd), &cls) )
@@ -1175,7 +1200,7 @@ WXDWORD wxWindowMSW::MSWGetStyle(long flags, WXDWORD *exstyle) const
 
     // using this flag results in very significant reduction in flicker,
     // especially with controls inside the static boxes (as the interior of the
 
     // using this flag results in very significant reduction in flicker,
     // especially with controls inside the static boxes (as the interior of the
-    // box is not redrawn twice).but sometimes results in redraw problems, so
+    // box is not redrawn twice)but sometimes results in redraw problems, so
     // optionally allow the old code to continue to use it provided a special
     // system option is turned on
     if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children"))
     // optionally allow the old code to continue to use it provided a special
     // system option is turned on
     if ( !wxSystemOptions::GetOptionInt(wxT("msw.window.no-clip-children"))
@@ -1419,7 +1444,7 @@ void wxWindowMSW::SetDropTarget(wxDropTarget *pDropTarget)
 }
 #endif // wxUSE_DRAG_AND_DROP
 
 }
 #endif // wxUSE_DRAG_AND_DROP
 
-// old style file-manager drag&drop support: we retain the old-style
+// old-style file manager drag&drop support: we retain the old-style
 // DragAcceptFiles in parallel with SetDropTarget.
 void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept))
 {
 // DragAcceptFiles in parallel with SetDropTarget.
 void wxWindowMSW::DragAcceptFiles(bool WXUNUSED_IN_WINCE(accept))
 {
@@ -1450,6 +1475,17 @@ void wxWindowMSW::DoSetToolTip(wxToolTip *tooltip)
 // moving and resizing
 // ---------------------------------------------------------------------------
 
 // moving and resizing
 // ---------------------------------------------------------------------------
 
+bool wxWindowMSW::IsSizeDeferred() const
+{
+#if USE_DEFERRED_SIZING
+    if ( m_pendingPosition != wxDefaultPosition ||
+         m_pendingSize     != wxDefaultSize )
+        return true;
+#endif // USE_DEFERRED_SIZING
+
+    return false;
+}
+
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
@@ -1477,14 +1513,24 @@ void wxWindowMSW::DoGetSize(int *x, int *y) const
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
 // Get size *available for subwindows* i.e. excluding menu bar etc.
 void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
-    // this is only for top level windows whose resizing is never deferred, so
-    // we can safely use the current size here
-    RECT rect = wxGetClientRect(GetHwnd());
+    if ( IsTopLevel() || m_pendingSize == wxDefaultSize )
+    {
+        // top level windows resizing is never deferred, so we can safely use
+        // the current size here
+        RECT rect = wxGetClientRect(GetHwnd());
 
 
-    if ( x )
-        *x = rect.right;
-    if ( y )
-        *y = rect.bottom;
+        if ( x )
+            *x = rect.right;
+        if ( y )
+            *y = rect.bottom;
+    }
+    else // non top level
+    {
+        // size is the same as client size for non top level windows, so
+        // forward to GetSize() to take into account deferred sizing (which
+        // wxGetClientRect() doesn't)
+        DoGetSize(x, y);
+    }
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
 }
 
 void wxWindowMSW::DoGetPosition(int *x, int *y) const
@@ -1579,7 +1625,7 @@ wxWindowMSW::DoMoveSibling(WXHWND hwnd, int x, int y, int width, int height)
     if ( hdwp )
     {
         hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height,
     if ( hdwp )
     {
         hdwp = ::DeferWindowPos(hdwp, (HWND)hwnd, NULL, x, y, width, height,
-                                SWP_NOZORDER);
+                                SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOACTIVATE);
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
         if ( !hdwp )
         {
             wxLogLastError(_T("DeferWindowPos"));
@@ -1701,7 +1747,7 @@ void wxWindowMSW::DoSetSize(int x, int y, int width, int height, int sizeFlags)
 
 void wxWindowMSW::DoSetClientSize(int width, int height)
 {
 
 void wxWindowMSW::DoSetClientSize(int width, int height)
 {
-    // setting the client size is less obvious than it it could have been
+    // setting the client size is less obvious than it could have been
     // because in the result of changing the total size the window scrollbar
     // may [dis]appear and/or its menubar may [un]wrap and so the client size
     // will not be correct as the difference between the total and client size
     // because in the result of changing the total size the window scrollbar
     // may [dis]appear and/or its menubar may [un]wrap and so the client size
     // will not be correct as the difference between the total and client size
@@ -1869,7 +1915,7 @@ bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 #endif
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
 #endif
     ::TrackPopupMenu(hMenu, flags, point.x, point.y, 0, hWnd, NULL);
 
-    // we need to do it righ now as otherwise the events are never going to be
+    // we need to do it right now as otherwise the events are never going to be
     // sent to wxCurrentPopupMenu from HandleCommand()
     //
     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
     // sent to wxCurrentPopupMenu from HandleCommand()
     //
     // note that even eliminating (ugly) wxCurrentPopupMenu global wouldn't
@@ -2010,6 +2056,12 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                             else // no default button
 #endif // wxUSE_BUTTON
                             {
                             else // no default button
 #endif // wxUSE_BUTTON
                             {
+#ifdef __WXWINCE__
+                                wxJoystickEvent event(wxEVT_JOY_BUTTON_DOWN);
+                                event.SetEventObject(this);
+                                if(GetEventHandler()->ProcessEvent(event))
+                                    return true;
+#endif
                                 // this is a quick and dirty test for a text
                                 // control
                                 if ( !(lDlgCode & DLGC_HASSETSEL) )
                                 // this is a quick and dirty test for a text
                                 // control
                                 if ( !(lDlgCode & DLGC_HASSETSEL) )
@@ -2048,6 +2100,11 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                 if ( GetEventHandler()->ProcessEvent(event) )
                 {
 
                 if ( GetEventHandler()->ProcessEvent(event) )
                 {
+                    // as we don't call IsDialogMessage(), which would take of
+                    // this by default, we need to manually send this message
+                    // so that controls can change their UI state if needed
+                    MSWUpdateUIState(UIS_CLEAR, UISF_HIDEFOCUS);
+
                     return true;
                 }
             }
                     return true;
                 }
             }
@@ -2061,7 +2118,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
         {
             // ::IsDialogMessage() is broken and may sometimes hang the
             // application by going into an infinite loop, so we try to detect
         {
             // ::IsDialogMessage() is broken and may sometimes hang the
             // application by going into an infinite loop, so we try to detect
-            // [some of] the situatations when this may happen and not call it
+            // [some of] the situations when this may happen and not call it
             // then
 
             // assume we can call it by default
             // then
 
             // assume we can call it by default
@@ -2082,7 +2139,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 #if !defined(__WXWINCE__)
             if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
             {
 #if !defined(__WXWINCE__)
             if ( ::GetWindowLong(hwndFocus, GWL_EXSTYLE) & WS_EX_CONTROLPARENT )
             {
-                // passimistic by default
+                // pessimistic by default
                 canSafelyCallIsDlgMsg = false;
                 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
                       node;
                 canSafelyCallIsDlgMsg = false;
                 for ( wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
                       node;
@@ -2349,28 +2406,6 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             break;
 #endif // !__WXWINCE__
 
             break;
 #endif // !__WXWINCE__
 
-#if !(defined(_WIN32_WCE) && _WIN32_WCE < 400)
-        case WM_WINDOWPOSCHANGED:
-            {
-                WINDOWPOS *lpPos = (WINDOWPOS *)lParam;
-
-                if ( !(lpPos->flags & SWP_NOSIZE) )
-                {
-                    RECT rc;
-                    ::GetClientRect(GetHwnd(), &rc);
-
-                    AutoHRGN hrgnClient(::CreateRectRgnIndirect(&rc));
-                    AutoHRGN hrgnNew(::CreateRectRgn(lpPos->x,  lpPos->y,
-                                                     lpPos->cx, lpPos->cy));
-
-                    // we need to invalidate any new exposed areas here
-                    // to force them to repaint
-                    if ( ::CombineRgn(hrgnNew, hrgnNew, hrgnClient, RGN_DIFF) != NULLREGION )
-                        ::InvalidateRgn(GetHwnd(), hrgnNew, TRUE);
-                }
-            }
-            break;
-#endif
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             // This implicitly sends a wxEVT_ACTIVATE_APP event
 #if !defined(__WXMICROWIN__) && !defined(__WXWINCE__)
         case WM_ACTIVATEAPP:
             // This implicitly sends a wxEVT_ACTIVATE_APP event
@@ -2492,8 +2527,10 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
                 int x = GET_X_LPARAM(lParam),
                     y = GET_Y_LPARAM(lParam);
 
+#ifdef __WXWINCE__
                 // redirect the event to a static control if necessary by
                 // redirect the event to a static control if necessary by
-                // finding one under mouse
+                // finding one under mouse because under CE the static controls
+                // don't generate mouse events (even with SS_NOTIFY)
                 wxWindowMSW *win;
                 if ( GetCapture() == this )
                 {
                 wxWindowMSW *win;
                 if ( GetCapture() == this )
                 {
@@ -2509,6 +2546,9 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
                 }
                     wxCHECK_MSG( win, 0,
                                  _T("FindWindowForMouseEvent() returned NULL") );
                 }
+#else // !__WXWINCE__
+                wxWindowMSW *win = this;
+#endif // __WXWINCE__/!__WXWINCE__
 
                 processed = win->HandleMouseEvent(message, x, y, wParam);
 
 
                 processed = win->HandleMouseEvent(message, x, y, wParam);
 
@@ -2627,7 +2667,7 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
             {
                 switch ( wParam )
                 {
             {
                 switch ( wParam )
                 {
-                    // we consider these message "not interesting" to OnChar, so
+                    // we consider these messages "not interesting" to OnChar, so
                     // just don't do anything more with them
                     case VK_SHIFT:
                     case VK_CONTROL:
                     // just don't do anything more with them
                     case VK_SHIFT:
                     case VK_CONTROL:
@@ -3147,8 +3187,6 @@ bool wxWindowMSW::MSWCreate(const wxChar *wclass,
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
 // WM_NOTIFY
 // ---------------------------------------------------------------------------
 
-#ifdef __WIN95__
-
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
 bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 {
 #ifndef __WXMICROWIN__
@@ -3292,8 +3330,6 @@ bool wxWindowMSW::MSWOnNotify(int WXUNUSED(idCtrl),
     return false;
 }
 
     return false;
 }
 
-#endif // __WIN95__
-
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // end session messages
 // ---------------------------------------------------------------------------
@@ -3482,6 +3518,20 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     return GetEventHandler()->ProcessEvent(event);
 }
 
     return GetEventHandler()->ProcessEvent(event);
 }
 
+// ---------------------------------------------------------------------------
+// labels
+// ---------------------------------------------------------------------------
+
+void wxWindowMSW::SetLabel( const wxString& label)
+{
+    SetWindowText(GetHwnd(), label.c_str());
+}
+
+wxString wxWindowMSW::GetLabel() const
+{
+    return wxGetWindowText(GetHWND());
+}
+
 // ---------------------------------------------------------------------------
 // miscellaneous
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // miscellaneous
 // ---------------------------------------------------------------------------
@@ -4228,7 +4278,7 @@ bool wxWindowMSW::HandleSize(int WXUNUSED(w), int WXUNUSED(h), WXUINT wParam)
                 useDefer = true;
         }
     }
                 useDefer = true;
         }
     }
-#endif
+#endif // USE_DEFERRED_SIZING
 
     // update this window size
     bool processed = false;
 
     // update this window size
     bool processed = false;
@@ -4451,12 +4501,12 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
     event.SetId(GetId());
 
 #if wxUSE_MOUSEEVENT_HACK
-    m_lastMouseX = x;
-    m_lastMouseY = y;
-    m_lastMouseEvent = event.GetEventType();
+    gs_lastMouseEvent.pos = ClientToScreen(wxPoint(x, y));
+    gs_lastMouseEvent.type = event.GetEventType();
 #endif // wxUSE_MOUSEEVENT_HACK
 }
 
 #endif // wxUSE_MOUSEEVENT_HACK
 }
 
+#ifdef __WXWINCE__
 // Windows doesn't send the mouse events to the static controls (which are
 // transparent in the sense that their WM_NCHITTEST handler returns
 // HTTRANSPARENT) at all but we want all controls to receive the mouse events
 // Windows doesn't send the mouse events to the static controls (which are
 // transparent in the sense that their WM_NCHITTEST handler returns
 // HTTRANSPARENT) at all but we want all controls to receive the mouse events
@@ -4467,7 +4517,7 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
 // Notice that this is not done for the mouse move events because this could
 // (would?) be too slow, but only for clicks which means that the static texts
 // still don't get move, enter nor leave events.
 // Notice that this is not done for the mouse move events because this could
 // (would?) be too slow, but only for clicks which means that the static texts
 // still don't get move, enter nor leave events.
-static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //TW:REQ:Univ
+static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y)
 {
     wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
 
 {
     wxCHECK_MSG( x && y, win, _T("NULL pointer in FindWindowForMouseEvent") );
 
@@ -4520,6 +4570,7 @@ static wxWindowMSW *FindWindowForMouseEvent(wxWindowMSW *win, int *x, int *y) //
 
     return win;
 }
 
     return win;
 }
+#endif // __WXWINCE__
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
 
 bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
 {
@@ -4577,19 +4628,36 @@ bool wxWindowMSW::HandleMouseMove(int x, int y, WXUINT flags)
             (void)GetEventHandler()->ProcessEvent(event);
         }
     }
             (void)GetEventHandler()->ProcessEvent(event);
         }
     }
+#ifdef HAVE_TRACKMOUSEEVENT
+    else
+    {
+        // Check if we need to send a LEAVE event
+        // Windows doesn't send WM_MOUSELEAVE if the mouse has been captured so
+        // send it here if we are using native mouse leave tracking
+        if ( HasCapture() && !IsMouseInWindow() )
+        {
+            GenerateMouseLeave();
+        }
+    }
+#endif // HAVE_TRACKMOUSEEVENT
 
 #if wxUSE_MOUSEEVENT_HACK
 
 #if wxUSE_MOUSEEVENT_HACK
-    // Window gets a click down message followed by a mouse move message even
-    // if position isn't changed!  We want to discard the trailing move event
-    // if x and y are the same.
-    if ( (m_lastMouseEvent == wxEVT_RIGHT_DOWN ||
-          m_lastMouseEvent == wxEVT_LEFT_DOWN ||
-          m_lastMouseEvent == wxEVT_MIDDLE_DOWN) &&
-         (m_lastMouseX == x && m_lastMouseY == y) )
-    {
-        m_lastMouseEvent = wxEVT_MOTION;
+    // Windows often generates mouse events even if mouse position hasn't
+    // changed (http://article.gmane.org/gmane.comp.lib.wxwidgets.devel/66576)
+    //
+    // Filter this out as it can result in unexpected behaviour compared to
+    // other platforms
+    if ( gs_lastMouseEvent.type == wxEVT_RIGHT_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_LEFT_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_MIDDLE_DOWN ||
+         gs_lastMouseEvent.type == wxEVT_MOTION )
+    {
+        if ( ClientToScreen(wxPoint(x, y)) == gs_lastMouseEvent.pos )
+        {
+            gs_lastMouseEvent.type = wxEVT_MOTION;
 
 
-        return false;
+            return false;
+        }
     }
 #endif // wxUSE_MOUSEEVENT_HACK
 
     }
 #endif // wxUSE_MOUSEEVENT_HACK
 
@@ -4837,12 +4905,20 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
     MENUITEMINFO mii;
     wxZeroMemory(mii);
     mii.cbSize = sizeof(MENUITEMINFO);
+
+    // we could use MIIM_FTYPE here as we only need to know if the item is
+    // ownerdrawn or not and not dwTypeData which MIIM_TYPE also returns, but
+    // MIIM_FTYPE is not supported under Win95
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
     mii.fMask = MIIM_TYPE | MIIM_DATA;
 
     // find if we have this letter in any owner drawn item
     const int count = ::GetMenuItemCount(hmenu);
     for ( int i = 0; i < count; i++ )
     {
+        // previous loop iteration could modify it, reset it back before
+        // calling GetMenuItemInfo() to prevent it from overflowing dwTypeData
+        mii.cch = 0;
+
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
         if ( ::GetMenuItemInfo(hmenu, i, TRUE, &mii) )
         {
             if ( mii.fType == MFT_OWNERDRAW )
@@ -4880,8 +4956,7 @@ int wxWindowMSW::HandleMenuChar(int WXUNUSED_IN_WINCE(chAccel),
         }
         else // failed to get the menu text?
         {
         }
         else // failed to get the menu text?
         {
-            // it's not fatal, so don't show error, but still log
-            // it
+            // it's not fatal, so don't show error, but still log it
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
             wxLogLastError(_T("GetMenuItemInfo"));
         }
     }
@@ -5312,6 +5387,28 @@ bool wxGetKeyState(wxKeyCode key)
 #endif
 }
 
 #endif
 }
 
+
+wxMouseState wxGetMouseState()
+{
+    wxMouseState ms;
+    POINT pt;
+    GetCursorPos( &pt );
+
+    ms.SetX(pt.x);
+    ms.SetY(pt.y);
+    ms.SetLeftDown( (GetAsyncKeyState(VK_LBUTTON) & (1<<15)) != 0 );
+    ms.SetMiddleDown( (GetAsyncKeyState(VK_MBUTTON) & (1<<15)) != 0 );
+    ms.SetRightDown( (GetAsyncKeyState(VK_RBUTTON) & (1<<15)) != 0 );
+
+    ms.SetControlDown( (GetAsyncKeyState(VK_CONTROL) & (1<<15)) != 0 );
+    ms.SetShiftDown( (GetAsyncKeyState(VK_SHIFT) & (1<<15)) != 0 );
+    ms.SetAltDown( (GetAsyncKeyState(VK_MENU) & (1<<15)) != 0 );
+//    ms.SetMetaDown();
+
+    return ms;
+}
+
+
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
 wxWindow *wxGetActiveWindow()
 {
     HWND hWnd = GetActiveWindow();
@@ -6120,4 +6217,3 @@ void wxWindowMSW::OnInitDialog( wxInitDialogEvent& event )
     event.Skip();
 }
 #endif
     event.Skip();
 }
 #endif
-