]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/window.cpp
wxExecute() fixes and doc updates: the return value for sync exec case is now
[wxWidgets.git] / src / msw / window.cpp
index 08cf3ce65d40b941a4dcdb1d425d4549f051da34..8b970ba6960d03663b16d8ddde0bda47bb8e8bb2 100644 (file)
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
 #include "wx/wxprec.h"
 
 #ifdef __BORLANDC__
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
 #endif
 
 #ifndef WX_PRECOMP
-#include <stdio.h>
-#include "wx/setup.h"
-#include "wx/menu.h"
-#include "wx/dc.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/listbox.h"
-#include "wx/button.h"
-#include "wx/settings.h"
-#include "wx/msgdlg.h"
+    #include "wx/setup.h"
+    #include "wx/menu.h"
+    #include "wx/dc.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/listbox.h"
+    #include "wx/button.h"
+    #include "wx/settings.h"
+    #include "wx/msgdlg.h"
+
+    #include <stdio.h>
 #endif
 
 #if     wxUSE_OWNER_DRAWN
 #endif
 
 #if     wxUSE_OWNER_DRAWN
-#include "wx/ownerdrw.h"
+    #include "wx/ownerdrw.h"
 #endif
 
 #if     wxUSE_DRAG_AND_DROP
 #endif
 
 #if     wxUSE_DRAG_AND_DROP
-#include "wx/msw/ole/droptgt.h"
+    #include "wx/msw/ole/droptgt.h"
 #endif
 
 #include "wx/menuitem.h"
 #include "wx/log.h"
 #endif
 
 #include "wx/menuitem.h"
 #include "wx/log.h"
+
+#if wxUSE_TOOLTIPS
+#include "wx/tooltip.h"
+#endif
+
+#include "wx/intl.h"
+#include "wx/log.h"
+
 #include "wx/msw/private.h"
 
 #include <string.h>
 
 #ifndef __GNUWIN32__
 #include "wx/msw/private.h"
 
 #include <string.h>
 
 #ifndef __GNUWIN32__
-#include <shellapi.h>
-#include <mmsystem.h>
+    #include <shellapi.h>
+    #include <mmsystem.h>
 #endif
 
 #ifdef __WIN32__
 #endif
 
 #ifdef __WIN32__
-#include <windowsx.h>
+    #include <windowsx.h>
+#endif
+
+#if (defined(__WIN95__) && !defined(__GNUWIN32__)) || defined(__TWIN32__)
+#include <commctrl.h>
 #endif
 
 #endif
 
-#ifdef __GNUWIN32__
-#include <wx/msw/gnuwin32/extra.h>
+#ifndef __TWIN32__
+    #ifdef __GNUWIN32__
+        #include <wx/msw/gnuwin32/extra.h>
+    #endif
 #endif
 
 #endif
 
+// all these are defined in <windows.h>
 #ifdef GetCharWidth
 #undef GetCharWidth
 #endif
 #ifdef GetCharWidth
 #undef GetCharWidth
 #endif
 #endif
 
 #ifdef  __WXDEBUG__
 #endif
 
 #ifdef  __WXDEBUG__
-const char *wxGetMessageName(int message);
+    const char *wxGetMessageName(int message);
 #endif  //__WXDEBUG__
 
 #define WINDOW_MARGIN 3 // This defines sensitivity of Leave events
 
 wxMenu *wxCurrentPopupMenu = NULL;
 #endif  //__WXDEBUG__
 
 #define WINDOW_MARGIN 3 // This defines sensitivity of Leave events
 
 wxMenu *wxCurrentPopupMenu = NULL;
-extern wxList wxPendingDelete;
+extern wxList WXDLLEXPORT wxPendingDelete;
 
 void wxRemoveHandleAssociation(wxWindow *win);
 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
 #if !USE_SHARED_LIBRARY
 
 void wxRemoveHandleAssociation(wxWindow *win);
 void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
 wxWindow *wxFindWinFromHandle(WXHWND hWnd);
 
 #if !USE_SHARED_LIBRARY
-IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
+    IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxEvtHandler)
 #endif
 
 BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
 #endif
 
 BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler)
