]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
Corrected problem with MDI children not refreshing (removed WS_CLIPCHILDREN).
[wxWidgets.git] / src / msw / window.cpp
index 3c3728462ad1d7e83204fcc0d6c33ed532777e53..239bd48bb194047d2d9dafe83d58f77f9b335c22 100644 (file)
@@ -79,7 +79,7 @@
 #undef GetClassInfo
 #endif
 
-#define WINDOW_MARGIN 3        // This defines sensitivity of Leave events
+#define WINDOW_MARGIN 3 // This defines sensitivity of Leave events
 
 wxMenu *wxCurrentPopupMenu = NULL;
 extern wxList wxPendingDelete;
@@ -303,8 +303,6 @@ wxWindow::~wxWindow(void)
   // wxWnd
   MSWDetachWindowMenu();
 
-  wxRemoveHandleAssociation(this);
-
   // TODO for backward compatibility
 #if 0
   // WX_CANVAS
@@ -325,6 +323,8 @@ wxWindow::~wxWindow(void)
 
   if (m_hWnd)
     ::DestroyWindow((HWND)m_hWnd);
+
+  wxRemoveHandleAssociation(this);
   m_hWnd = 0;
 #ifndef __WIN32__
   if (m_globalHandle)
@@ -472,11 +472,10 @@ bool wxWindow::Create(wxWindow *parent, const wxWindowID id,
     msflags |= WS_BORDER;
   if (style & wxTHICK_FRAME)
     msflags |= WS_THICKFRAME;
-  // TODO: probably make WS_CLIPCHILDREN this a setting in wx/setup.h,
-  // to reduce flicker with the trade-off that groupboxes must paint in a solid
-  // colour (so your control order must be correct, and you can't easily draw a
-  // transparent group).
-  msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN;
+
+  msflags |= WS_CHILD | WS_VISIBLE;
+  if (style & wxCLIP_CHILDREN)
+    msflags |= WS_CLIPCHILDREN;
 
   bool want3D;
   WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D) ;
@@ -566,7 +565,11 @@ wxEvtHandler *wxWindow::PopEventHandler(bool deleteHandler)
 
 void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
 {
-  DELETEP(m_pDropTarget);
+  if ( m_pDropTarget != 0 ) {
+    m_pDropTarget->Revoke(m_hWnd);
+    delete m_pDropTarget;
+  }
+
   m_pDropTarget = pDropTarget;
   if ( m_pDropTarget != 0 )
     m_pDropTarget->Register(m_hWnd);
@@ -815,9 +818,6 @@ void wxWindow::GetTextExtent(const wxString& string, int *x, int *y,
   HFONT was = 0;
   if (fontToUse && fontToUse->Ok())
   {
-//    fontToUse->UseResource();
-    
-//    fontToUse->RealizeResource();
     if ((fnt=(HFONT) fontToUse->GetResourceHandle()))
       was = SelectObject(dc,fnt) ;
   }
@@ -877,42 +877,11 @@ void wxWindow::Refresh(const bool eraseBack, const wxRectangle *rect)
   }
 }
 
-// TODO: Are these really necessary now?
-/*
-WXHDC wxWindow::GetHDC(void) const
-{
-  wxWindow *nonConst = (wxWindow *)this;
-  if (m_paintHDC)
-    return(m_paintHDC) ;
-  nonConst->m_tempHDC = (WXHDC) ::GetDC((HWND) GetHWND()) ;
-  return(m_tempHDC) ;
-}
-
-void wxWindow::ReleaseHDC(void)
-{
-  // We're within an OnPaint: it'll be released.
-  if (m_paintHDC)
-    return ;
-
-  ::ReleaseDC((HWND) GetHWND(),(HDC) m_tempHDC) ;
-}
-*/
-
 // Hook for new window just as it's being created,
 // when the window isn't yet associated with the handle
 wxWindow *wxWndHook = NULL;
 
-/*
-#if HAVE_SOCKET
-// DDE Interface Handler
-extern "C" {
-  long ddeWindowProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam);
-  void __ddeUnblock(HWND hWnd, WPARAM wParam);
-};
-#endif
-*/
-
-// Main Windows 3 window proc
+// Main window proc
 LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
   wxWindow *wnd = wxFindWinFromHandle((WXHWND) hWnd);
@@ -941,12 +910,6 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
     wnd->m_lastMsg = message;
     wnd->m_lastWParam = wParam;
     wnd->m_lastLParam = lParam;
