]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
added missing -univ package control files.
[wxWidgets.git] / src / msw / window.cpp
index 5994bed1f73b2a82684dcf0455ab301c6c6d6b00..aa47fded2486d711cec8e44735bb57d271958413 100644 (file)
@@ -39,7 +39,6 @@
     #include "wx/dcclient.h"
     #include "wx/utils.h"
     #include "wx/app.h"
     #include "wx/dcclient.h"
     #include "wx/utils.h"
     #include "wx/app.h"
-    #include "wx/panel.h"
     #include "wx/layout.h"
     #include "wx/dialog.h"
     #include "wx/frame.h"
     #include "wx/layout.h"
     #include "wx/dialog.h"
     #include "wx/frame.h"
@@ -47,8 +46,7 @@
     #include "wx/button.h"
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
     #include "wx/button.h"
     #include "wx/msgdlg.h"
     #include "wx/settings.h"
-
-    #include <stdio.h>
+    #include "wx/statbox.h"
 #endif
 
 #if wxUSE_OWNER_DRAWN
 #endif
 
 #if wxUSE_OWNER_DRAWN
@@ -132,7 +130,6 @@ extern MSG s_currentMsg;
 wxMenu *wxCurrentPopupMenu = NULL;
 #endif // wxUSE_MENUS_NATIVE
 
 wxMenu *wxCurrentPopupMenu = NULL;
 #endif // wxUSE_MENUS_NATIVE
 
-extern wxList WXDLLEXPORT wxPendingDelete;
 extern const wxChar *wxCanvasClassName;
 
 // ---------------------------------------------------------------------------
 extern const wxChar *wxCanvasClassName;
 
 // ---------------------------------------------------------------------------