@@ -123,7 +139,7 @@ wxWindow *wxWindow::FindItem(int id) const
         if (childWin->IsKindOf(CLASSINFO(wxControl)))
         {
             wxControl *item = (wxControl *)childWin;
         if (childWin->IsKindOf(CLASSINFO(wxControl)))
         {
             wxControl *item = (wxControl *)childWin;
-            if (item->m_windowId == id)
+            if (item->GetId() == id)
                 return item;
             else
             {
                 return item;
             else
             {
@@ -175,9 +191,23 @@ bool wxWindow::MSWCommand(WXUINT WXUNUSED(param), WXWORD WXUNUSED(id))
 }
 
 bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam),
 }
 
 bool wxWindow::MSWNotify(WXWPARAM WXUNUSED(wParam),
-                         WXLPARAM WXUNUSED(lParam),
+                         WXLPARAM lParam,
                          WXLPARAM* WXUNUSED(result))
 {
                          WXLPARAM* WXUNUSED(result))
 {
+#ifdef __WIN95__
+#if wxUSE_TOOLTIPS
+    NMHDR* hdr = (NMHDR *)lParam;
+    if ( hdr->code == TTN_NEEDTEXT && m_tooltip )
+    {
+        TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
+        ttt->lpszText = (char *)m_tooltip->GetTip().c_str();
+
+        // processed
+        return TRUE;
+    }
+#endif
+#endif
+
     return FALSE;
 }
 
     return FALSE;
 }
 
@@ -264,6 +294,10 @@ void wxWindow::Init()
 #if  wxUSE_DRAG_AND_DROP
     m_pDropTarget = NULL;
 #endif
 #if  wxUSE_DRAG_AND_DROP
     m_pDropTarget = NULL;
 #endif
+
+#if wxUSE_TOOLTIPS
+    m_tooltip = NULL;
+#endif
 }
 
 wxWindow::wxWindow()
 }
 
 wxWindow::wxWindow()
@@ -274,8 +308,22 @@ wxWindow::wxWindow()
 // Destructor
 wxWindow::~wxWindow()
 {
 // Destructor
 wxWindow::~wxWindow()
 {
+    // Remove potential dangling pointer
+    if (GetParent() && GetParent()->IsKindOf(CLASSINFO(wxPanel)))
+    {
+        wxPanel* panel = (wxPanel*) GetParent();
+        if (panel->GetLastFocus() == this)
+            panel->SetLastFocus((wxWindow*) NULL);
+    }
+
     m_isBeingDeleted = TRUE;
 
     m_isBeingDeleted = TRUE;
 
+    // first of all, delete the things on which nothing else depends
+
+#if wxUSE_TOOLTIPS
+    wxDELETE(m_tooltip);
+#endif
+
     // JACS - if behaviour is odd, restore this
     // to the start of ~wxWindow. Vadim has changed
     // it to nearer the end. Unsure of side-effects
     // JACS - if behaviour is odd, restore this
     // to the start of ~wxWindow. Vadim has changed
     // it to nearer the end. Unsure of side-effects
@@ -288,6 +336,7 @@ wxWindow::~wxWindow()
     // delete themselves.
 #if wxUSE_CONSTRAINTS
     DeleteRelatedConstraints();
     // delete themselves.
 #if wxUSE_CONSTRAINTS
     DeleteRelatedConstraints();
+
     if (m_constraints)
     {
         // This removes any dangling pointers to this window
     if (m_constraints)
     {
         // This removes any dangling pointers to this window
@@ -296,11 +345,9 @@ wxWindow::~wxWindow()
         delete m_constraints;
         m_constraints = NULL;
     }
         delete m_constraints;
         m_constraints = NULL;
     }
-    if (m_windowSizer)
-    {
-        delete m_windowSizer;
-        m_windowSizer = NULL;
-    }
+
+    wxDELETE(m_windowSizer);
+
     // If this is a child of a sizer, remove self from parent
     if (m_sizerParent)
         m_sizerParent->RemoveChild((wxWindow *)this);
     // If this is a child of a sizer, remove self from parent
     if (m_sizerParent)
         m_sizerParent->RemoveChild((wxWindow *)this);
@@ -497,7 +544,8 @@ void wxWindow::SetDropTarget(wxDropTarget *pDropTarget)
         m_pDropTarget->Register(m_hWnd);
 }
 
         m_pDropTarget->Register(m_hWnd);
 }
 
-#endif
+#endif // wxUSE_DRAG_AND_DROP
+
 
 //old style file-manager drag&drop support
 // I think we should retain the old-style
 
 //old style file-manager drag&drop support
 // I think we should retain the old-style