-/* Don't know why this was here
-    if (message == WM_SETFONT)
-      return 0;
-    else if (message == WM_INITDIALOG)
-      return TRUE;
-*/
   }
   if (wnd)
     return wnd->MSWWindowProc(message, wParam, lParam);
@@ -1020,12 +983,6 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 
   switch (message)
   {
-/*
-        case WM_SETFONT:
-        {
-          return 0;
-        }
-*/
         case WM_ACTIVATE:
         {
 #ifdef __WIN32__
@@ -1289,10 +1246,9 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
           return MSWOnMeasureItem((int)wParam, (WXMEASUREITEMSTRUCT *)lParam);
           break;
         }
+
         case WM_KEYDOWN:
         {
-//            return Default();
-
             if (wParam == VK_SHIFT)
                return Default();
 
@@ -1308,23 +1264,18 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
                }
                        else
                                return Default();
-            break;
         }
         case WM_KEYUP:
         {
-/*
-            if (wParam == VK_SHIFT)
-              wxShiftDown = FALSE;
-            else if (wParam == VK_CONTROL)
-              wxControlDown = FALSE;
-*/
             break;
         }
+        // VZ: WM_KEYUP not processed
         case WM_CHAR: // Always an ASCII character
         {
           MSWOnChar((WORD)wParam, lParam, TRUE);
           break;
         }