@@ -159,8 +156,25 @@ static void TranslateKbdEventToMouse(wxWindowMSW *win,
 // 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);
 
-// check if the mouse is in the window or its child
-//static bool IsMouseInWindow(HWND hwnd);
+// wrapper around BringWindowToTop() API
+static inline void wxBringWindowToTop(HWND hwnd)
+{
+#ifdef __WXMICROWIN__
+    // It seems that MicroWindows brings the _parent_ of the window to the top,
+    // which can be the wrong one.
+
+    // activate (set focus to) specified window
+    ::SetFocus(hwnd);
+
+    // raise top level parent to top of z order
+    ::SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
+#else // !__WXMICROWIN__
+    if ( !::BringWindowToTop(hwnd) )
+    {
+        wxLogLastError(_T("BringWindowToTop"));
+    }
+#endif // __WXMICROWIN__/!__WXMICROWIN__
+}
 
 // ---------------------------------------------------------------------------
 // event tables
 
 // ---------------------------------------------------------------------------
 // event tables
@@ -179,7 +193,6 @@ BEGIN_EVENT_TABLE(wxWindowMSW, wxWindowBase)
     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
     EVT_IDLE(wxWindowMSW::OnIdle)
     EVT_SYS_COLOUR_CHANGED(wxWindowMSW::OnSysColourChanged)
     EVT_INIT_DIALOG(wxWindowMSW::OnInitDialog)
     EVT_IDLE(wxWindowMSW::OnIdle)
-    EVT_SET_FOCUS(wxWindowMSW::OnSetFocus)
 END_EVENT_TABLE()
 
 // ===========================================================================
 END_EVENT_TABLE()
 
 // ===========================================================================
@@ -194,7 +207,7 @@ END_EVENT_TABLE()
 wxWindow *wxWindowMSW::FindItem(long id) const
 {
 #if wxUSE_CONTROLS
 wxWindow *wxWindowMSW::FindItem(long id) const
 {
 #if wxUSE_CONTROLS
-    wxControl *item = wxDynamicThisCast(this, wxControl);
+    wxControl *item = wxDynamicCastThis(wxControl);
     if ( item )
     {
         // is it we or one of our "internal" children?
     if ( item )
     {
         // is it we or one of our "internal" children?
@@ -310,17 +323,21 @@ wxWindowMSW::~wxWindowMSW()
 
     MSWDetachWindowMenu();
 
 
     MSWDetachWindowMenu();
 
+#ifndef __WXUNIVERSAL__
     // VS: make sure there's no wxFrame with last focus set to us:
     // VS: make sure there's no wxFrame with last focus set to us:
-    for (wxWindow *win = GetParent(); win; win = win->GetParent())
+    for ( wxWindow *win = GetParent(); win; win = win->GetParent() )
     {
         wxFrame *frame = wxDynamicCast(win, wxFrame);
         if ( frame )
         {
             if ( frame->GetLastFocus() == this )
     {
         wxFrame *frame = wxDynamicCast(win, wxFrame);
         if ( frame )
         {
             if ( frame->GetLastFocus() == this )
+            {
                 frame->SetLastFocus((wxWindow*)NULL);
                 frame->SetLastFocus((wxWindow*)NULL);
+            }
             break;
         }
     }
             break;
         }
     }
+#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
 
     // 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
@@ -354,6 +371,17 @@ bool wxWindowMSW::Create(wxWindow *parent,
 {
     wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
 
 {
     wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
 
+#if wxUSE_STATBOX
+    // wxGTK doesn't allow to create controls with static box as the parent so
+    // this will result in a crash when the program is ported to wxGTK - warn
+    // about it
+    //
+    // the correct solution is to create the controls as siblings of the
+    // static box
+    wxASSERT_MSG( !wxDynamicCastThis(wxStaticBox),
+                  _T("wxStaticBox can't be used as a window parent!") );
+#endif // wxUSE_STATBOX
+
     if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
         return FALSE;
 
     if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
         return FALSE;
 
@@ -424,7 +452,7 @@ void wxWindowMSW::SetFocus()
 #ifndef __WXMICROWIN__
     ::SetLastError(0);
 #endif
 #ifndef __WXMICROWIN__
     ::SetLastError(0);
 #endif
-    
+
     if ( !::SetFocus(hWnd) )
     {
         // was there really an error?
     if ( !::SetFocus(hWnd) )
     {
         // was there really an error?
@@ -496,7 +524,7 @@ bool wxWindowMSW::Show(bool show)
 
     if ( show )
     {
 
     if ( show )
     {
-        BringWindowToTop(hWnd);
+        wxBringWindowToTop(hWnd);
     }
 
     return TRUE;
     }
 
     return TRUE;
@@ -505,11 +533,7 @@ bool wxWindowMSW::Show(bool show)
 // Raise the window to the top of the Z order
 void wxWindowMSW::Raise()
 {
 // Raise the window to the top of the Z order
 void wxWindowMSW::Raise()
 {
-#ifdef __WIN16__
-    ::BringWindowToTop(GetHwnd());
-#else // Win32
-    ::SetForegroundWindow(GetHwnd());
-#endif
+    wxBringWindowToTop(GetHwnd());
 }
 
 // Lower the window to the bottom of the Z order
 }
 
 // Lower the window to the bottom of the Z order
@@ -588,8 +612,7 @@ bool wxWindowMSW::SetCursor(const wxCursor& cursor)
         POINT point;
         ::GetCursorPos(&point);
 
         POINT point;
         ::GetCursorPos(&point);
 
-        RECT rect;
-        ::GetWindowRect(hWnd, &rect);
+        RECT rect = wxGetWindowRect(hWnd);
 
         if ( ::PtInRect(&rect, point) && !wxIsBusy() )
             ::SetCursor(GetHcursorOf(m_cursor));
 
         if ( ::PtInRect(&rect, point) && !wxIsBusy() )
             ::SetCursor(GetHcursorOf(m_cursor));
@@ -737,6 +760,15 @@ int wxWindowMSW::GetScrollPage(int orient) const
 
 #endif // WXWIN_COMPATIBILITY
 
 
 #endif // WXWIN_COMPATIBILITY
 
+inline int GetScrollPosition(HWND hWnd, int wOrient)
+{
+#ifdef __WXMICROWIN__
+    return ::GetScrollPosWX(hWnd, wOrient);
+#else
+    return ::GetScrollPos(hWnd, wOrient);
+#endif
+}
+
 int wxWindowMSW::GetScrollPos(int orient) const
 {
     int wOrient;
 int wxWindowMSW::GetScrollPos(int orient) const
 {
     int wOrient;
@@ -744,17 +776,11 @@ int wxWindowMSW::GetScrollPos(int orient) const
         wOrient = SB_HORZ;
     else
         wOrient = SB_VERT;
         wOrient = SB_HORZ;
     else
         wOrient = SB_VERT;
+
     HWND hWnd = GetHwnd();
     HWND hWnd = GetHwnd();
-    if ( hWnd )
-    {
-#ifdef __WXMICROWIN__
-        return ::GetScrollPosWX(hWnd, wOrient);
-#else
-        return ::GetScrollPos(hWnd, wOrient);
-#endif
-    }
-    else
-        return 0;
+    wxCHECK_MSG( hWnd, 0, _T("no HWND in GetScrollPos") );
+
+    return GetScrollPosition(hWnd, wOrient);
 }
 
 // This now returns the whole range, not just the number
 }
 
 // This now returns the whole range, not just the number
@@ -907,6 +933,46 @@ void wxWindowMSW::ScrollWindow(int dx, int dy, const wxRect *prect)
     ::ScrollWindow(GetHwnd(), dx, dy, prect ? &rect : NULL, NULL);
 }
 
     ::ScrollWindow(GetHwnd(), dx, dy, prect ? &rect : NULL, NULL);
 }
 
+static bool ScrollVertically(HWND hwnd, int kind, int count)
+{
+    int posStart = GetScrollPosition(hwnd, SB_VERT);
+
+    int pos = posStart;
+    for ( int n = 0; n < count; n++ )
+    {
+        ::SendMessage(hwnd, WM_VSCROLL, kind, 0);
+
+        int posNew = GetScrollPosition(hwnd, SB_VERT);
+        if ( posNew == pos )
+        {
+            // don't bother to continue, we're already at top/bottom
+            break;
+        }
+
+        pos = posNew;
+    }
+
+    return pos != posStart;
+}
+
+bool wxWindowMSW::ScrollLines(int lines)
+{
+    bool down = lines > 0;
+
+    return ScrollVertically(GetHwnd(),
+                            down ? SB_LINEDOWN : SB_LINEUP,
+                            down ? lines : -lines);
+}
+
+bool wxWindowMSW::ScrollPages(int pages)
+{
+    bool down = pages > 0;
+
+    return ScrollVertically(GetHwnd(),
+                            down ? SB_PAGEDOWN : SB_PAGEUP,
+                            down ? pages : -pages);
+}
+
 // ---------------------------------------------------------------------------
 // subclassing
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // subclassing
 // ---------------------------------------------------------------------------
@@ -921,6 +987,9 @@ void wxWindowMSW::SubclassWin(WXHWND hWnd)
     wxAssociateWinWithHandle(hwnd, this);
 
     m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
     wxAssociateWinWithHandle(hwnd, this);
 
     m_oldWndProc = (WXFARPROC) GetWindowLong(hwnd, GWL_WNDPROC);
+
+    wxASSERT( (WXFARPROC) m_oldWndProc != (WXFARPROC) wxWndProc );
+
     SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc);
 }
 
     SetWindowLong(hwnd, GWL_WNDPROC, (LONG) wxWndProc);
 }
 
@@ -1118,11 +1187,7 @@ void wxWindowMSW::OnIdle(wxIdleEvent& WXUNUSED(event))
 
             // we need to have client coordinates here for symmetry with
             // wxEVT_ENTER_WINDOW
 
             // we need to have client coordinates here for symmetry with
             // wxEVT_ENTER_WINDOW
-            RECT rect;
-            if ( !::GetWindowRect(GetHwnd(), &rect) )
-            {
-                wxLogLastError(_T("GetWindowRect"));
-            }
+            RECT rect = wxGetWindowRect(GetHwnd());
             pt.x -= rect.left;
             pt.y -= rect.top;
 
             pt.x -= rect.left;
             pt.y -= rect.top;
 
@@ -1158,6 +1223,25 @@ void wxWindowMSW::Clear()
     dc.Clear();
 }
 
     dc.Clear();
 }
 
+static inline void SendSetRedraw(HWND hwnd, bool on)
+{
+    ::SendMessage(hwnd, WM_SETREDRAW, (WPARAM)on, 0);
+}
+
+void wxWindowMSW::Freeze()
+{
+    SendSetRedraw(GetHwnd(), FALSE);
+}
+
+void wxWindowMSW::Thaw()
+{
+    SendSetRedraw(GetHwnd(), TRUE);
+
+    // we need to refresh everything or otherwise he invalidated area is not
+    // repainted
+    Refresh();
+}
+
 void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
 {
     HWND hWnd = GetHwnd();
 void wxWindowMSW::Refresh(bool eraseBack, const wxRect *rect)
 {
     HWND hWnd = GetHwnd();
@@ -1244,28 +1328,28 @@ void wxWindowMSW::DoSetToolTip(wxToolTip *tooltip)
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
 // Get total size
 void wxWindowMSW::DoGetSize(int *x, int *y) const
 {
-    HWND hWnd = GetHwnd();
-    RECT rect;
-#ifdef __WIN16__
-    ::GetWindowRect(hWnd, &rect);
-#else
-    if ( !::GetWindowRect(hWnd, &rect) )
-    {
-        wxLogLastError(_T("GetWindowRect"));
-    }
-#endif
+    RECT rect = wxGetWindowRect(GetHwnd());
+
     if ( x )
         *x = rect.right - rect.left;
     if ( y )
         *y = rect.bottom - rect.top;
 }
 
     if ( x )
         *x = rect.right - rect.left;
     if ( y )
         *y = rect.bottom - rect.top;
 }
 
-void wxWindowMSW::DoGetPosition(int *x, int *y) const
+// Get size *available for subwindows* i.e. excluding menu bar etc.
+void wxWindowMSW::DoGetClientSize(int *x, int *y) const
 {
 {
-    HWND hWnd = GetHwnd();
+    RECT rect = wxGetClientRect(GetHwnd());
 
 
-    RECT rect;
-    GetWindowRect(hWnd, &rect);
+    if ( x )
+        *x = rect.right;
+    if ( y )
+        *y = rect.bottom;
+}
+
+void wxWindowMSW::DoGetPosition(int *x, int *y) const
+{
+    RECT rect = wxGetWindowRect(GetHwnd());
 
     POINT point;
     point.x = rect.left;
 
     POINT point;
     point.x = rect.left;
@@ -1311,8 +1395,7 @@ void wxWindowMSW::DoScreenToClient(int *x, int *y) const
     if ( y )
         pt.y = *y;
 
     if ( y )
         pt.y = *y;
 
-    HWND hWnd = GetHwnd();
-    ::ScreenToClient(hWnd, &pt);
+    ::ScreenToClient(GetHwnd(), &pt);
 
     if ( x )
         *x = pt.x;
 
     if ( x )
         *x = pt.x;
@@ -1328,8 +1411,7 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
     if ( y )
         pt.y = *y;
 
     if ( y )
         pt.y = *y;
 
-    HWND hWnd = GetHwnd();
-    ::ClientToScreen(hWnd, &pt);
+    ::ClientToScreen(GetHwnd(), &pt);
 
     if ( x )
         *x = pt.x;
 
     if ( x )
         *x = pt.x;
@@ -1337,18 +1419,6 @@ void wxWindowMSW::DoClientToScreen(int *x, int *y) const
         *y = pt.y;
 }
 
         *y = pt.y;
 }
 
-// Get size *available for subwindows* i.e. excluding menu bar etc.
-void wxWindowMSW::DoGetClientSize(int *x, int *y) const
-{
-    HWND hWnd = GetHwnd();
-    RECT rect;
-    ::GetClientRect(hWnd, &rect);
-    if ( x )
-        *x = rect.right;
-    if ( y )
-        *y = rect.bottom;
-}
-
 void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
 {
     if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
 void wxWindowMSW::DoMoveWindow(int x, int y, int width, int height)
 {
     if ( !::MoveWindow(GetHwnd(), x, y, width, height, TRUE) )
@@ -1469,24 +1539,6 @@ wxPoint wxWindowMSW::GetClientAreaOrigin() const
     return wxPoint(0, 0);
 }
 
     return wxPoint(0, 0);
 }
 
-// Makes an adjustment to the window position (for example, a frame that has
-// a toolbar that it manages itself).
-void wxWindowMSW::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
-{
-    // don't do it for the dialogs/frames - they float independently of their
-    // parent
-    if ( !IsTopLevel() )
-    {
-        wxWindow *parent = GetParent();
-        if ( !(sizeFlags & wxSIZE_NO_ADJUSTMENTS) && parent )
-        {
-            wxPoint pt(parent->GetClientAreaOrigin());
-            x += pt.x;
-            y += pt.y;
-        }
-    }
-}
-
 // ---------------------------------------------------------------------------
 // text metrics
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // text metrics
 // ---------------------------------------------------------------------------
@@ -1594,6 +1646,8 @@ void wxWindowMSW::GetCaretPos(int *x, int *y) const
 // popup menu
 // ---------------------------------------------------------------------------
 
 // popup menu
 // ---------------------------------------------------------------------------
 
+#if wxUSE_MENUS_NATIVE
+
 // yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue
 // immediately, without waiting for the next event loop iteration
 //
 // yield for WM_COMMAND events only, i.e. process all WM_COMMANDs in the queue
 // immediately, without waiting for the next event loop iteration
 //
@@ -1611,8 +1665,6 @@ static void wxYieldForCommandsOnly()
     }
 }
 
     }
 }
 