@@ -510,6 +558,28 @@ void wxWindow::DragAcceptFiles(bool accept)
         ::DragAcceptFiles(hWnd, (BOOL)accept);
 }
 
         ::DragAcceptFiles(hWnd, (BOOL)accept);
 }
 
+// ----------------------------------------------------------------------------
+// tooltips
+// ----------------------------------------------------------------------------
+
+#if wxUSE_TOOLTIPS
+
+void wxWindow::SetToolTip(const wxString &tip)
+{
+    SetToolTip(new wxToolTip(tip));
+}
+
+void wxWindow::SetToolTip(wxToolTip *tooltip)
+{
+    if ( m_tooltip )
+        delete m_tooltip;
+
+    m_tooltip = tooltip;
+    m_tooltip->SetWindow(this);
+}
+
+#endif // wxUSE_TOOLTIPS
+
 // Get total size
 void wxWindow::GetSize(int *x, int *y) const
 {
 // Get total size
 void wxWindow::GetSize(int *x, int *y) const
 {
@@ -700,13 +770,14 @@ void wxWindow::AdjustForParentClientOrigin(int& x, int& y, int sizeFlags)
 
 bool wxWindow::Show(bool show)
 {
 
 bool wxWindow::Show(bool show)
 {
+    m_isShown = show;
     HWND hWnd = (HWND) GetHWND();
     int cshow;
     if (show)
         cshow = SW_SHOW;
     else
         cshow = SW_HIDE;
     HWND hWnd = (HWND) GetHWND();
     int cshow;
     if (show)
         cshow = SW_SHOW;
     else
         cshow = SW_HIDE;
-    ShowWindow(hWnd, (BOOL)cshow);
+    ShowWindow(hWnd, cshow);
     if (show)
     {
         BringWindowToTop(hWnd);
     if (show)
     {
         BringWindowToTop(hWnd);
@@ -718,7 +789,11 @@ bool wxWindow::Show(bool show)
 
 bool wxWindow::IsShown(void) const
 {
 
 bool wxWindow::IsShown(void) const
 {
-    return (::IsWindowVisible((HWND) GetHWND()) != 0);
+    // Can't rely on IsWindowVisible, since it will return FALSE
+    // if the parent is not visible.
+    return m_isShown;
+//    int ret = ::IsWindowVisible((HWND) GetHWND()) ;
+//    return (ret != 0);
 }
 
 int wxWindow::GetCharHeight(void) const
 }
 
 int wxWindow::GetCharHeight(void) const
@@ -841,12 +916,9 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
         wxWndHook = NULL;
         wnd->m_hWnd = (WXHWND) hWnd;
     }
         wxWndHook = NULL;
         wnd->m_hWnd = (WXHWND) hWnd;
     }
-    //    wxDebugMsg("hWnd = %d, m_hWnd = %d, msg = %d\n", hWnd, m_hWnd, message);
 
 
-    // Stop right here if we don't have a valid handle
-    // in our wxWnd object.
+    // Stop right here if we don't have a valid handle in our wxWindow object.
     if (wnd && !wnd->m_hWnd) {
     if (wnd && !wnd->m_hWnd) {
-        //    wxDebugMsg("Warning: could not find a valid handle, wx_win.cc/wxWndProc.\n");
         wnd->m_hWnd = (WXHWND) hWnd;
         long res = wnd->MSWDefWindowProc(message, wParam, lParam );
         wnd->m_hWnd = 0;
         wnd->m_hWnd = (WXHWND) hWnd;
         long res = wnd->MSWDefWindowProc(message, wParam, lParam );
         wnd->m_hWnd = 0;
@@ -866,21 +938,20 @@ LRESULT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
 
 // Should probably have a test for 'genuine' NT
 #if defined(__WIN32__)
 
 // Should probably have a test for 'genuine' NT
 #if defined(__WIN32__)
-#define DIMENSION_TYPE short
+    #define DIMENSION_TYPE short
 #else
 #else
-#define DIMENSION_TYPE int
+    #define DIMENSION_TYPE int
 #endif
 
 // Main Windows 3 window proc
 long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
     wxASSERT( m_lastMsg == message &&
 #endif
 
 // Main Windows 3 window proc
 long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
 {
     wxASSERT( m_lastMsg == message &&
-        m_lastWParam == wParam &&
-        m_lastLParam == lParam );
+              m_lastWParam == wParam && m_lastLParam == lParam );
 
 #ifdef __WXDEBUG__
     wxLogTrace(wxTraceMessages, "Processing %s(%lx, %lx)",
 
 #ifdef __WXDEBUG__
     wxLogTrace(wxTraceMessages, "Processing %s(%lx, %lx)",
-        wxGetMessageName(message), wParam, lParam);
+               wxGetMessageName(message), wParam, lParam);
 #endif // __WXDEBUG__
 
     HWND hWnd = (HWND)m_hWnd;
 #endif // __WXDEBUG__
 
     HWND hWnd = (HWND)m_hWnd;
@@ -1163,28 +1234,62 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
         }
 
     case WM_KEYDOWN:
         }
 
     case WM_KEYDOWN:
-        // we consider these message "not interesting"
+    {
+        // If this has been processed by an event handler,
+        // return 0 now (we've handled it).
+        if (MSWOnKeyDown((WORD) wParam, lParam))
+        {
+            return 0;
+        }
+
+        // we consider these message "not interesting" to OnChar
         if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
         if ( wParam == VK_SHIFT || wParam == VK_CONTROL )
+        {
             return Default();
             return Default();
+        }
 
 
-        // Avoid duplicate messages to OnChar
-        if ( (wParam != VK_ESCAPE) && (wParam != VK_SPACE) &&
-            (wParam != VK_RETURN) && (wParam != VK_BACK) &&
-            (wParam != VK_TAB) )
+        // Avoid duplicate messages to OnChar for these special keys
+        switch ( wParam )
         {
         {
-            MSWOnChar((WORD)wParam, lParam);
-            if ( ::GetKeyState(VK_CONTROL) & 0x100 )
-                return Default();
+            case VK_ESCAPE:
+            case VK_SPACE:
+            case VK_RETURN:
+            case VK_BACK:
+            case VK_TAB:
+            case VK_LEFT:
+            case VK_RIGHT:
+            case VK_DOWN:
+            case VK_UP:
+/*
+//            if ( ::GetKeyState(VK_CONTROL) & 0x100 ) // Don't understand purpose of this test
+                if (!MSWOnChar((WORD)wParam, lParam))
+                    return Default();
+                break;
+*/
+            default:
+                if (!MSWOnChar((WORD)wParam, lParam))
+                {
+                    return Default();
+                }
+/*
+                if ( ::GetKeyState(VK_CONTROL) & 0x100 )
+                    return Default();
+*/
+                break;
         }
         }
-        else if ( ::GetKeyState(VK_CONTROL) & 0x100 )
-            MSWOnChar((WORD)wParam, lParam);
-        else
+
+        break;
+    }
+    case WM_KEYUP:
+    {
+        if (!MSWOnKeyUp((WORD) wParam, lParam))
             return Default();
         break;
             return Default();
         break;
-
+    }
     case WM_CHAR: // Always an ASCII character
         {
     case WM_CHAR: // Always an ASCII character
         {
-            MSWOnChar((WORD)wParam, lParam, TRUE);
+            if (!MSWOnChar((WORD)wParam, lParam, TRUE))
+                return Default();
             break;
         }
 
             break;
         }
 
@@ -1387,6 +1492,7 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
     default:
         return MSWDefWindowProc(message, wParam, lParam );
     }
     default:
         return MSWDefWindowProc(message, wParam, lParam );
     }
+
     return 0; // Success: we processed this command.
 }
 
     return 0; // Success: we processed this command.
 }
 
@@ -1410,7 +1516,7 @@ void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win)
 {
     // adding NULL hWnd is (first) surely a result of an error and
     // (secondly) breaks menu command processing
 {
     // 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" );
+    wxCHECK_RET( hWnd != (HWND) NULL, "attempt to add a NULL hWnd to window list" );
 
     if ( !wxWinHandleList->Find((long)hWnd) )
         wxWinHandleList->Append((long)hWnd, win);
 
     if ( !wxWinHandleList->Find((long)hWnd) )
         wxWinHandleList->Append((long)hWnd, win);
@@ -1653,6 +1759,13 @@ bool wxWindow::MSWOnSetFocus(WXHWND WXUNUSED(hwnd))
             ::ShowCaret((HWND) GetHWND());
     }
 
             ::ShowCaret((HWND) GetHWND());
     }
 
