]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/window.cpp
non PCH compilation
[wxWidgets.git] / src / os2 / window.cpp
index 801175c4ea6b05f537151f3ff3f056303e2bcdd7..7a44b19018cd028220f5721bac92326c5da028a7 100644 (file)
 //
 #include "wx/wxprec.h"
 
+#include "wx/window.h"
+
 #ifndef WX_PRECOMP
     #define INCL_DOS
     #define INCL_PM
     #include <os2.h>
-    #include "wx/window.h"
     #include "wx/accel.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/statusbr.h"
     #include "wx/toolbar.h"
     #include "wx/settings.h"
+    #include "wx/intl.h"
+    #include "wx/log.h"
+    #include "wx/textctrl.h"
+    #include "wx/menuitem.h"
     #include <stdio.h>
 #endif
 
+#include "wx/os2/dcclient.h"
+
 #if wxUSE_OWNER_DRAWN
     #include "wx/ownerdrw.h"
 #endif
@@ -54,9 +61,6 @@
     #include "wx/dnd.h"
 #endif
 
-#include "wx/menuitem.h"
-#include "wx/log.h"
-
 #include "wx/os2/private.h"
 
 #if wxUSE_TOOLTIPS
     #include "wx/caret.h"
 #endif // wxUSE_CARET
 
-#include "wx/intl.h"
-#include "wx/log.h"
-
-
-#include "wx/textctrl.h"
-
 #include <string.h>
 
 //
 QMSG                      s_currentMsg;
 
 #if wxUSE_MENUS_NATIVE
-wxMenu*                   wxCurrentPopupMenu = NULL;
+extern wxMenu*            wxCurrentPopupMenu;
 #endif // wxUSE_MENUS_NATIVE
 
 // ---------------------------------------------------------------------------
@@ -158,8 +156,9 @@ wxWindow* wxFindWinFromHandle(WXHWND hWnd);
 //
 // get the current state of SHIFT/CTRL keys
 //
-static inline bool IsShiftDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_SHIFT) & 0x8000) != 0; }
-static inline bool IsCtrlDown() { return (::WinGetKeyState(HWND_DESKTOP, VK_CTRL) & 0x8000) != 0; }
+static inline bool IsKeyDown(LONG key) {return (::WinGetKeyState(HWND_DESKTOP, key) & 0x8000) != 0; }
+static inline bool IsShiftDown() { return IsKeyDown(VK_SHIFT); }
+static inline bool IsCtrlDown() { return IsKeyDown(VK_CTRL); }
 
 static wxWindow*                    gpWinBeingCreated = NULL;
 
@@ -298,7 +297,6 @@ void wxWindowOS2::Init()
     m_bUseCtl3D             = false;
     m_bMouseInWindow        = false;
     m_bLastKeydownProcessed = false;
-    m_pChildrenDisabled     = NULL;
 
     //
     // wxWnd