-#if wxUSE_MENUS_NATIVE
-
 bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 {
     menu->SetInvokingWindow(this);
 bool wxWindowMSW::DoPopupMenu(wxMenu *menu, int x, int y)
 {
     menu->SetInvokingWindow(this);
@@ -1748,18 +1800,13 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                             bProcess = FALSE;
                         }
 
                             bProcess = FALSE;
                         }
-#if wxUSE_BUTTON
+                        // FIXME: this should be handled by
+                        //        wxNavigationKeyEvent handler and not here!!
                         else
                         {
                         else
                         {
-                            wxPanel *panel = wxDynamicThisCast(this, wxPanel);
-                            wxButton *btn = NULL;
-                            if ( panel )
-                            {
-                                // panel may have a default button which should
-                                // be activated by Enter
-                                btn = panel->GetDefaultItem();
-                            }
-
+#if wxUSE_BUTTON
+                            wxButton *btn = wxDynamicCast(GetDefaultItem(),
+                                                          wxButton);
                             if ( btn && btn->IsEnabled() )
                             {
                                 // if we do have a default button, do press it
                             if ( btn && btn->IsEnabled() )
                             {
                                 // if we do have a default button, do press it
@@ -1767,11 +1814,15 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                                 return TRUE;
                             }
 
                                 return TRUE;
                             }
-                            // else: but if it does not it makes sense to make
-                            //       it work like a TAB - and that's what we do.
-                            //       Note that Ctrl-Enter always works this way.
-                        }
+                            else // no default button
 #endif // wxUSE_BUTTON
 #endif // wxUSE_BUTTON
+                            {
+                                // no special function for enter and don't even
+                                // let IsDialogMessage() have it: it seems to
+                                // do something really strange with it
+                                return FALSE;
+                            }
+                        }
                     }
                     break;
 
                     }
                     break;
 