+    // panel wants to track the window which was the last to have focus in it
+    wxWindow *parent = GetParent();
+    if ( parent && parent->IsKindOf(CLASSINFO(wxPanel)) )
+    {
+        ((wxPanel *)parent)->SetLastFocus(this);
+    }
+
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
     if (!GetEventHandler()->ProcessEvent(event))
     wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId);
     event.SetEventObject(this);
     if (!GetEventHandler()->ProcessEvent(event))
@@ -1878,26 +1991,36 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
         if ( msg->message != WM_KEYDOWN )
             bProcess = FALSE;
 
         if ( msg->message != WM_KEYDOWN )
             bProcess = FALSE;
 
-        if ( (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
+        if ( bProcess && (HIWORD(msg->lParam) & KF_ALTDOWN) == KF_ALTDOWN )
             bProcess = FALSE;
 
             bProcess = FALSE;
 
-        bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
+        if ( bProcess )
+        {
+            bool bCtrlDown = (::GetKeyState(VK_CONTROL) & 0x100) != 0;
 
 
-        // WM_GETDLGCODE: if the control wants it for itself, don't process it
-        // (except for Ctrl-Tab combination which is always processed)
-        LONG lDlgCode = 0;
-        if ( bProcess && !bCtrlDown ) {
-            lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
-        }
+            // WM_GETDLGCODE: ask the control if it wants the key for itself,
+            // don't process it if it's the case (except for Ctrl-Tab/Enter
+            // combinations which are always processed)
+            LONG lDlgCode = 0;
+            if ( !bCtrlDown )
+            {
+                lDlgCode = ::SendMessage(msg->hwnd, WM_GETDLGCODE, 0, 0);
+            }
+
+            bool bForward = TRUE,
+                 bWindowChange = FALSE;
 
 
-        bool bForward = TRUE;
-        if ( bProcess ) {
-            switch ( msg->wParam ) {
+            switch ( msg->wParam ) 
+            {
                 case VK_TAB:
                 case VK_TAB:
-                    if ( lDlgCode & DLGC_WANTTAB )  // FALSE for Ctrl-Tab
+                    if ( lDlgCode & DLGC_WANTTAB ) {
                         bProcess = FALSE;
                         bProcess = FALSE;
-                    else
+                    }
+                    else {
+                        // Ctrl-Tab cycles thru notebook pages
+                        bWindowChange = bCtrlDown;
                         bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
                         bForward = !(::GetKeyState(VK_SHIFT) & 0x100);
+                    }
                     break;
 
                 case VK_UP:
                     break;
 
                 case VK_UP:
@@ -1914,23 +2037,60 @@ bool wxWindow::MSWProcessMessage(WXMSG* pMsg)
                         bProcess = FALSE;
                     break;
 
                         bProcess = FALSE;
                     break;
 
+                case VK_RETURN:
+                    {
+                        if ( lDlgCode & DLGC_WANTMESSAGE )
+                        {
+                            // control wants to process Enter itself, don't
+                            // call IsDialogMessage() which would interpret
+                            // it
+                            return FALSE;
+                        }
+#ifndef __WIN16__
+                        wxButton *btnDefault = GetDefaultItem();
+                        if ( btnDefault && !bCtrlDown )
+                        {
+                            // if there is a default button, Enter should
+                            // press it
+                            (void)::SendMessage((HWND)btnDefault->GetHWND(),
+                                                BM_CLICK, 0, 0);
+                            return TRUE;
+                        }
+                        // else: but if there is 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.
+#endif
+                    }
+                    break;
+
                 default:
                     bProcess = FALSE;
             }
                 default:
                     bProcess = FALSE;
             }
-        }
 
 
-        if ( bProcess ) {
-            wxNavigationKeyEvent event;
-            event.SetDirection(bForward);
-            event.SetWindowChange(bCtrlDown);
-            event.SetEventObject(this);
+            if ( bProcess )
+            {
+                wxNavigationKeyEvent event;
+                event.SetDirection(bForward);
+                event.SetWindowChange(bWindowChange);
+                event.SetEventObject(this);
 
 
-            if ( GetEventHandler()->ProcessEvent(event) )
-                return TRUE;
+                if ( GetEventHandler()->ProcessEvent(event) )
+                    return TRUE;
+            }
         }
 
         }
 
-        return ::IsDialogMessage((HWND)GetHWND(), msg) != 0;
+        if ( ::IsDialogMessage((HWND)GetHWND(), msg) )
+            return TRUE;
     }
     }