@@ -336,7 +334,7 @@ void wxWindowOS2::Init()
 //
 wxWindowOS2::~wxWindowOS2()
 {
-    m_isBeingDeleted = true;
+    SendDestroyEvent();
 
     for (wxWindow* pWin = GetParent(); pWin; pWin = pWin->GetParent())
     {
@@ -354,13 +352,14 @@ wxWindowOS2::~wxWindowOS2()
     if (m_hWnd)
     {
         if(!::WinDestroyWindow(GetHWND()))
+        {
             wxLogLastError(wxT("DestroyWindow"));
+        }
         //
         // remove hWnd <-> wxWindow association
         //
         wxRemoveHandleAssociation(this);
     }
-    delete m_pChildrenDisabled;
 } // end of wxWindowOS2::~wxWindowOS2
 
 // real construction (Init() must have been called before!)
@@ -387,7 +386,7 @@ bool wxWindowOS2::Create( wxWindow*       pParent,
     // static box
     //
     wxASSERT_MSG( !wxDynamicCast(pParent, wxStaticBox),
-                  _T("wxStaticBox can't be used as a window parent!") );
+                  wxT("wxStaticBox can't be used as a window parent!") );
 #endif // wxUSE_STATBOX
 
      // Ensure groupbox backgrounds are painted
@@ -457,7 +456,7 @@ bool wxWindowOS2::Create( wxWindow*       pParent,
 void wxWindowOS2::SetFocus()
 {
     HWND                            hWnd = GetHwnd();
-    wxCHECK_RET( hWnd, _T("can't set focus to invalid window") );
+    wxCHECK_RET( hWnd, wxT("can't set focus to invalid window") );
 
     if (hWnd)
         ::WinSetFocus(HWND_DESKTOP, hWnd);
@@ -482,70 +481,12 @@ wxWindow* wxWindowBase::DoFindFocus()
     return NULL;
 } // wxWindowBase::DoFindFocus
 
-bool wxWindowOS2::Enable( bool bEnable )
+void wxWindowOS2::DoEnable( bool bEnable )
 {
-    if (!wxWindowBase::Enable(bEnable))
-        return false;
-
     HWND                            hWnd = GetHwnd();
-
     if ( hWnd )
         ::WinEnableWindow(hWnd, (BOOL)bEnable);
-
-    //
-    // The logic below doesn't apply to the top level windows -- otherwise
-    // showing a modal dialog would result in total greying out (and ungreying
-    // out later) of everything which would be really ugly
-    //
-    if (IsTopLevel())
-        return true;
-
-    wxWindowList::compatibility_iterator     node = GetChildren().GetFirst();
-
-    while (node)
-    {
-        wxWindow*                   pChild = node->GetData();
-
-        if (bEnable)
-        {
-            //
-            // Enable the child back unless it had been disabled before us
-            //
-            if (!m_pChildrenDisabled || !m_pChildrenDisabled->Find(pChild))
-                pChild->Enable();
-        }
-        else // we're being disabled
-        {
-            if (pChild->IsEnabled())
-            {
-                //
-                // Disable it as children shouldn't stay enabled while the
-                // parent is not
-                //
-                pChild->Disable();
-            }
-            else // child already disabled, remember it
-            {
-                //
-                // Have we created the list of disabled children already?
-                //
-                if (!m_pChildrenDisabled)
-                    m_pChildrenDisabled = new wxWindowList;
-                m_pChildrenDisabled->Append(pChild);
-            }
-        }
-        node = node->GetNext();
-    }
-    if (bEnable && m_pChildrenDisabled)
-    {
-        //
-        // We don't need this list any more, don't keep unused memory
-        //
-        delete m_pChildrenDisabled;
-        m_pChildrenDisabled = NULL;
-    }
-    return true;
-} // end of wxWindowOS2::Enable
+}
 
 bool wxWindowOS2::Show( bool bShow )
 {
@@ -575,7 +516,7 @@ void wxWindowOS2::Lower()
 
 void wxWindowOS2::SetLabel( const wxString& label )
 {
-    ::WinSetWindowText(GetHwnd(), (PSZ)label.c_str());
+    ::WinSetWindowText(GetHwnd(), label.c_str());
 } // end of wxWindowOS2::SetLabel
 
 wxString wxWindowOS2::GetLabel() const
@@ -606,7 +547,7 @@ void wxWindowOS2::DoReleaseMouse()
 /* static */ wxWindow* wxWindowBase::GetCapture()
 {
     HWND hwnd = ::WinQueryCapture(HWND_DESKTOP);
-    return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : (wxWindow *)NULL;
+    return hwnd ? wxFindWinFromHandle((WXHWND)hwnd) : NULL;
 } // end of wxWindowBase::GetCapture
 
 bool wxWindowOS2::SetFont( const wxFont& rFont )
@@ -1145,7 +1086,7 @@ void wxWindowOS2::OnIdle(
                            ,vPoint.y
                            ,nState
                           );
-            (void)GetEventHandler()->ProcessEvent(rEvent);
+            (void)HandleWindowEvent(rEvent);
         }
     }
     if (wxUpdateUIEvent::CanUpdate(this))