@@ -1788,20 +1839,11 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
 
                 if ( GetEventHandler()->ProcessEvent(event) )
                 {
 
                 if ( GetEventHandler()->ProcessEvent(event) )
                 {
-#if wxUSE_BUTTON
-                    wxButton *btn = wxDynamicCast(FindFocus(), wxButton);
-                    if ( btn )
-                    {
-                        // the button which has focus should be default
-                        btn->SetDefault();
-                    }
-#endif // wxUSE_BUTTON
-
                     return TRUE;
                 }
             }
         }
                     return TRUE;
                 }
             }
         }
-#else
+#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 )
         // 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 )
@@ -1829,7 +1871,7 @@ bool wxWindowMSW::MSWProcessMessage(WXMSG* pMsg)
                 }
             }
         }
                 }
             }
         }
-#endif // 0
+#endif // 1/0
 
         if ( ::IsDialogMessage(GetHwnd(), msg) )
         {
 
         if ( ::IsDialogMessage(GetHwnd(), msg) )
         {
@@ -1861,6 +1903,12 @@ bool wxWindowMSW::MSWTranslateMessage(WXMSG* pMsg)
 #endif // wxUSE_ACCEL
 }
 
 #endif // wxUSE_ACCEL
 }
 
+bool wxWindowMSW::MSWShouldPreProcessMessage(WXMSG* pMsg)
+{
+    // preprocess all messages by default
+    return TRUE;
+}
+
 // ---------------------------------------------------------------------------
 // message params unpackers (different for Win16 and Win32)
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // message params unpackers (different for Win16 and Win32)
 // ---------------------------------------------------------------------------
@@ -2041,7 +2089,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             break;
 
         case WM_DESTROY:
             break;
 
         case WM_DESTROY:
-            processed = HandleDestroy();
+            // never set processed to TRUE and *always* pass WM_DESTROY to
+            // DefWindowProc() as Windows may do some internal cleanup when
+            // processing it and failing to pass the message along may cause
+            // memory and resource leaks!
+            (void)HandleDestroy();
             break;
 
         case WM_MOVE:
             break;
 
         case WM_MOVE:
@@ -2076,21 +2128,11 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 
             }
             break;
 
-#if defined(__WXUNIVERSAL__) && !defined(__WXMICROWIN__)
+#ifndef __WXMICROWIN__
         case WM_ACTIVATEAPP:
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
         case WM_ACTIVATEAPP:
             wxTheApp->SetActive(wParam != 0, FindFocus());
             break;
-
-        case WM_NCHITTEST:
-            // we shouldn't allow the windows which don't want to get focus to
-            // get it
-            if ( !AcceptsFocus() )
-            {
-                rc.result = HTTRANSPARENT;
-                processed = TRUE;
-            }
-            break;
-#endif // __WXUNIVERSAL__
+#endif
 
         case WM_ACTIVATE:
             {
 
         case WM_ACTIVATE:
             {
@@ -2138,12 +2180,6 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
 #endif
 
         case WM_LBUTTONDOWN:
 #endif
 
         case WM_LBUTTONDOWN:
-           // set focus to this window
-           if (AcceptsFocus())
-                SetFocus();
-
-           // fall through
-
         case WM_LBUTTONUP:
         case WM_LBUTTONDBLCLK:
         case WM_RBUTTONDOWN:
         case WM_LBUTTONUP:
         case WM_LBUTTONDBLCLK:
         case WM_RBUTTONDOWN:
@@ -2152,13 +2188,70 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
         case WM_MBUTTONDOWN:
         case WM_MBUTTONUP:
         case WM_MBUTTONDBLCLK:
         case WM_MBUTTONDOWN:
         case WM_MBUTTONUP:
         case WM_MBUTTONDBLCLK:
-            processed = HandleMouseEvent(message,
+         {
+                processed = FALSE;
+#ifdef __WXMICROWIN__
+                // MicroWindows seems to ignore the fact that a window is
+                // disabled. So catch mouse events and throw them away if
+                // necessary.
+                wxWindowMSW* win = this;
+                while (win)
+                {
+                    if (!win->IsEnabled())
+                    {
+                        processed = TRUE;
+                        break;
+                    }
+                    win = win->GetParent();
+                    if (win && win->IsTopLevel())
+                        break;
+                }
+#endif // __WXMICROWIN__
+                if (!processed)
+                {
+                    if (message == WM_LBUTTONDOWN && AcceptsFocus())
+                        SetFocus();
+                     processed = HandleMouseEvent(message,
                                          GET_X_LPARAM(lParam),
                                          GET_Y_LPARAM(lParam),
                                          GET_X_LPARAM(lParam),
                                          GET_Y_LPARAM(lParam),
-                                         wParam);
-            break;
+                                                  wParam);
+                }
+                break;
+         }
 
 
-#ifdef MM_JOY1MOVE // __WXMICROWIN__
+#ifdef __WXMICROWIN__
+        case WM_NCLBUTTONDOWN:
+        case WM_NCLBUTTONUP:
+        case WM_NCLBUTTONDBLCLK:
+        case WM_NCRBUTTONDOWN:
+        case WM_NCRBUTTONUP:
+        case WM_NCRBUTTONDBLCLK:
+#if 0
+        case WM_NCMBUTTONDOWN:
+        case WM_NCMBUTTONUP:
+        case WM_NCMBUTTONDBLCLK:
+#endif
+            {
+                // MicroWindows seems to ignore the fact that a window
+                // is disabled. So catch mouse events and throw them away if necessary.
+                processed = FALSE;
+                wxWindowMSW* win = this;
+                while (win)
+                {
+                    if (!win->IsEnabled())
+                    {
+                        processed = TRUE;
+                        break;
+                    }
+                    win = win->GetParent();
+                    if (win && win->IsTopLevel())
+                        break;
+                }
+                break;
+            }
+#endif // __WXMICROWIN__
+
+#ifdef MM_JOY1MOVE
         case MM_JOY1MOVE:
         case MM_JOY2MOVE:
         case MM_JOY1ZMOVE:
         case MM_JOY1MOVE:
         case MM_JOY2MOVE:
         case MM_JOY1ZMOVE:
@@ -2172,7 +2265,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                                             GET_Y_LPARAM(lParam),
                                             wParam);
             break;
                                             GET_Y_LPARAM(lParam),
                                             wParam);
             break;
-#endif
+#endif // __WXMICROWIN__
 
         case WM_SYSCOMMAND:
             processed = HandleSysCommand(wParam, lParam);
 
         case WM_SYSCOMMAND:
             processed = HandleSysCommand(wParam, lParam);
@@ -2195,7 +2288,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
 #endif  // Win95
 
             // for these messages we must return TRUE if process the message
 #endif  // Win95
 
             // for these messages we must return TRUE if process the message
-#ifdef WM_DRAWITEM // __WXMICROWIN__
+#ifdef WM_DRAWITEM
         case WM_DRAWITEM:
         case WM_MEASUREITEM:
             {
         case WM_DRAWITEM:
         case WM_MEASUREITEM:
             {
@@ -2215,7 +2308,8 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                     rc.result = TRUE;
             }
             break;
                     rc.result = TRUE;
             }
             break;