+#if wxUSE_TOOLTIPS
+    if ( m_tooltip )
+    {
+        // relay mouse move events to the tooltip control
+        MSG *msg = (MSG *)pMsg;
+        if ( msg->message == WM_MOUSEMOVE )
+            m_tooltip->RelayEvent(pMsg);
+    }
+#endif // wxUSE_TOOLTIPS
 
     return FALSE;
 }
 
     return FALSE;
 }
@@ -2147,7 +2307,6 @@ void wxWindow::MSWOnMButtonDown(int x, int y, WXUINT flags)
 
 void wxWindow::MSWOnMButtonUp(int x, int y, WXUINT flags)
 {
 
 void wxWindow::MSWOnMButtonUp(int x, int y, WXUINT flags)
 {
-    //wxDebugMsg("MButtonUp\n") ;
     wxMouseEvent event(wxEVT_MIDDLE_UP);
 
     event.m_x = x; event.m_y = y;
     wxMouseEvent event(wxEVT_MIDDLE_UP);
 
     event.m_x = x; event.m_y = y;
@@ -2327,7 +2486,7 @@ void wxWindow::MSWOnMouseLeave(int x, int y, WXUINT flags)
     GetEventHandler()->ProcessEvent(event);
 }
 
     GetEventHandler()->ProcessEvent(event);
 }
 