@@ -1155,7 +1096,7 @@ void wxWindowOS2::OnIdle(
 //
 // Set this window to be the child of 'parent'.
 //
-bool wxWindowOS2::Reparent( wxWindow* pParent)
+bool wxWindowOS2::Reparent( wxWindowBase* pParent)
 {
     if (!wxWindowBase::Reparent(pParent))
         return false;
@@ -1172,12 +1113,12 @@ void wxWindowOS2::Update()
     ::WinUpdateWindow(GetHwnd());
 } // end of wxWindowOS2::Update
 
-void wxWindowOS2::Freeze()
+void wxWindowOS2::DoFreeze()
 {
    ::WinSendMsg(GetHwnd(), WM_VRNDISABLED, (MPARAM)0, (MPARAM)0);
 } // end of wxWindowOS2::Freeze
 
-void wxWindowOS2::Thaw()
+void wxWindowOS2::DoThaw()
 {
    ::WinSendMsg(GetHwnd(), WM_VRNENABLED, (MPARAM)TRUE, (MPARAM)0);
 
@@ -1683,7 +1624,7 @@ void wxWindowOS2::DoSetClientSize( int nWidth,
     wxSize size( nWidth, nHeight );
     wxSizeEvent vEvent( size, m_windowId );
     vEvent.SetEventObject(this);
-    GetEventHandler()->ProcessEvent(vEvent);
+    HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::DoSetClientSize
 
 // ---------------------------------------------------------------------------
@@ -1722,12 +1663,12 @@ int wxWindowOS2::GetCharWidth() const
     return(vFontMetrics.lAveCharWidth);
 } // end of wxWindowOS2::GetCharWidth
 
-void wxWindowOS2::GetTextExtent( const wxString& rString,
-                                 int* pX,
-                                 int* pY,
-                                 int* pDescent,
-                                 int* pExternalLeading,
-                                 const wxFont* WXUNUSED(pTheFont) ) const
+void wxWindowOS2::DoGetTextExtent( const wxString& rString,
+                                   int* pX,
+                                   int* pY,
+                                   int* pDescent,
+                                   int* pExternalLeading,
+                                   const wxFont* WXUNUSED(pTheFont) ) const
 {
     POINTL      avPoint[TXTBOX_COUNT];
     POINTL      vPtMin;
@@ -1736,7 +1677,6 @@ void wxWindowOS2::GetTextExtent( const wxString& rString,
     int         l;
     FONTMETRICS vFM; // metrics structure
     BOOL        bRc = FALSE;
-    char*       pStr;
     HPS         hPS;
 
     hPS = ::WinGetPS(GetHwnd());
@@ -1744,14 +1684,12 @@ void wxWindowOS2::GetTextExtent( const wxString& rString,
     l = rString.length();
     if (l > 0L)
     {
-        pStr = (PCH)rString.c_str();
-
         //
         // In world coordinates.
         //
         bRc = ::GpiQueryTextBox( hPS,
                                  l,
-                                 pStr,
+                                 (char*) rString.wx_str(),
                                  TXTBOX_COUNT,// return maximum information
                                  avPoint      // array of coordinates points
                                 );
@@ -1814,7 +1752,7 @@ void wxWindowOS2::GetTextExtent( const wxString& rString,
             *pExternalLeading = 0;
     }
     ::WinReleasePS(hPS);
-} // end of wxWindow::GetTextExtent
+} // end of wxWindow::DoGetTextExtent
 
 bool wxWindowOS2::IsMouseInWindow() const
 {
@@ -1850,10 +1788,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
     bool bIsWaiting = true;
     int nHeight;
 
-    // Protect against recursion
-    if (wxCurrentPopupMenu)
-        return false;
-
     pMenu->SetInvokingWindow(this);
     pMenu->UpdateUI();
 
@@ -1870,7 +1804,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
         DoGetSize(0,&nHeight);
         nY = nHeight - nY;
     }
-    wxCurrentPopupMenu = pMenu;
 
     ::WinPopupMenu( hWndParent
                    ,hWndOwner
@@ -1891,7 +1824,6 @@ bool wxWindowOS2::DoPopupMenu( wxMenu* pMenu, int nX, int nY )
         ::WinDispatchMsg(vHabmain, (PQMSG)&vMsg);
     }
 
-    wxCurrentPopupMenu = NULL;
     pMenu->SetInvokingWindow(NULL);
     return true;
 } // end of wxWindowOS2::DoPopupMenu
@@ -2024,9 +1956,13 @@ bool wxWindowOS2::OS2ProcessMessage( WXMSG* pMsg )
                         }
                         else
                         {
-                            wxButton*   pBtn = wxDynamicCast( GetDefaultItem()
-                                                             ,wxButton
-                                                            );
+                            wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow);
+                            wxButton*   pBtn = NULL;
+
+                            if (tlw)
+                            {
+                                pBtn = wxDynamicCast(tlw->GetDefaultItem(), wxButton);
+                            }
 
                             if (pBtn && pBtn->IsEnabled())
                             {
@@ -2063,7 +1999,7 @@ bool wxWindowOS2::OS2ProcessMessage( WXMSG* pMsg )
                 vEvent.SetWindowChange(bWindowChange);
                 vEvent.SetEventObject(this);
 
-                if (GetEventHandler()->ProcessEvent(vEvent))
+                if (HandleWindowEvent(vEvent))
                 {
                     wxButton*       pBtn = wxDynamicCast(FindFocus(), wxButton);
 
@@ -2395,9 +2331,6 @@ MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
         case WM_BUTTON3MOTIONEND:
         case WM_BUTTON3MOTIONSTART:
             {
-                if (uMsg == WM_BUTTON1DOWN && AcceptsFocus())
-                    SetFocus();
-
                 short               nX = LOWORD(wParam);
                 short               nY = HIWORD(wParam);
 
@@ -2420,7 +2353,7 @@ MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
                                                                   );
                     if (!pWin->IsOfStandardClass())
                     {
-                        if (uMsg == WM_BUTTON1DOWN && pWin->AcceptsFocus() )
+                        if (uMsg == WM_BUTTON1DOWN && pWin->CanAcceptFocus() )
                             pWin->SetFocus();
                     }
                     bProcessed = pWin->HandleMouseEvent( uMsg
@@ -2617,7 +2550,7 @@ MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
                             (pPage->ulPageIdNew > 0L && pPage->ulPageIdCur > 0L))
                         {
                             wxWindowOS2*        pWin = wxFindWinFromHandle(pPage->hwndBook);
-                            wxNotebookEvent     vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
+                            wxBookCtrlEvent     vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
                                                        ,(int)SHORT1FROMMP(wParam)
                                                        ,(int)pPage->ulPageIdNew
                                                        ,(int)pPage->ulPageIdCur
@@ -2643,6 +2576,7 @@ MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
                     }
                     break;
 
+                case CBN_LBSELECT:
                 case BN_CLICKED: // Dups as LN_SELECT and CBN_LBSELECT
                     {
                         HWND                hWnd = ::WinWindowFromID((HWND)GetHwnd(), SHORT1FROMMP(wParam));
@@ -2699,11 +2633,19 @@ MRESULT wxWindowOS2::OS2WindowProc( WXUINT uMsg,
                                                   ,(WXWORD)SHORT1FROMMP(wParam)
                                                  );
                         }
+                        if (pWin->IsKindOf(CLASSINFO(wxChoice)))
+                        {
+                            wxChoice*           pChoice = wxDynamicCast(pWin, wxChoice);
+
+                            pChoice->OS2Command( (WXUINT)SHORT2FROMMP(wParam)
+                                                ,(WXWORD)SHORT1FROMMP(wParam)
+                                               );
+                        }
                         return 0;
                     }
                     // break;
 
-                case LN_ENTER:   /* dups as CBN_EFCHANGE */
+                case LN_ENTER:
                     {
                         HWND                hWnd = HWNDFROMMP(lParam);
                         wxWindowOS2*        pWin = wxFindWinFromHandle(hWnd);
@@ -2913,7 +2855,7 @@ void wxAssociateWinWithHandle(
     {
         wxString  Newstr(pWin->GetClassInfo()->GetClassName());
         wxString Oldstr(pOldWin->GetClassInfo()->GetClassName());
-        wxLogError( _T("Bug! New window of class %s has same HWND %X as old window of class %s"),
+        wxLogError( wxT("Bug! New window of class %s has same HWND %X as old window of class %s"),
                     Newstr.c_str(),
                     (int)hWnd,
                     Oldstr.c_str()
@@ -2997,6 +2939,7 @@ bool wxWindowOS2::OS2Create( PSZ            zClass,
     long                 lControlId = 0L;
     wxWindowCreationHook vHook(this);
     wxString             sClassName((wxChar*)zClass);
+    wxString             sTitle(zTitle ? zTitle : wxEmptyString);
 
     OS2GetCreateWindowCoords( rPos
                              ,rSize
@@ -3024,8 +2967,8 @@ bool wxWindowOS2::OS2Create( PSZ            zClass,
         sClassName += wxT("NR");
     }
     m_hWnd = (WXHWND)::WinCreateWindow( (HWND)OS2GetParent()
-                                       ,(PSZ)sClassName.c_str()
-                                       ,(PSZ)(zTitle ? zTitle : wxEmptyString)
+                                       ,sClassName.c_str()
+                                       ,sTitle.c_str()
                                        ,(ULONG)dwStyle
                                        ,(LONG)0L
                                        ,(LONG)0L
@@ -3058,7 +3001,7 @@ bool wxWindowOS2::OS2Create( PSZ            zClass,
     {
         vError = ::WinGetLastError(vHabmain);
         sError = wxPMErrorToStr(vError);
-        wxLogError(_T("Error creating frame. Error: %s\n"), sError.c_str());
+        wxLogError(wxT("Error creating frame. Error: %s\n"), sError.c_str());
         return false;
     }
     SetSize( nX
@@ -3082,7 +3025,7 @@ bool wxWindowOS2::HandleCreate( WXLPCREATESTRUCT WXUNUSED(vCs),
 {
     wxWindowCreateEvent             vEvent((wxWindow*)this);
 
-    (void)GetEventHandler()->ProcessEvent(vEvent);
+    (void)HandleWindowEvent(vEvent);
     *pbMayCreate = true;
     return true;
 } // end of wxWindowOS2::HandleCreate
@@ -3091,7 +3034,7 @@ bool wxWindowOS2::HandleDestroy()
 {
     wxWindowDestroyEvent            vEvent((wxWindow*)this);
     vEvent.SetId(GetId());
-    (void)GetEventHandler()->ProcessEvent(vEvent);
+    (void)HandleWindowEvent(vEvent);
 
     //
     // Delete our drop target if we've got one
@@ -3130,7 +3073,7 @@ bool wxWindowOS2::HandleActivate(
                                            ,m_windowId
                                           );
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleActivate
 
 bool wxWindowOS2::HandleSetFocus( WXHWND WXUNUSED(hWnd) )
@@ -3140,7 +3083,7 @@ bool wxWindowOS2::HandleSetFocus( WXHWND WXUNUSED(hWnd) )
     // purposes that we got it
     //
     wxChildFocusEvent               vEventFocus((wxWindow *)this);
-    (void)GetEventHandler()->ProcessEvent(vEventFocus);
+    (void)HandleWindowEvent(vEventFocus);
 
 #if wxUSE_CARET
     //
@@ -3164,7 +3107,7 @@ bool wxWindowOS2::HandleSetFocus( WXHWND WXUNUSED(hWnd) )
     wxFocusEvent                    vEvent(wxEVT_SET_FOCUS, m_windowId);
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleSetFocus
 
 bool wxWindowOS2::HandleKillFocus( WXHWND hWnd )
@@ -3211,7 +3154,7 @@ bool wxWindowOS2::HandleKillFocus( WXHWND hWnd )
     // wxFindWinFromHandle() may return NULL, it is ok
     //
     vEvent.SetWindow(wxFindWinFromHandle(hWnd));
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleKillFocus
 
 // ---------------------------------------------------------------------------
@@ -3226,7 +3169,7 @@ bool wxWindowOS2::HandleShow(
     wxShowEvent                     vEvent(GetId(), bShow);
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleShow
 
 bool wxWindowOS2::HandleInitDialog( WXHWND WXUNUSED(hWndFocus) )
@@ -3234,7 +3177,7 @@ bool wxWindowOS2::HandleInitDialog( WXHWND WXUNUSED(hWndFocus) )
     wxInitDialogEvent               vEvent(GetId());
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleInitDialog
 
 bool wxWindowOS2::HandleEndDrag(WXWPARAM WXUNUSED(wParam))
@@ -3261,7 +3204,7 @@ bool wxWindowOS2::OS2OnDrawItem( int vId,
                                  WXDRAWITEMSTRUCT* pItemStruct )
 {
 #if wxUSE_OWNER_DRAWN
-    wxDC                            vDc;
+    wxClientDC                      vDc(this);
 
 #if wxUSE_MENUS_NATIVE
     //
@@ -3280,8 +3223,10 @@ bool wxWindowOS2::OS2OnDrawItem( int vId,
                                           ,pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft
                                           ,pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom
                                          );
-        vDc.SetHDC( hDC, false );
-        vDc.SetHPS( pMeasureStruct->hps );
+
+        wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl();
+        impl->SetHDC( hDC, false );
+        impl->SetHPS( pMeasureStruct->hps );
         //
         // Load the wxWidgets Pallete and set to RGB mode
         //
@@ -3295,7 +3240,7 @@ bool wxWindowOS2::OS2OnDrawItem( int vId,
         {
             vError = ::WinGetLastError(vHabmain);
             sError = wxPMErrorToStr(vError);
-            wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
+            wxLogError(wxT("Unable to set current color table (1). Error: %s\n"), sError.c_str());
         }
         //
         // Set the color table to RGB mode
@@ -3310,7 +3255,7 @@ bool wxWindowOS2::OS2OnDrawItem( int vId,
         {
             vError = ::WinGetLastError(vHabmain);
             sError = wxPMErrorToStr(vError);
-            wxLogError(_T("Unable to set current color table. Error: %s\n"), sError.c_str());
+            wxLogError(wxT("Unable to set current color table (2). Error: %s\n"), sError.c_str());
         }
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
@@ -3471,7 +3416,7 @@ bool wxWindowOS2::HandleSysColorChange()
     wxSysColourChangedEvent         vEvent;
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleSysColorChange
 
 bool wxWindowOS2::HandleCtlColor( WXHBRUSH* WXUNUSED(phBrush) )
@@ -3504,7 +3449,7 @@ bool wxWindowOS2::HandlePaletteChanged()
     vEvent.SetEventObject(this);
     vEvent.SetChangedWindow(wxFindWinFromHandle(hWndPalChange));
 
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandlePaletteChanged
 
 //
@@ -3528,7 +3473,7 @@ void wxWindowOS2::OnSysColourChanged(
             wxSysColourChangedEvent vEvent;
 
             rEvent.SetEventObject(pWin);
-            pWin->GetEventHandler()->ProcessEvent(vEvent);
+            pWin->HandleWindowEvent(vEvent);
         }
         node = node->GetNext();
     }
@@ -3542,7 +3487,7 @@ void wxWindow::OnPaint (
   wxPaintEvent&                     rEvent
 )
 {
-    HDC                             hDC = (HDC)wxPaintDC::FindDCInCache((wxWindow*) rEvent.GetEventObject());
+    HDC                             hDC = (HDC)wxPaintDCImpl::FindDCInCache((wxWindow*) rEvent.GetEventObject());
 
     if (hDC != 0)
     {
@@ -3570,15 +3515,10 @@ bool wxWindowOS2::HandlePaint()
          wxLogLastError(wxT("CreateRectRgn"));
          return false;
     }
-
     // Get all the rectangles from the region, convert the individual
     // rectangles to "the other" coordinate system and reassemble a
     // region from the rectangles, to be feed into m_updateRegion.
     //
-    // FIXME: This is a bad hack since OS/2 API specifies that rectangles
-    //        passed into GpiSetRegion must not have Bottom > Top,
-    //        however, at first sight, it _seems_ to work nonetheless.
-    //
     RGNRECT                     vRgnData;
     PRECTL                      pUpdateRects = NULL;
     vRgnData.ulDirection = RECTDIR_LFRT_TOPBOT;
@@ -3608,18 +3548,17 @@ bool wxWindowOS2::HandlePaint()
             {
                 int                 rectHeight;
                 rectHeight = pUpdateRects[i].yTop - pUpdateRects[i].yBottom;
-                pUpdateRects[i].yTop = height - pUpdateRects[i].yTop;
-                pUpdateRects[i].yBottom = pUpdateRects[i].yTop + rectHeight;
+                pUpdateRects[i].yBottom = height - pUpdateRects[i].yTop;
+                pUpdateRects[i].yTop = pUpdateRects[i].yBottom + rectHeight;
             }
             ::GpiSetRegion(hPS, hRgn, vRgnData.crc, pUpdateRects);
             delete [] pUpdateRects;
         }
     }
-
     m_updateRegion = wxRegion(hRgn, hPS);
 
     vEvent.SetEventObject(this);
-    bProcessed = GetEventHandler()->ProcessEvent(vEvent);
+    bProcessed = HandleWindowEvent(vEvent);
 
     if (!bProcessed &&
          IsKindOf(CLASSINFO(wxPanel)) &&
@@ -3733,25 +3672,26 @@ bool wxWindowOS2::HandleEraseBkgnd( WXHDC hDC )
     if (vSwp.fl & SWP_MINIMIZE)
         return true;
 
-    wxDC vDC;
-
-    vDC.m_hPS = (HPS)hDC; // this is really a PS
-    vDC.SetWindow((wxWindow*)this);
+    wxClientDC vDC(this);
+    wxPMDCImpl *impl = (wxPMDCImpl*) vDC.GetImpl();
+    impl->SetHDC(hDC);
+    impl->SetHPS((HPS)hDC); // this is really a PS
 
     wxEraseEvent vEvent(m_windowId, &vDC);
 
     vEvent.SetEventObject(this);
 
-    rc = GetEventHandler()->ProcessEvent(vEvent);
+    rc = HandleWindowEvent(vEvent);
 
-    vDC.m_hPS = NULLHANDLE;
+    impl->SetHPS(NULLHANDLE);
     return true;
 } // end of wxWindowOS2::HandleEraseBkgnd
 
 void wxWindowOS2::OnEraseBackground(wxEraseEvent& rEvent)
 {
     RECTL   vRect;
-    HPS     hPS = rEvent.GetDC()->GetHPS();
+    wxPMDCImpl *impl = (wxPMDCImpl*) rEvent.GetDC()->GetImpl();
+    HPS     hPS = impl->GetHPS();
     APIRET  rc;
     LONG    lColor = m_backgroundColour.GetPixel();
 
@@ -3768,7 +3708,7 @@ bool wxWindowOS2::HandleMinimize()
     wxIconizeEvent                  vEvent(m_windowId);
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleMinimize
 
 bool wxWindowOS2::HandleMaximize()
@@ -3776,7 +3716,7 @@ bool wxWindowOS2::HandleMaximize()
     wxMaximizeEvent                 vEvent(m_windowId);
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleMaximize
 
 bool wxWindowOS2::HandleMove( int nX, int nY )
@@ -3785,7 +3725,7 @@ bool wxWindowOS2::HandleMove( int nX, int nY )
     wxMoveEvent vEvent(pt, m_windowId);
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 }  // end of wxWindowOS2::HandleMove
 
 bool wxWindowOS2::HandleSize( int    nWidth,
@@ -3796,7 +3736,7 @@ bool wxWindowOS2::HandleSize( int    nWidth,
     wxSizeEvent vEvent(sz, m_windowId);
 
     vEvent.SetEventObject(this);
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::HandleSize
 
 bool wxWindowOS2::HandleGetMinMaxInfo( PSWP pSwp )
@@ -3889,12 +3829,9 @@ void wxWindowOS2::InitMouseEvent(
     rEvent.m_shiftDown   = ((uFlags & KC_SHIFT) != 0);
     rEvent.m_controlDown = ((uFlags & KC_CTRL) != 0);
     rEvent.m_altDown     = ((uFlags & KC_ALT) != 0);
-    rEvent.m_leftDown    = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON1) &
-                           0x8000) != 0;
-    rEvent.m_middleDown  = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON3) &
-                           0x8000) != 0;
-    rEvent.m_rightDown   = (::WinGetKeyState(HWND_DESKTOP, VK_BUTTON2) &
-                           0x8000) != 0;
+    rEvent.m_leftDown    = IsKeyDown(VK_BUTTON1);
+    rEvent.m_middleDown  = IsKeyDown(VK_BUTTON3);
+    rEvent.m_rightDown   = IsKeyDown(VK_BUTTON2);
     rEvent.SetTimestamp(s_currentMsg.time);
     rEvent.SetEventObject(this);
     rEvent.SetId(GetId());
@@ -3944,7 +3881,7 @@ bool wxWindowOS2::HandleMouseEvent( WXUINT uMsg,
                        ,uFlags
                        );
 
-        bProcessed = GetEventHandler()->ProcessEvent(vEvent);
+        bProcessed = HandleWindowEvent(vEvent);
         if (!bProcessed)
         {
             HPOINTER hCursor = (HPOINTER)GetCursor().GetHCURSOR();
@@ -3978,7 +3915,7 @@ bool wxWindowOS2::HandleMouseMove( int nX,
                        ,uFlags
                       );
 
-        (void)GetEventHandler()->ProcessEvent(vEvent);
+        (void)HandleWindowEvent(vEvent);
     }
     return HandleMouseEvent( WM_MOUSEMOVE
                             ,nX
@@ -4100,7 +4037,7 @@ bool wxWindowOS2::HandleChar( WXWPARAM WXUNUSED(wParam),
         vEvent.m_controlDown = true;
     }
 
-    return (GetEventHandler()->ProcessEvent(vEvent));
+    return (HandleWindowEvent(vEvent));
 }
 
 bool wxWindowOS2::HandleKeyDown( WXWPARAM wParam,
@@ -4124,7 +4061,7 @@ bool wxWindowOS2::HandleKeyDown( WXWPARAM wParam,
                                           ,(MPARAM)wParam
                                          ));
 
-        if (GetEventHandler()->ProcessEvent(vEvent))
+        if (HandleWindowEvent(vEvent))
         {
             return true;
         }
@@ -4153,7 +4090,7 @@ bool wxWindowOS2::HandleKeyUp( WXWPARAM wParam,
                                          ,(MPARAM)wParam
                                         ));
 
-        if (GetEventHandler()->ProcessEvent(vEvent))
+        if (HandleWindowEvent(vEvent))
             return true;
     }
     return false;
@@ -4219,7 +4156,7 @@ bool wxWindowOS2::OS2OnScroll( int nOrientation,
         default:
             return false;
     }
-    return GetEventHandler()->ProcessEvent(vEvent);
+    return HandleWindowEvent(vEvent);
 } // end of wxWindowOS2::OS2OnScroll
 
 //
@@ -4379,8 +4316,8 @@ int wxCharCodeOS2ToWX(
         case VK_CTRL:       nId = WXK_CONTROL; break;
         case VK_PAUSE:      nId = WXK_PAUSE; break;
         case VK_SPACE:      nId = WXK_SPACE; break;
-        case VK_PAGEUP:     nId = WXK_PRIOR; break;
-        case VK_PAGEDOWN:   nId = WXK_NEXT; break;
+        case VK_PAGEUP:     nId = WXK_PAGEUP; break;
+        case VK_PAGEDOWN:   nId = WXK_PAGEDOWN; break;
         case VK_ESC:        nId = WXK_ESCAPE; break;
         case VK_END:        nId = WXK_END; break;
         case VK_HOME :      nId = WXK_HOME; break;
@@ -4442,15 +4379,16 @@ int wxCharCodeWXToOS2( int nId,
 {
     int nKeySym = 0;
 
-    *bIsVirtual = true;
+    if ( bIsVirtual )
+        *bIsVirtual = true;
     switch (nId)
     {
         case WXK_CLEAR:     nKeySym = VK_CLEAR; break;
         case WXK_SHIFT:     nKeySym = VK_SHIFT; break;
         case WXK_CONTROL:   nKeySym = VK_CTRL; break;
         case WXK_PAUSE:     nKeySym = VK_PAUSE; break;
-        case WXK_PRIOR:     nKeySym = VK_PAGEUP; break;
-        case WXK_NEXT :     nKeySym = VK_PAGEDOWN; break;
+        case WXK_PAGEUP:    nKeySym = VK_PAGEUP; break;
+        case WXK_PAGEDOWN:  nKeySym = VK_PAGEDOWN; break;
         case WXK_END:       nKeySym = VK_END; break;
         case WXK_HOME :     nKeySym = VK_HOME; break;
         case WXK_LEFT :     nKeySym = VK_LEFT; break;
@@ -4488,7 +4426,8 @@ int wxCharCodeWXToOS2( int nId,
         case WXK_SCROLL:    nKeySym = VK_SCRLLOCK; break;
         default:
         {
-            *bIsVirtual = false;
+            if ( bIsVirtual )
+                *bIsVirtual = false;
             nKeySym = nId;
             break;
         }
@@ -4496,6 +4435,29 @@ int wxCharCodeWXToOS2( int nId,
     return nKeySym;
 } // end of wxCharCodeWXToOS2
 
+
+bool wxGetKeyState(wxKeyCode key)
+{
+    wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
+        WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
+
+    const LONG vk = wxCharCodeWXToOS2(key);
+    // if the requested key is a LED key, return true if the led is pressed
+    if ( key == WXK_NUMLOCK || key == WXK_CAPITAL || key == WXK_SCROLL )
+    {
+        // low order bit means LED is highlighted and high order one means the
+        // key is down; for compatibility with the other ports return true if
+        // either one is set
+        return ::WinGetKeyState(HWND_DESKTOP, vk) != 0;
+
+    }
+    else // normal key
+    {
+        return IsKeyDown(vk);
+    }
+}
+
+
 wxWindow* wxGetActiveWindow()
 {
     HWND                            hWnd = ::WinQueryActiveWindow(HWND_DESKTOP);
@@ -5035,12 +4997,29 @@ wxWindow* wxFindWindowAtPoint(const wxPoint& rPt)
 // Get the current mouse position.
 wxPoint wxGetMousePosition()
 {
-    POINTL                          vPt;
+    POINTL vPt;
 
     ::WinQueryPointerPos(HWND_DESKTOP, &vPt);
     return wxPoint(vPt.x, vPt.y);
 }
 
+wxMouseState wxGetMouseState()
+{
+    wxMouseState ms;
+    wxPoint pt = wxGetMousePosition();
+    ms.SetX(pt.x);
+    ms.SetY(pt.y);
+    ms.SetLeftDown(IsKeyDown(VK_BUTTON1));
+    ms.SetMiddleDown(IsKeyDown(VK_BUTTON3));
+    ms.SetRightDown(IsKeyDown(VK_BUTTON2));
+    ms.SetControlDown(IsCtrlDown());
+    ms.SetShiftDown(IsShiftDown());
+    ms.SetAltDown(IsKeyDown(VK_ALT)|IsKeyDown(VK_ALTGRAF));
+    ms.SetMetaDown(IsKeyDown(VK_ALTGRAF));
+    return ms;
+}
+
+
 wxWindowOS2* FindWindowForMouseEvent( wxWindow* pWin,
                                       short*    WXUNUSED(pnX),
                                       short*    WXUNUSED(pnY) )