-#endif
+#endif // defined(WM_DRAWITEM)
+
         case WM_GETDLGCODE:
             if ( m_lDlgCode )
             {
         case WM_GETDLGCODE:
             if ( m_lDlgCode )
             {
@@ -2351,7 +2445,7 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
                                            lParam);
             }
             break;
                                            lParam);
             }
             break;
-#endif
+#endif // !__WXMICROWIN__
 
             // the return value for this message is ignored
         case WM_SYSCOLORCHANGE:
 
             // the return value for this message is ignored
         case WM_SYSCOLORCHANGE:
@@ -2463,6 +2557,18 @@ long wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam
             }
             break;
 #endif // __WIN32__
             }
             break;
 #endif // __WIN32__
+
+#ifdef __WXUNIVERSAL__
+        case WM_NCHITTEST:
+            // we shouldn't allow the windows which don't want to get focus to
+            // get it
+            if ( !AcceptsFocus() )
+            {
+                rc.result = HTTRANSPARENT;
+                processed = TRUE;
+            }
+            break;
+#endif // __WXUNIVERSAL__
     }
 
     if ( !processed )
     }
 
     if ( !processed )
@@ -2654,9 +2760,9 @@ bool wxWindowMSW::MSWCreate(int id,
 
     wxWndHook = this;
 
 
     wxWndHook = this;
 
+#ifndef __WXMICROWIN__
     if ( dialog_template )
     {
     if ( dialog_template )
     {
-#ifndef __WXMICROWIN__
         // for the dialogs without wxDIALOG_NO_PARENT style, use the top level
         // app window as parent - this avoids creating modal dialogs without
         // parent
         // for the dialogs without wxDIALOG_NO_PARENT style, use the top level
         // app window as parent - this avoids creating modal dialogs without
         // parent
@@ -2728,11 +2834,10 @@ bool wxWindowMSW::MSWCreate(int id,
         {
             wxLogLastError(wxT("MoveWindow"));
         }
         {
             wxLogLastError(wxT("MoveWindow"));
         }
-#endif
-       // __WXMICROWIN__
 
     }
     else // creating a normal window, not a dialog
 
     }
     else // creating a normal window, not a dialog
+#endif // !__WXMICROWIN__
     {
         int controlId = 0;
         if ( style & WS_CHILD )
     {
         int controlId = 0;
         if ( style & WS_CHILD )
@@ -2763,8 +2868,7 @@ bool wxWindowMSW::MSWCreate(int id,
 
         if ( !m_hWnd )
         {
 
         if ( !m_hWnd )
         {
-            wxLogError(_("Can't create window of class %s!\nPossible Windows 3.x compatibility problem?"),
-                       wclass);
+            wxLogSysError(_("Can't create window of class %s"), wclass);
 
             return FALSE;
         }
 
             return FALSE;
         }
@@ -2829,7 +2933,7 @@ bool wxWindowMSW::HandleNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
 
     // finally try this window too (catches toolbar case)
     return MSWOnNotify(idCtrl, lParam, result);
 
     // finally try this window too (catches toolbar case)
     return MSWOnNotify(idCtrl, lParam, result);
-#else
+#else // __WXMICROWIN__
     return FALSE;
 #endif
 }
     return FALSE;
 #endif
 }
@@ -2883,15 +2987,16 @@ bool wxWindowMSW::HandleEndSession(bool endSession, long logOff)
     if ( !endSession )
         return FALSE;
 
     if ( !endSession )
         return FALSE;
 
+    // only send once
+    if ( (this != wxTheApp->GetTopWindow()) )
+        return FALSE;
+
     wxCloseEvent event(wxEVT_END_SESSION, -1);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(FALSE);
     event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
     wxCloseEvent event(wxEVT_END_SESSION, -1);
     event.SetEventObject(wxTheApp);
     event.SetCanVeto(FALSE);
     event.SetLoggingOff( (logOff == (long)ENDSESSION_LOGOFF) );
-    if ( (this == wxTheApp->GetTopWindow()) && // Only send once
-        wxTheApp->ProcessEvent(event))
-    {
-    }
-    return TRUE;
+
+    return wxTheApp->ProcessEvent(event);
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -2933,33 +3038,6 @@ bool wxWindowMSW::HandleDestroy()
 // activation/focus
 // ---------------------------------------------------------------------------
 
 // activation/focus
 // ---------------------------------------------------------------------------
 
-void wxWindowMSW::OnSetFocus(wxFocusEvent& event)
-{
-    // panel wants to track the window which was the last to have focus in it,
-    // so we want to set ourselves as the window which last had focus
-    //
-    // notice that it's also important to do it upwards the tree becaus
-    // otherwise when the top level panel gets focus, it won't set it back to
-    // us, but to some other sibling
-    wxWindow *win = (wxWindow *)this;
-    while ( win )
-    {
-        wxWindow *parent = win->GetParent();
-        wxPanel *panel = wxDynamicCast(parent, wxPanel);
-        if ( panel )
-        {
-            panel->SetLastFocus(win);
-        }
-
-        win = parent;
-    }
-
-    wxLogTrace(_T("focus"), _T("%s (0x%08x) gets focus"),
-               GetClassInfo()->GetClassName(), GetHandle());
-
-    event.Skip();
-}
-
 bool wxWindowMSW::HandleActivate(int state,
                               bool WXUNUSED(minimized),
                               WXHWND WXUNUSED(activate))
 bool wxWindowMSW::HandleActivate(int state,
                               bool WXUNUSED(minimized),
                               WXHWND WXUNUSED(activate))
@@ -2974,6 +3052,11 @@ bool wxWindowMSW::HandleActivate(int state,
 
 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
 {
 
 bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
 {
+    // notify the parent keeping track of focus for the kbd navigation
+    // purposes that we got it
+    wxChildFocusEvent eventFocus((wxWindow *)this);
+    (void)GetEventHandler()->ProcessEvent(eventFocus);
+
 #if wxUSE_CARET
     // Deal with caret
     if ( m_caret )
 #if wxUSE_CARET
     // Deal with caret
     if ( m_caret )
@@ -2982,6 +3065,15 @@ bool wxWindowMSW::HandleSetFocus(WXHWND hwnd)
     }
 #endif // wxUSE_CARET
 
     }
 #endif // wxUSE_CARET
 
+#if wxUSE_TEXTCTRL
+    // If it's a wxTextCtrl don't send the event as it will be done
+    // after the control gets to process it from EN_FOCUS handler
+    if ( wxDynamicCastThis(wxTextCtrl) )
+    {
+        return FALSE;
+    }
+#endif // wxUSE_TEXTCTRL
+
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
 
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
 
@@ -3001,6 +3093,16 @@ bool wxWindowMSW::HandleKillFocus(WXHWND hwnd)
     }
 #endif // wxUSE_CARET
 
     }
 #endif // wxUSE_CARET
 
+#if wxUSE_TEXTCTRL
+    // If it's a wxTextCtrl don't send the event as it will be done
+    // after the control gets to process it.
+    wxTextCtrl *ctrl = wxDynamicCastThis(wxTextCtrl);
+    if ( ctrl )
+    {
+        return FALSE;
+    }
+#endif
+
     wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
     event.SetEventObject(this);
 
     wxFocusEvent event(wxEVT_KILL_FOCUS, m_windowId);
     event.SetEventObject(this);
 
@@ -3057,14 +3159,15 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam)
 
     wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
     event.m_eventObject = this;
 
     wxDropFilesEvent event(wxEVT_DROP_FILES, gwFilesDropped, files);
     event.m_eventObject = this;
-    event.m_pos.x = dropPoint.x; event.m_pos.x = dropPoint.y;
+    event.m_pos.x = dropPoint.x;
+    event.m_pos.y = dropPoint.y;
 
     bool rc = GetEventHandler()->ProcessEvent(event);
 
     delete[] files;
 
     return rc;
 
     bool rc = GetEventHandler()->ProcessEvent(event);
 
     delete[] files;
 
     return rc;
-#else
+#else // __WXMICROWIN__
     return FALSE;
 #endif
 }
     return FALSE;
 #endif
 }