-void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+bool wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 {
     int id;
     bool tempControlDown = FALSE;
 {
     int id;
     bool tempControlDown = FALSE;
@@ -2389,11 +2548,94 @@ void wxWindow::MSWOnChar(WXWORD wParam, WXLPARAM lParam, bool isASCII)
 
         event.m_x = pt.x; event.m_y = pt.y;
 
 
         event.m_x = pt.x; event.m_y = pt.y;
 
-        if (!GetEventHandler()->ProcessEvent(event))
-            Default();
+        if (GetEventHandler()->ProcessEvent(event))
+            return TRUE;
+        else
+            return FALSE;
+    }
+    else
+        return FALSE;
+}
+
+bool wxWindow::MSWOnKeyDown(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+{
+    int id;
+
+    if ((id = wxCharCodeMSWToWX(wParam)) == 0) {
+        id = wParam;
+    }
+
+    if (id != -1)
+    {
+        wxKeyEvent event(wxEVT_KEY_DOWN);
+        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
+        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
+        if ((HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN)
+            event.m_altDown = TRUE;
+
+        event.m_eventObject = this;
+        event.m_keyCode = id;
+        event.SetTimestamp(wxApp::sm_lastMessageTime);
+
+        POINT pt ;
+        GetCursorPos(&pt) ;
+        RECT rect ;
+        GetWindowRect((HWND) GetHWND(),&rect) ;
+        pt.x -= rect.left ;
+        pt.y -= rect.top ;
+
+        event.m_x = pt.x; event.m_y = pt.y;
+
+        if (GetEventHandler()->ProcessEvent(event))
+        {
+            return TRUE;
+        }
+        else return FALSE;
+    }
+    else
+    {
+        return FALSE;
     }
 }
 
     }
 }
 