+
         case WM_HSCROLL:
         {
 #ifdef __WIN32__
@@ -1538,6 +1489,10 @@ wxWindow *wxFindWinFromHandle(WXHWND hWnd)
 
 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
 {
+  // adding NULL hWnd is (first) surely a result of an error and
+  // (secondly) breaks menu command processing
+  wxCHECK_RET( hWnd != NULL, "attempt to add a NULL hWnd to window list" );
+
   if ( !wxWinHandleList->Find((long)hWnd) )
     wxWinHandleList->Append((long)hWnd, win);
 }
@@ -1680,15 +1635,15 @@ bool wxWindow::MSWOnDestroy(void)
 #if DEBUG > 1
   wxDebugMsg("wxWindow::MSWOnDestroy %d\n", handle);
 #endif
-  // delete our log target if we've got one
-#if USE_DRAG_AND_DROP
-    if ( m_pDropTarget != 0 ) {
+  // delete our drop target if we've got one
+  #if USE_DRAG_AND_DROP
+    if ( m_pDropTarget != NULL ) {
       m_pDropTarget->Revoke(m_hWnd);
 
       delete m_pDropTarget;
       m_pDropTarget = NULL;
     }
-#endif
+  #endif
 
   return TRUE;
 }
@@ -1850,7 +1805,7 @@ bool wxWindow::MSWOnDrawItem(const int id, WXDRAWITEMSTRUCT *itemStruct)
     if ( id == 0 ) {    // is it a menu item?
       DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
       wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
-      wxCHECK_RET( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+      wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
 
       // prepare to call OnDrawItem()
       wxDC dc;
@@ -1883,7 +1838,7 @@ bool wxWindow::MSWOnMeasureItem(const int id, WXMEASUREITEMSTRUCT *itemStruct)
     if ( id == 0 ) {    // is it a menu item?
       MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
       wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
-      wxCHECK_RET( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+      wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
 
       return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth, 
                                       &pMeasureStruct->itemHeight);
@@ -1981,7 +1936,11 @@ long wxWindow::MSWDefWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 
 long wxWindow::Default()
 {
-  return this->MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
+    // Ignore 'fake' events (perhaps generated as a result of a separate real event)
+    if (m_lastMsg == 0)
+        return 0;
+
+    return this->MSWDefWindowProc(m_lastMsg, m_lastWParam, m_lastLParam);
 }
 
 bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
@@ -2227,18 +2186,8 @@ void wxWindow::MSWOnLButtonDown(const int x, const int y, const WXUINT flags)
   }
 #endif
 
-//wxDebugMsg("LButtonDown\n") ;
   wxMouseEvent event(wxEVENT_TYPE_LEFT_DOWN);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2254,18 +2203,8 @@ void wxWindow::MSWOnLButtonDown(const int x, const int y, const WXUINT flags)
 
 void wxWindow::MSWOnLButtonUp(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("LButtonUp\n") ;
   wxMouseEvent event(wxEVENT_TYPE_LEFT_UP);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2282,19 +2221,7 @@ void wxWindow::MSWOnLButtonUp(const int x, const int y, const WXUINT flags)
 
 void wxWindow::MSWOnLButtonDClick(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("LButtonDClick\n") ;
-  /* MATTHEW: If dclick not allowed, generate another single-click */
-  wxMouseEvent event(m_doubleClickAllowed ?
-                    wxEVENT_TYPE_LEFT_DCLICK : wxEVENT_TYPE_LEFT_DOWN);
-
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
+  wxMouseEvent event(wxEVENT_TYPE_LEFT_DCLICK);
 
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
@@ -2334,18 +2261,8 @@ void wxWindow::MSWOnMButtonDown(const int x, const int y, const WXUINT flags)
   }
 #endif
 
-//wxDebugMsg("MButtonDown\n") ;
   wxMouseEvent event(wxEVENT_TYPE_MIDDLE_DOWN);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2355,7 +2272,7 @@ void wxWindow::MSWOnMButtonDown(const int x, const int y, const WXUINT flags)
   event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
   event.m_eventObject = this;
 
-  m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_DOWN;
+  m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_MIDDLE_DOWN;
   GetEventHandler()->OldOnMouseEvent(event);
 }
 
@@ -2364,15 +2281,6 @@ void wxWindow::MSWOnMButtonUp(const int x, const int y, const WXUINT flags)
 //wxDebugMsg("MButtonUp\n") ;
   wxMouseEvent event(wxEVENT_TYPE_MIDDLE_UP);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2382,25 +2290,13 @@ void wxWindow::MSWOnMButtonUp(const int x, const int y, const WXUINT flags)
   event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
   event.m_eventObject = this;
 
-  m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_UP;
+  m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_MIDDLE_UP;
   GetEventHandler()->OldOnMouseEvent(event);
 }
 
 void wxWindow::MSWOnMButtonDClick(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("MButtonDClick\n") ;
-  /* MATTHEW: If dclick not allowed, generate another single-click */
-  wxMouseEvent event((m_doubleClickAllowed) ?
-                    wxEVENT_TYPE_MIDDLE_DCLICK : wxEVENT_TYPE_MIDDLE_DOWN);
-
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
+  wxMouseEvent event(wxEVENT_TYPE_MIDDLE_DCLICK);
 
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
@@ -2411,7 +2307,7 @@ void wxWindow::MSWOnMButtonDClick(const int x, const int y, const WXUINT flags)
   event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
   event.m_eventObject = this;
 
-  m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_LEFT_DCLICK;
+  m_lastXPos = event.m_x; m_lastYPos = event.m_y; m_lastEvent = wxEVENT_TYPE_MIDDLE_DCLICK;
 //  if (m_doubleClickAllowed)
      GetEventHandler()->OldOnMouseEvent(event);
 }
@@ -2439,18 +2335,8 @@ void wxWindow::MSWOnRButtonDown(const int x, const int y, const WXUINT flags)
   }
 #endif
 
-//wxDebugMsg("RButtonDown\n") ;
   wxMouseEvent event(wxEVENT_TYPE_RIGHT_DOWN);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2466,18 +2352,8 @@ void wxWindow::MSWOnRButtonDown(const int x, const int y, const WXUINT flags)
 
 void wxWindow::MSWOnRButtonUp(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("RButtonUp\n") ;
   wxMouseEvent event(wxEVENT_TYPE_RIGHT_UP);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2493,19 +2369,7 @@ void wxWindow::MSWOnRButtonUp(const int x, const int y, const WXUINT flags)
 
 void wxWindow::MSWOnRButtonDClick(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("RButtonDClick\n") ;
-  /* MATTHEW: If dclick not allowed, generate another single-click */
-  wxMouseEvent event((m_doubleClickAllowed) ?
-                    wxEVENT_TYPE_RIGHT_DCLICK : wxEVENT_TYPE_RIGHT_DOWN);
-
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
+  wxMouseEvent event(wxEVENT_TYPE_RIGHT_DCLICK);
 
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
@@ -2530,127 +2394,15 @@ void wxWindow::MSWOnMouseMove(const int x, const int y, const WXUINT flags)
   if (m_windowCursor.Ok() && !wxIsBusy())
     ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
 
-  wxMouseEvent event(wxEVENT_TYPE_MOTION);
-
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
-  event.m_x = x; event.m_y = y;
-  event.m_shiftDown = ((flags & MK_SHIFT) != 0);
-  event.m_controlDown = ((flags & MK_CONTROL) != 0);
-  event.m_leftDown = ((flags & MK_LBUTTON) != 0);
-  event.m_middleDown = ((flags & MK_MBUTTON) != 0);
-  event.m_rightDown = ((flags & MK_RBUTTON) != 0);
-  event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
-  event.m_eventObject = this;
-
-  // 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_lastEvent == wxEVENT_TYPE_RIGHT_DOWN || m_lastEvent == wxEVENT_TYPE_LEFT_DOWN ||
-       m_lastEvent == wxEVENT_TYPE_MIDDLE_DOWN) &&
-      (m_lastXPos == event.m_x && m_lastYPos == event.m_y))
+ if (!m_mouseInWindow)
   {
-    m_lastXPos = event.m_x; m_lastYPos = event.m_y;
-    m_lastEvent = wxEVENT_TYPE_MOTION;
-    return;
+    // Generate an ENTER event
+    m_mouseInWindow = TRUE;
+    MSWOnMouseEnter(x, y, flags);
   }
 
-  m_lastEvent = wxEVENT_TYPE_MOTION;
-  m_lastXPos = event.m_x; m_lastYPos = event.m_y;
-  GetEventHandler()->OldOnMouseEvent(event);
-}
-
-/* TODO put back leave/enter code if required
- */
-#if 0
-void wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags)
-{
-//wxDebugMsg("Client 0x%08x Move Msg %d,%d\n",this,x,y) ;
-
-// #if MOUSE_EXIT_FIX //Should work now!!
-
-  // Don't do the Leave/Enter fix if we've captured the window,
-  // or SetCapture won't work properly.
-  if (!m_winCaptured)
-  {
-    HWND hunder ;
-    POINT pt ;
-    // See if we Leave/Enter the window.
-    GetCursorPos(&pt) ;
-    hunder = WindowFromPoint(pt) ;
-    if (hunder==m_hWnd)
-    {
-      // I'm in the Window, but perhaps in NC area.
-      RECT wind ;
-      RECT nc ;
-      GetClientRect(m_hWnd,&wind) ;
-      GetWindowRect(m_hWnd,&nc) ;
-      pt.x -= nc.left ;
-      pt.y -= nc.top ;
-      wind.left    += WINDOW_MARGIN ; // to be able to 'see' leave
-      wind.top     += WINDOW_MARGIN ; // to be able to 'see' leave
-      wind.right   -= WINDOW_MARGIN ; // to be able to 'see' leave
-      wind.bottom  -= WINDOW_MARGIN ; // to be able to 'see' leave
-
-      if (!PtInRect(&wind,pt))
-        hunder = NULL ; // So, I can simulate a Leave event...
-    }
-
-    if (hunder!=m_hWnd)
-    {
-      if (m_mouseInWindow)
-      {
-        m_mouseInWindow = FALSE ;
-        // Capture/Release is no more needed...
-        //ReleaseCapture() ;
-        MSWOnMouseLeave(x,y,flags) ;
-        return ;
-      }
-      // We never want to see Enter or Motion in this part of the Window...
-      return ;
-    }
-    else
-    {
-      // Event was triggered while I'm really into my client area.
-      // Do an Enter if not done.
-      if (!m_mouseInWindow)
-      {
-        m_mouseInWindow = TRUE ;
-        // Capture/Release is no more needed...
-        //SetCapture(m_hWnd) ;
-        // Set cursor, but only if we're not in 'busy' mode
-        if (m_windowCursor.Ok() && !wxIsBusy())
-          ::SetCursor(m_windowCursor.ms_cursor);
-        MSWOnMouseEnter(x,y,flags) ;
-        return ;
-      }
-    }
-  }
-// #endif //MOUSE_EXIT_FIX
-    
-  // 'normal' move event...
-  // Set cursor, but only if we're not in 'busy' mode
-  if (m_windowCursor.Ok() && !wxIsBusy())
-    ::SetCursor(m_windowCursor.ms_cursor);
-
   wxMouseEvent event(wxEVENT_TYPE_MOTION);
 
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
-
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
   event.m_controlDown = ((flags & MK_CONTROL) != 0);
@@ -2676,26 +2428,10 @@ void wxWindow::MSWOnMouseMove(int x, int y, WXUINT flags)
   m_lastXPos = event.m_x; m_lastYPos = event.m_y;
   GetEventHandler()->OldOnMouseEvent(event);
 }