@@ -3150,7 +3253,8 @@ bool wxWindowMSW::HandleSetCursor(WXHWND WXUNUSED(hWnd),
         // cursor set, stop here
         return TRUE;
     }
         // cursor set, stop here
         return TRUE;
     }
-#endif
+#endif // __WXMICROWIN__
+
     // pass up the window chain
     return FALSE;
 }
     // pass up the window chain
     return FALSE;
 }
@@ -3165,9 +3269,9 @@ bool wxWindowMSW::MSWOnDrawItem(int id, WXDRAWITEMSTRUCT *itemStruct)
 
 #if wxUSE_MENUS_NATIVE
     // is it a menu item?
 
 #if wxUSE_MENUS_NATIVE
     // is it a menu item?
-    if ( id == 0 )
+    DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
+    if ( id == 0 && pDrawStruct->CtlType == ODT_MENU )
     {
     {
-        DRAWITEMSTRUCT *pDrawStruct = (DRAWITEMSTRUCT *)itemStruct;
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
         wxMenuItem *pMenuItem = (wxMenuItem *)(pDrawStruct->itemData);
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
@@ -3206,9 +3310,9 @@ bool wxWindowMSW::MSWOnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
 {
 #if wxUSE_OWNER_DRAWN
     // is it a menu item?
 {
 #if wxUSE_OWNER_DRAWN
     // is it a menu item?
-    if ( id == 0 )
+    MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
+    if ( id == 0 && pMeasureStruct->CtlType == ODT_MENU )
     {
     {
-        MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
         wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
@@ -3266,7 +3370,7 @@ bool wxWindowMSW::HandleCtlColor(WXHBRUSH *brush,
         *brush = hBrush;
 
     return hBrush != 0;
         *brush = hBrush;
 
     return hBrush != 0;
-#else
+#else // __WXMICROWIN__
     return FALSE;
 #endif
 }
     return FALSE;
 #endif
 }
@@ -3709,8 +3813,8 @@ bool wxWindowMSW::HandleMouseWheel(WXWPARAM wParam, WXLPARAM lParam)
 // create the key event of the given type for the given key - used by
 // HandleChar and HandleKeyDown/Up
 wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
 // create the key event of the given type for the given key - used by
 // HandleChar and HandleKeyDown/Up
 wxKeyEvent wxWindowMSW::CreateKeyEvent(wxEventType evType,
-                                    int id,
-                                    WXLPARAM lParam) const
+                                       int id,
+                                       WXLPARAM lParam) const
 {
     wxKeyEvent event(evType);
     event.SetId(GetId());
 {
     wxKeyEvent event(evType);
     event.SetId(GetId());
@@ -4080,14 +4184,11 @@ int wxCharCodeMSWToWX(int keySym)
         case VK_NUMPAD7:    id = WXK_NUMPAD7; break;
         case VK_NUMPAD8:    id = WXK_NUMPAD8; break;
         case VK_NUMPAD9:    id = WXK_NUMPAD9; break;
         case VK_NUMPAD7:    id = WXK_NUMPAD7; break;
         case VK_NUMPAD8:    id = WXK_NUMPAD8; break;
         case VK_NUMPAD9:    id = WXK_NUMPAD9; break;
-        case VK_MULTIPLY:   id = WXK_MULTIPLY; break;
-        case 0xBB: // VK_OEM_PLUS
-        case VK_ADD:        id = WXK_ADD; break;
-        case 0xBD: // VK_OEM_MINUS
-        case VK_SUBTRACT:   id = WXK_SUBTRACT; break;
-        case 0xBE: // VK_OEM_PERIOD
-        case VK_DECIMAL:    id = WXK_DECIMAL; break;
-        case VK_DIVIDE:     id = WXK_DIVIDE; break;
+        case VK_MULTIPLY:   id = WXK_NUMPAD_MULTIPLY; break;
+        case VK_ADD:        id = WXK_NUMPAD_ADD; break;
+        case VK_SUBTRACT:   id = WXK_NUMPAD_SUBTRACT; break;
+        case VK_DECIMAL:    id = WXK_NUMPAD_DECIMAL; break;
+        case VK_DIVIDE:     id = WXK_NUMPAD_DIVIDE; break;
         case VK_F1:         id = WXK_F1; break;
         case VK_F2:         id = WXK_F2; break;
         case VK_F3:         id = WXK_F3; break;
         case VK_F1:         id = WXK_F1; break;
         case VK_F2:         id = WXK_F2; break;
         case VK_F3:         id = WXK_F3; break;
@@ -4157,11 +4258,11 @@ int wxCharCodeWXToMSW(int id, bool *isVirtual)
     case WXK_NUMPAD7:   keySym = VK_NUMPAD7; break;
     case WXK_NUMPAD8:   keySym = VK_NUMPAD8; break;
     case WXK_NUMPAD9:   keySym = VK_NUMPAD9; break;
     case WXK_NUMPAD7:   keySym = VK_NUMPAD7; break;
     case WXK_NUMPAD8:   keySym = VK_NUMPAD8; break;
     case WXK_NUMPAD9:   keySym = VK_NUMPAD9; break;
-    case WXK_MULTIPLY:  keySym = VK_MULTIPLY; break;
-    case WXK_ADD:       keySym = VK_ADD; break;
-    case WXK_SUBTRACT:  keySym = VK_SUBTRACT; break;
-    case WXK_DECIMAL:   keySym = VK_DECIMAL; break;
-    case WXK_DIVIDE:    keySym = VK_DIVIDE; break;
+    case WXK_NUMPAD_MULTIPLY:  keySym = VK_MULTIPLY; break;
+    case WXK_NUMPAD_ADD:       keySym = VK_ADD; break;
+    case WXK_NUMPAD_SUBTRACT:  keySym = VK_SUBTRACT; break;
+    case WXK_NUMPAD_DECIMAL:   keySym = VK_DECIMAL; break;
+    case WXK_NUMPAD_DIVIDE:    keySym = VK_DIVIDE; break;
     case WXK_F1:        keySym = VK_F1; break;
     case WXK_F2:        keySym = VK_F2; break;
     case WXK_F3:        keySym = VK_F3; break;
     case WXK_F1:        keySym = VK_F1; break;
     case WXK_F2:        keySym = VK_F2; break;
     case WXK_F3:        keySym = VK_F3; break;
@@ -4245,19 +4346,27 @@ extern wxWindow *wxGetWindowFromHWND(WXHWND hWnd)
 #endif // wxUSE_SPINCTRL
 
 #endif // Win32
 #endif // wxUSE_SPINCTRL
 
 #endif // Win32
-
-            if ( !win )
-            {
-                // hwnd is not a wxWindow, try its parent next below
-                hwnd = ::GetParent(hwnd);
-            }
         }
     }
 
     while ( hwnd && !win )
     {
         }
     }
 
     while ( hwnd && !win )
     {
-        win = wxFindWinFromHandle((WXHWND)hwnd);
+        // this is a really ugly hack needed to avoid mistakenly returning the
+        // parent frame wxWindow for the find/replace modeless dialog HWND -
+        // this, in turn, is needed to call IsDialogMessage() from
+        // wxApp::ProcessMessage() as for this we must return NULL from here
+        //
+        // FIXME: this is clearly not the best way to do it but I think we'll
+        //        need to change HWND <-> wxWindow code more heavily than I can
+        //        do it now to fix it
+        if ( ::GetWindow(hwnd, GW_OWNER) )
+        {
+            // it's a dialog box, don't go upwards
+            break;
+        }
+
         hwnd = ::GetParent(hwnd);
         hwnd = ::GetParent(hwnd);
+        win = wxFindWinFromHandle((WXHWND)hwnd);
     }
 
     return win;
     }
 
     return win;
@@ -4341,7 +4450,8 @@ wxKeyboardHook(int nCode, WORD wParam, DWORD lParam)
 
     return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
 }
 
     return (int)CallNextHookEx(wxTheKeyboardHook, nCode, wParam, lParam);
 }
-#endif
+
+#endif // !__WXMICROWIN__
 
 #ifdef __WXDEBUG__
 const char *wxGetMessageName(int message)
 
 #ifdef __WXDEBUG__
 const char *wxGetMessageName(int message)