+bool wxWindow::MSWOnKeyUp(WXWORD wParam, WXLPARAM lParam, bool isASCII)
+{
+    int id;
+
+    if ((id = wxCharCodeMSWToWX(wParam)) == 0) {
+        id = wParam;
+    }
+
+    if (id != -1)
+    {
+        wxKeyEvent event(wxEVT_KEY_UP);
+        event.m_shiftDown = (::GetKeyState(VK_SHIFT)&0x100?TRUE:FALSE);
+        event.m_controlDown = (::GetKeyState(VK_CONTROL)&0x100?TRUE:FALSE);
+        if ((HIWORD(lParam) & KF_ALTDOWN) == KF_ALTDOWN)
+            event.m_altDown = TRUE;
+
+        event.m_eventObject = this;
+        event.m_keyCode = id;
+        event.SetTimestamp(wxApp::sm_lastMessageTime);
+
+        POINT pt ;
+        GetCursorPos(&pt) ;
+        RECT rect ;
+        GetWindowRect((HWND) GetHWND(),&rect) ;
+        pt.x -= rect.left ;
+        pt.y -= rect.top ;
+
+        event.m_x = pt.x; event.m_y = pt.y;
+
+        if (GetEventHandler()->ProcessEvent(event))
+            return TRUE;
+        else
+            return FALSE;
+    }
+    else
+        return FALSE;
+}
+
 void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags)
 {
     int buttons = 0;
 void wxWindow::MSWOnJoyDown(int joystick, int x, int y, WXUINT flags)
 {
     int buttons = 0;
@@ -2885,7 +3127,7 @@ void wxSetKeyboardHook(bool doIt)
     {
         wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
         wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
     {
         wxTheKeyboardHookProc = MakeProcInstance((FARPROC) wxKeyboardHook, wxGetInstance());
         wxTheKeyboardHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) wxTheKeyboardHookProc, wxGetInstance(),
-#ifdef __WIN32__
+#if defined(__WIN32__) && !defined(__TWIN32__)
             GetCurrentThreadId());
         //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
 #else
             GetCurrentThreadId());
         //      (DWORD)GetCurrentProcess()); // This is another possibility. Which is right?
 #else
@@ -2969,13 +3211,6 @@ void wxWindow::Centre(int direction)
 
 }
 
 
 }
 