-#endif
 
 void wxWindow::MSWOnMouseEnter(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("Client 0x%08x Enter %d,%d\n",this,x,y) ;
-
-  // Set cursor, but only if we're not in 'busy' mode
-  if (m_windowCursor.Ok() && !wxIsBusy())
-    ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
-
-  wxMouseEvent event(wxEVENT_TYPE_ENTER_WINDOW);
-
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
+  wxMouseEvent event(wxEVT_ENTER_WINDOW);
 
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
@@ -2706,29 +2442,16 @@ void wxWindow::MSWOnMouseEnter(const int x, const int y, const WXUINT flags)
   event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
   event.m_eventObject = this;
 
-  m_lastEvent = wxEVENT_TYPE_ENTER_WINDOW;
+  m_lastEvent = wxEVT_ENTER_WINDOW;
   m_lastXPos = event.m_x; m_lastYPos = event.m_y;
-  GetEventHandler()->OldOnMouseEvent(event);
+  // No message - ensure we don't try to call the default behaviour accidentally.
+  m_lastMsg = 0;
+  GetEventHandler()->ProcessEvent(event);
 }
 
 void wxWindow::MSWOnMouseLeave(const int x, const int y, const WXUINT flags)
 {
-//wxDebugMsg("Client 0x%08x Leave %d,%d\n",this,x,y) ;
-
-  // Set cursor, but only if we're not in 'busy' mode
-  if (m_windowCursor.Ok() && !wxIsBusy())
-    ::SetCursor((HCURSOR) m_windowCursor.GetHCURSOR());
-
-  wxMouseEvent event(wxEVENT_TYPE_LEAVE_WINDOW);
-
-/*
-  float px = (float)x;
-  float py = (float)y;
-
-  MSWDeviceToLogical(&px, &py);
-
-  CalcUnscrolledPosition((int)px, (int)py, &event.m_x, &event.m_y);
-*/
+  wxMouseEvent event(wxEVT_LEAVE_WINDOW);
 
   event.m_x = x; event.m_y = y;
   event.m_shiftDown = ((flags & MK_SHIFT) != 0);
@@ -2739,9 +2462,11 @@ void wxWindow::MSWOnMouseLeave(const int x, const int y, const WXUINT flags)
   event.SetTimestamp(wxApp::sm_lastMessageTime); /* MATTHEW: timeStamp */
   event.m_eventObject = this;
 
-  m_lastEvent = wxEVENT_TYPE_LEAVE_WINDOW;
+  m_lastEvent = wxEVT_LEAVE_WINDOW;
   m_lastXPos = event.m_x; m_lastYPos = event.m_y;
-  GetEventHandler()->OldOnMouseEvent(event);
+  // No message - ensure we don't try to call the default behaviour accidentally.
+  m_lastMsg = 0;
+  GetEventHandler()->ProcessEvent(event);
 }
 
 void wxWindow::MSWOnChar(const WXWORD wParam, const WXLPARAM lParam, const bool isASCII)