-/* TODO (maybe)
-void wxWindow::OnPaint()
-{
-PaintSelectionHandles();
-}
-*/
-
 void wxWindow::WarpPointer (int x_pos, int y_pos)
 {
     // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
 void wxWindow::WarpPointer (int x_pos, int y_pos)
 {
     // Move the pointer to (x_pos,y_pos) coordinates. They are expressed in
@@ -3024,10 +3259,14 @@ bool wxWindow::MSWOnEraseBkgnd (WXHDC pDC)
 
 void wxWindow::OnEraseBackground(wxEraseEvent& event)
 {
 
 void wxWindow::OnEraseBackground(wxEraseEvent& event)
 {
+    if (!GetHWND())
+        return;
+
     RECT rect;
     ::GetClientRect((HWND) GetHWND(), &rect);
 
     RECT rect;
     ::GetClientRect((HWND) GetHWND(), &rect);
 
-    HBRUSH hBrush = ::CreateSolidBrush(PALETTERGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
+    COLORREF ref = PALETTERGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue()) ;
+    HBRUSH hBrush = ::CreateSolidBrush(ref);
     int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
 
     //  ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect);
     int mode = ::SetMapMode((HDC) event.GetDC()->GetHDC(), MM_TEXT);
 
     //  ::GetClipBox((HDC) event.GetDC()->GetHDC(), &rect);
@@ -3445,7 +3684,7 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
 
     // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
     // effects from extended style
 
     // 5) If this isn't a Win95 app, and we are using CTL3D, remove border
     // effects from extended style
-#if CTL3D
+#if wxUSE_CTL3D
     if ( *want3D )
         nativeBorder = FALSE;
 #endif
     if ( *want3D )
         nativeBorder = FALSE;
 #endif
@@ -3455,7 +3694,7 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
     // If we want 3D, but haven't specified a border here,
     // apply the default border style specified.
     // TODO what about non-Win95 WIN32? Does it have borders?
     // If we want 3D, but haven't specified a border here,
     // apply the default border style specified.
     // TODO what about non-Win95 WIN32? Does it have borders?
-#if defined(__WIN95__) && !CTL3D
+#if defined(__WIN95__) && !wxUSE_CTL3D
     if (defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
         (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
         exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
     if (defaultBorderStyle && (*want3D) && ! ((m_windowStyle & wxDOUBLE_BORDER) || (m_windowStyle & wxRAISED_BORDER) ||
         (m_windowStyle & wxSTATIC_BORDER) || (m_windowStyle & wxSIMPLE_BORDER) ))
         exStyle |= defaultBorderStyle; // WS_EX_CLIENTEDGE ;
@@ -3466,25 +3705,26 @@ WXDWORD wxWindow::Determine3DEffects(WXDWORD defaultBorderStyle, bool *want3D)
 
 void wxWindow::OnChar(wxKeyEvent& event)
 {
 
 void wxWindow::OnChar(wxKeyEvent& event)
 {
-    if ( event.KeyCode() == WXK_TAB ) {
-        // propagate the TABs to the parent - it's up to it to decide what
-        // to do with it
-        if ( GetParent() ) {
-            if ( GetParent()->GetEventHandler()->ProcessEvent(event) )
-                return;
-        }
-    }
-
     bool isVirtual;
     int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
 
     if ( id == -1 )
         id= m_lastWParam;
 
     bool isVirtual;
     int id = wxCharCodeWXToMSW((int)event.KeyCode(), &isVirtual);
 
     if ( id == -1 )
         id= m_lastWParam;
 
-    if ( !event.ControlDown() )
+    if ( !event.ControlDown() ) // Why this test?
         (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
 }
 
         (void) MSWDefWindowProc(m_lastMsg, (WPARAM) id, m_lastLParam);
 }
 
+void wxWindow::OnKeyDown(wxKeyEvent& event)
+{
+    Default();
+}
+
+void wxWindow::OnKeyUp(wxKeyEvent& event)
+{
+    Default();
+}
+
 void wxWindow::OnPaint(wxPaintEvent& event)
 {
     Default();
 void wxWindow::OnPaint(wxPaintEvent& event)
 {
     Default();
@@ -3513,7 +3753,7 @@ bool wxWindow::TransferDataToWindow()
         if ( child->GetValidator() && /* child->GetValidator()->Ok() && */
             !child->GetValidator()->TransferToWindow() )
         {
         if ( child->GetValidator() && /* child->GetValidator()->Ok() && */
             !child->GetValidator()->TransferToWindow() )
         {
-            wxMessageBox("Application Error", "Could not transfer data to window", wxOK|wxICON_EXCLAMATION);
+            wxLogError(_("Could not transfer data to window"));
             return FALSE;
         }
 
             return FALSE;
         }
 
@@ -3895,16 +4135,17 @@ void wxWindow::SetConstraintSizes(bool recurse)
             winName = "unnamed";
         else
             winName = GetName();
             winName = "unnamed";
         else
             winName = GetName();
-        wxDebugMsg("Constraint(s) not satisfied for window of type %s, name %s:\n", (const char *)windowClass, (const char *)winName);
+        wxLogDebug("Constraint(s) not satisfied for window of type %s, name %s:",
+                    (const char *)windowClass, (const char *)winName);
         if (!constr->left.GetDone())
         if (!constr->left.GetDone())
-            wxDebugMsg("  unsatisfied 'left' constraint.\n");
+            wxLogDebug("  unsatisfied 'left' constraint.");
         if (!constr->right.GetDone())
         if (!constr->right.GetDone())
-            wxDebugMsg("  unsatisfied 'right' constraint.\n");
+            wxLogDebug("  unsatisfied 'right' constraint.");
         if (!constr->width.GetDone())
         if (!constr->width.GetDone())
-            wxDebugMsg("  unsatisfied 'width' constraint.\n");
+            wxLogDebug("  unsatisfied 'width' constraint.");
         if (!constr->height.GetDone())
         if (!constr->height.GetDone())
-            wxDebugMsg("  unsatisfied 'height' constraint.\n");
-        wxDebugMsg("Please check constraints: try adding AsIs() constraints.\n");
+            wxLogDebug("  unsatisfied 'height' constraint.");
+        wxLogDebug("Please check constraints: try adding AsIs() constraints.\n");
     }
 
     if (recurse)
     }
 
     if (recurse)
@@ -4038,7 +4279,9 @@ bool wxWindow::Close(bool force)
 {
     wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
     event.SetEventObject(this);
 {
     wxCloseEvent event(wxEVT_CLOSE_WINDOW, m_windowId);
     event.SetEventObject(this);
+#if WXWIN_COMPATIBILITY
     event.SetForce(force);
     event.SetForce(force);
+#endif
     event.SetCanVeto(!force);
 
     return (GetEventHandler()->ProcessEvent(event) && !event.GetVeto());
     event.SetCanVeto(!force);
 
     return (GetEventHandler()->ProcessEvent(event) && !event.GetVeto());
@@ -4330,6 +4573,7 @@ long wxWindow::MSWGetDlgCode()
 
 bool wxWindow::AcceptsFocus() const
 {
 
 bool wxWindow::AcceptsFocus() const
 {
+    // invisible and disabled controls don't need focus
     return IsShown() && IsEnabled();
 }
 
     return IsShown() && IsEnabled();
 }