@@ -2779,11 +2504,13 @@ void wxWindow::MSWOnChar(const WXWORD wParam, const WXLPARAM lParam, const bool
       }
     }
   }
-  else
-    if ((id = wxCharCodeMSWToWX(wParam)) == 0)
+  else if ((id = wxCharCodeMSWToWX(wParam)) == 0) {
+      // it's ASCII and will be processed here only when called from
+      // WM_CHAR (i.e. when isASCII = TRUE)
       id = -1;
+  }
 
-  if (id > -1)
+  if (id != -1)
   {
     wxKeyEvent event(wxEVT_CHAR);
     event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
@@ -2802,13 +2529,6 @@ void wxWindow::MSWOnChar(const WXWORD wParam, const WXLPARAM lParam, const bool
     pt.x -= rect.left ;
     pt.y -= rect.top ;
 
-/*
-    float fx,fy ;
-    fx = (float)pt.x ;
-    fy = (float)pt.y ;
-    MSWDeviceToLogical(&fx,&fy) ;
-    CalcUnscrolledPosition((int)fx,(int)fy,&event.m_x,&event.m_y) ;
-*/
     event.m_x = pt.x; event.m_y = pt.y;
 
 #if WXWIN_COMPATIBILITY
@@ -4942,6 +4662,18 @@ void wxWindow::UpdateWindowUI(void)
 
 void wxWindow::OnIdle(wxIdleEvent& event)
 {
+    // Check if we need to send a LEAVE event
+    if (m_mouseInWindow)
+    {
+        POINT pt;
+        ::GetCursorPos(&pt);
+        if (::WindowFromPoint(pt) != (HWND) GetHWND())
+        {
+            // Generate a LEAVE event
+            m_mouseInWindow = FALSE;
+            MSWOnMouseLeave(pt.x, pt.y, 0);
+        }
+    }
        UpdateWindowUI();
 }