]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/window.cpp
don't waste time updating state of tools in a hidden toolbar (patch 1612415)
[wxWidgets.git] / src / os2 / window.cpp
index efee222aa0b2974ca1f84fc3091ee36e67bb85e0..c41347074c7625db76600473e21fded8c855bdbb 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/setup.h"
     #include "wx/menu.h"
     #include "wx/dc.h"
     #include "wx/dcclient.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
 
@@ -55,9 +59,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>
 
 //
@@ -159,8 +154,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;
 
@@ -1299,7 +1295,10 @@ void wxWindowOS2::DoGetPosition(
 , int*                              pY
 ) const
 {
-    HWND                            hWnd = GetHwnd();
+    //
+    // Return parameters assume wxWidgets coordinate system
+    //
+    HWND                            hWnd;
     SWP                             vSwp;
     POINTL                          vPoint;
     wxWindow*                       pParent = GetParent();
@@ -1309,17 +1308,30 @@ void wxWindowOS2::DoGetPosition(
     // the WIN32 WinGetRect, but unlike WinGetRect which returns the window
     // origin position in screen coordinates, WinQueryWindowRect returns it
     // relative to itself, i.e. (0,0).  To get the same under PM we must
-    // us WinQueryWindowPos.  This call, unlike the WIN32 call, however,
+    // use WinQueryWindowPos.  This call, unlike the WIN32 call, however,
     // returns a position relative to it's parent, so no parent adujstments
     // are needed under OS/2.  Also, windows should be created using
-    // wxWindow coordinates, i.e 0,0 is the TOP left so vSwp will already
-    // reflect that.
+    // wxWindow coordinates, i.e 0,0 is the TOP left.
     //
+    if (IsKindOf(CLASSINFO(wxFrame)))
+    {
+        wxFrame*                    pFrame = wxDynamicCast(this, wxFrame);
+        hWnd = pFrame->GetFrame();
+    }
+    else
+        hWnd = GetHwnd();
+
     ::WinQueryWindowPos(hWnd, &vSwp);
 
     vPoint.x = vSwp.x;
     vPoint.y = vSwp.y;
 
+    // We need to convert to wxWidgets coordinates
+    int vHeight;
+    DoGetSize(NULL,&vHeight);
+    wxWindow* pWindow = wxDynamicCast(this,wxWindow);
+    vPoint.y = pWindow->GetOS2ParentHeight(pParent) - vPoint.y - vHeight;
+
     //
     // We may be faking the client origin. So a window that's really at (0,
     // 30) may appear (to wxWin apps) to be at (0, 0).
@@ -1451,18 +1463,12 @@ void wxWindowOS2::DoMoveWindow(
 , int                               nHeight
 )
 {
+    //
+    // Input parameters assume wxWidgets coordinate system
+    //
     RECTL                           vRect;
     wxWindow*                       pParent = GetParent();
-
-    /* Due to OS/2's inverted coordinate system, changing the height
-       of a window requires repositioning all it's children, e.g. if
-       you want a child of height 100 to be at the top left corner of
-       the parent you need to position the lower left corner of the
-       child at (0, (height of parent - 100)), so, obviously, if the
-       height of the parent changes, the child needs to be repositioned. */
-    int                         nHeightDelta;
-    GetSize(0, &nHeightDelta);
-    nHeightDelta = nHeight - nHeightDelta;
+    HWND                            hWnd = GetHwnd();
 
     if (pParent && !IsKindOf(CLASSINFO(wxDialog)))
     {
@@ -1492,64 +1498,26 @@ void wxWindowOS2::DoMoveWindow(
     if (IsKindOf(CLASSINFO(wxFrame)))
     {
         RECTL                       vFRect;
-        HWND                        hWndFrame;
         int                         nWidthFrameDelta = 0;
         int                         nHeightFrameDelta = 0;
-        int                         nHeightFrame = 0;
-        int                         nWidthFrame = 0;
         wxFrame*                    pFrame;
 
         pFrame = wxDynamicCast(this, wxFrame);
-        hWndFrame = pFrame->GetFrame();
-        ::WinQueryWindowRect(hWndFrame, &vRect);
-        ::WinMapWindowPoints(hWndFrame, HWND_DESKTOP, (PPOINTL)&vRect, 2);
+        hWnd = pFrame->GetFrame();
+        ::WinQueryWindowRect(hWnd, &vRect);
+        ::WinMapWindowPoints(hWnd, HWND_DESKTOP, (PPOINTL)&vRect, 2);
         vFRect = vRect;
-        ::WinCalcFrameRect(hWndFrame, &vRect, TRUE);
+        ::WinCalcFrameRect(hWnd, &vRect, TRUE);
         nWidthFrameDelta = ((vRect.xLeft - vFRect.xLeft) + (vFRect.xRight - vRect.xRight));
         nHeightFrameDelta = ((vRect.yBottom - vFRect.yBottom) + (vFRect.yTop - vRect.yTop));
-        nWidthFrame = vFRect.xRight - vFRect.xLeft;
-        nHeightFrame = vFRect.yTop - vFRect.yBottom;
-
-        if (nWidth == vFRect.xRight - vFRect.xLeft &&
-            nHeight == vFRect.yTop - vFRect.yBottom)
-        {
-            //
-            // In this case the caller is not aware of OS/2's need to size both
-            // the frame and it's client and is really only moving the window,
-            // not resizeing it.  So move the frame, and back off the sizes
-            // for a proper client fit.
-            //
-            ::WinSetWindowPos( hWndFrame
-                              ,HWND_TOP
-                              ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
-                              ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
-                              ,(LONG)0
-                              ,(LONG)0
-                              ,SWP_MOVE
-                             );
-            nX += (vRect.xLeft - vFRect.xLeft);
-            nY += (vRect.yBottom - vFRect.yBottom);
-            nWidth -= nWidthFrameDelta;
-            nHeight -= nHeightFrameDelta;
-        }
-        else
-        {
-            if (nWidth > nWidthFrame - nHeightFrameDelta ||
-                nHeight > nHeightFrame - nHeightFrameDelta)
-            {
-                ::WinSetWindowPos( hWndFrame
-                                  ,HWND_TOP
-                                  ,(LONG)nX - (vRect.xLeft - vFRect.xLeft)
-                                  ,(LONG)nY - (vRect.yBottom - vFRect.yBottom)
-                                  ,(LONG)nWidth + nWidthFrameDelta
-                                  ,(LONG)nHeight + nHeightFrameDelta
-                                  ,SWP_MOVE | SWP_SIZE
-                                 );
-            }
-        }
+        // Input values refer to the window position relative to its parent
+        // which may be the Desktop so we need to calculate
+        // the new frame values to keep the wxWidgets frame origin constant
+        nY -= nHeightFrameDelta;
+        nWidth += nWidthFrameDelta;
+        nHeight += nHeightFrameDelta;
     }
-
-    ::WinSetWindowPos( GetHwnd()
+    ::WinSetWindowPos( hWnd
                       ,HWND_TOP
                       ,(LONG)nX
                       ,(LONG)nY
@@ -1564,8 +1532,6 @@ void wxWindowOS2::DoMoveWindow(
         ::WinQueryWindowPos(hWnd, &m_vWinSwp);
     else
     {
-        int                         nYDiff = m_vWinSwp.cy - nHeight;
-
         //
         // Handle resizing of scrolled windows.  The target or window to
         // be scrolled is the owner (gets the scroll notifications).  The
@@ -1587,7 +1553,7 @@ void wxWindowOS2::DoMoveWindow(
             int nHSBHeight = wxSystemSettingsNative::GetMetric(wxSYS_HSCROLL_Y,
                                                                this);
             int nVSBWidth  = wxSystemSettingsNative::GetMetric(wxSYS_VSCROLL_X,
-                                                              this);
+                                                               this);
             SWP                     vSwpScroll;
 
             if (GetScrollBarHorz() == NULLHANDLE ||
@@ -1609,19 +1575,9 @@ void wxWindowOS2::DoMoveWindow(
                               ,vSwpScroll.cy - nAdjustHeight
                               ,SWP_MOVE | SWP_SIZE
                              );
-            nYDiff -= nAdjustHeight;
         }
-        MoveChildren(nYDiff);
-        ::WinQueryWindowPos(GetHwnd(), &m_vWinSwp);
+        ::WinQueryWindowPos(hWnd, &m_vWinSwp);
     }
-#if 0
-    // FIXME: By my logic, the next line should be needed as it moves child
-    //        windows when resizing the parent (see comment at beginning of
-    //        function). However, this seems to cause lots of problems. At
-    //        least, e.g. the grid sample almost works with this line
-    //        commented out but crashes badly with it.
-    MoveChildren(nHeightDelta);
-#endif
 } // end of wxWindowOS2::DoMoveWindow
 
 //
@@ -1640,6 +1596,10 @@ void wxWindowOS2::DoSetSize( int nX,
                              int nHeight,
                              int nSizeFlags )
 {
+    //
+    // Input & output parameters assume wxWidgets coordinate system
+    //
+
     //
     // Get the current size and position...
     //
@@ -1655,12 +1615,7 @@ void wxWindowOS2::DoSetSize( int nX,
     //
     // ... and don't do anything (avoiding flicker) if it's already ok
     //
-    //
-    // Must convert Y coords to test for equality under OS/2
-    //
-    int                             nY2 = nY;
-
-    if (nX == nCurrentX && nY2 == nCurrentY &&
+    if (nX == nCurrentX && nY == nCurrentY &&
         nWidth == nCurrentWidth && nHeight == nCurrentHeight)
     {
         return;
@@ -1712,50 +1667,15 @@ void wxWindowOS2::DoSetSize( int nX,
 void wxWindowOS2::DoSetClientSize( int nWidth,
                                    int nHeight )
 {
-    POINTL    vPoint;
-    int       nActualWidth;
-    int       nActualHeight;
-    wxWindow* pParent = (wxWindow*)GetParent();
-    HWND      hParentWnd = (HWND)0;
-
-    if (pParent)
-        hParentWnd = (HWND)pParent->GetHWND();
-
-    if (IsKindOf(CLASSINFO(wxFrame)))
-    {
-        wxFrame* pFrame = wxDynamicCast(this, wxFrame);
-        HWND     hFrame = pFrame->GetFrame();
-        RECTL    vRect;
-        RECTL    vRect2;
-        RECTL    vRect3;
-
-        ::WinQueryWindowRect(GetHwnd(), &vRect2);
-        ::WinQueryWindowRect(hFrame, &vRect);
-        ::WinQueryWindowRect(hParentWnd, &vRect3);
-        nActualWidth = vRect2.xRight - vRect2.xLeft - vRect.xRight + nWidth;
-        nActualHeight = vRect2.yTop - vRect2.yBottom - vRect.yTop + nHeight;
-
-        vPoint.x = vRect2.xLeft;
-        vPoint.y = vRect2.yBottom;
-        if (pParent)
-        {
-            vPoint.x -= vRect3.xLeft;
-            vPoint.y -= vRect3.yBottom;
-        }
-    }
-    else
-    {
-        int nX;
-        int nY;
+    //
+    // nX & nY assume wxWidgets coordinate system
+    //
+    int nX;
+    int nY;
 
-        GetPosition(&nX, &nY);
-        nActualWidth  = nWidth;
-        nActualHeight = nHeight;
+    GetPosition(&nX, &nY);
 
-        vPoint.x = nX;
-        vPoint.y = nY;
-    }
-    DoMoveWindow( vPoint.x, vPoint.y, nActualWidth, nActualHeight );
+    DoMoveWindow( nX, nY, nWidth, nHeight );
 
     wxSize size( nWidth, nHeight );
     wxSizeEvent vEvent( size, m_windowId );
@@ -2101,9 +2021,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())
                             {
@@ -2472,9 +2396,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);
 
@@ -2720,6 +2641,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));
@@ -2776,11 +2698,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);
@@ -2984,16 +2914,16 @@ void wxAssociateWinWithHandle(
     wxCHECK_RET( hWnd != (HWND)NULL,
                  wxT("attempt to add a NULL hWnd to window list ignored") );
 
-
     wxWindow*                       pOldWin = wxFindWinFromHandle((WXHWND) hWnd);
 
     if (pOldWin && (pOldWin != pWin))
     {
-        wxString                    str(pWin->GetClassInfo()->GetClassName());
-
-        wxLogError( _T("Bug! Found existing HWND %X for new window of class %s")
-                   ,(int)hWnd
-                   ,str.c_str()
+        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"),
+                    Newstr.c_str(),
+                    (int)hWnd,
+                    Oldstr.c_str()
                   );
     }
     else if (!pOldWin)
@@ -3144,7 +3074,7 @@ bool wxWindowOS2::OS2Create( PSZ            zClass,
             ,nHeight
            );
     return true;
-} // end of WinGuiBase_Window::OS2Create
+} // end of wxWindowOS2::OS2Create
 
 // ===========================================================================
 // OS2 PM message handlers
@@ -3372,7 +3302,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(_T("Unable to set current color table (1). Error: %s\n"), sError.c_str());
         }
         //
         // Set the color table to RGB mode
@@ -3387,7 +3317,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(_T("Unable to set current color table (2). Error: %s\n"), sError.c_str());
         }
 
         wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
@@ -3647,15 +3577,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;
@@ -3685,14 +3610,13 @@ 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);
@@ -3814,7 +3738,6 @@ bool wxWindowOS2::HandleEraseBkgnd( WXHDC hDC )
 
     vDC.m_hPS = (HPS)hDC; // this is really a PS
     vDC.SetWindow((wxWindow*)this);
-    vDC.BeginDrawing();
 
     wxEraseEvent vEvent(m_windowId, &vDC);
 
@@ -3822,7 +3745,6 @@ bool wxWindowOS2::HandleEraseBkgnd( WXHDC hDC )
 
     rc = GetEventHandler()->ProcessEvent(vEvent);
 
-    vDC.EndDrawing();
     vDC.m_hPS = NULLHANDLE;
     return true;
 } // end of wxWindowOS2::HandleEraseBkgnd
@@ -3968,12 +3890,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());
@@ -4301,88 +4220,9 @@ bool wxWindowOS2::OS2OnScroll( int nOrientation,
     return GetEventHandler()->ProcessEvent(vEvent);
 } // end of wxWindowOS2::OS2OnScroll
 
-void wxWindowOS2::MoveChildren(
-  int                               nDiff
-)
-{
-    //
-    // We want to handle top levels ourself, manually
-    //
-    if (!IsTopLevel() && GetAutoLayout())
-    {
-        Layout();
-    }
-    else
-    {
-        SWP                         vSwp;
-
-        for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst();
-             node;
-             node = node->GetNext())
-        {
-            wxWindow*               pWin = node->GetData();
-
-            ::WinQueryWindowPos( GetHwndOf(pWin)
-                                ,&vSwp
-                               );
-            // Actually, only move children that already are placed on the
-            // frame, not ones which are still at wxDefaultCoord.
-            if (vSwp.y == wxDefaultCoord)
-                continue;
-            if (pWin->IsKindOf(CLASSINFO(wxControl)))
-            {
-                wxControl*          pCtrl;
-
-                //
-                // Must deal with controls that have margins like ENTRYFIELD.  The SWP
-                // struct of such a control will have and origin offset from its intended
-                // position by the width of the margins.
-                //
-                pCtrl = wxDynamicCast(pWin, wxControl);
-                vSwp.y -= pCtrl->GetYComp();
-                vSwp.x -= pCtrl->GetXComp();
-            }
-            ::WinSetWindowPos( GetHwndOf(pWin)
-                              ,HWND_TOP
-                              ,vSwp.x
-                              ,vSwp.y - nDiff
-                              ,vSwp.cx
-                              ,vSwp.cy
-                              ,SWP_MOVE
-                             );
-            ::WinQueryWindowPos(GetHwndOf(pWin), pWin->GetSwp());
-            if (pWin->IsKindOf(CLASSINFO(wxRadioBox)))
-            {
-                wxRadioBox*     pRadioBox;
-
-                pRadioBox = wxDynamicCast(pWin, wxRadioBox);
-                pRadioBox->AdjustButtons( (int)vSwp.x
-                                         ,(int)vSwp.y - nDiff
-                                         ,(int)vSwp.cx
-                                         ,(int)vSwp.cy
-                                         ,pRadioBox->GetSizeFlags()
-                                        );
-            }
-            if (pWin->IsKindOf(CLASSINFO(wxSlider)))
-            {
-                wxSlider*           pSlider;
-
-                pSlider = wxDynamicCast(pWin, wxSlider);
-                pSlider->AdjustSubControls( (int)vSwp.x
-                                           ,(int)vSwp.y - nDiff
-                                           ,(int)vSwp.cx
-                                           ,(int)vSwp.cy
-                                           ,(int)pSlider->GetSizeFlags()
-                                          );
-            }
-        }
-    }
-    Refresh();
-} // end of wxWindowOS2::MoveChildren
-
 //
 //  Getting the Y position for a window, like a control, is a real
-//  pain.  There are three sitatuions we must deal with in determining
+//  pain.  There are three situations we must deal with in determining
 //  the OS2 to wxWidgets Y coordinate.
 //
 //  1)  The controls are created in a dialog.
@@ -4413,11 +4253,13 @@ void wxWindowOS2::MoveChildren(
 //
 int wxWindowOS2::GetOS2ParentHeight( wxWindowOS2* pParent )
 {
+    if (pParent)
+    {
     //
     // Case 1
     //
-    if (pParent->IsKindOf(CLASSINFO(wxDialog)))
-        return(pParent->GetClientSize().y);
+        if (pParent->IsKindOf(CLASSINFO(wxDialog)))
+            return(pParent->GetClientSize().y);
 
     //
     // Case 2 -- if we are one of the separately built standard Frame
@@ -4425,40 +4267,43 @@ int wxWindowOS2::GetOS2ParentHeight( wxWindowOS2* pParent )
     //           use the frame, itself, for positioning.  Otherwise we are
     //           child window and want to use the Frame's client.
     //
-    else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
-    {
-        if (IsKindOf(CLASSINFO(wxStatusBar)) ||
-            IsKindOf(CLASSINFO(wxMenuBar))   ||
-            IsKindOf(CLASSINFO(wxToolBar))
-           )
+        else if (pParent->IsKindOf(CLASSINFO(wxFrame)))
         {
-            if (IsKindOf(CLASSINFO(wxToolBar)))
+            if (IsKindOf(CLASSINFO(wxStatusBar)) ||
+                IsKindOf(CLASSINFO(wxMenuBar))   ||
+                IsKindOf(CLASSINFO(wxToolBar))
+               )
             {
-                wxFrame*            pFrame = wxDynamicCast(GetParent(), wxFrame);
+                if (IsKindOf(CLASSINFO(wxToolBar)))
+                {
+                    wxFrame*        pFrame = wxDynamicCast(GetParent(), wxFrame);
 
-                if (pFrame->GetToolBar() == this)
-                    return(pParent->GetSize().y);
+                    if (pFrame->GetToolBar() == this)
+                        return(pParent->GetSize().y);
+                    else
+                        return(pParent->GetClientSize().y);
+                }
                 else
-                    return(pParent->GetClientSize().y);
+                    return(pParent->GetSize().y);
             }
             else
-                return(pParent->GetSize().y);
+                return(pParent->GetClientSize().y);
         }
+        //
+        // Case -- this is for any window that is the sole child of a Frame.
+        //         The grandparent must exist and it must be of type CFrame
+        //         and it's height must be different. Otherwise the standard
+        //         applies.
+        //
         else
             return(pParent->GetClientSize().y);
     }
-    //
-    // Case -- this is for any window that is the sole child of a Frame.
-    //         The grandparent must exist and it must be of type CFrame
-    //         and it's height must be different. Otherwise the standard
-    //         applies.
-    //
-    // else
-    // {
-
-    return(pParent->GetClientSize().y);
-
-    // }
+    else // We must be a child of the screen
+    {
+        int nHeight;
+        wxDisplaySize(NULL,&nHeight);
+        return(nHeight);
+    }
 } // end of wxWindowOS2::GetOS2ParentHeight
 
 //
@@ -4532,8 +4377,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;
@@ -4595,15 +4440,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;
@@ -4641,7 +4487,8 @@ int wxCharCodeWXToOS2( int nId,
         case WXK_SCROLL:    nKeySym = VK_SCRLLOCK; break;
         default:
         {
-            *bIsVirtual = false;
+            if ( bIsVirtual )
+                *bIsVirtual = false;
             nKeySym = nId;
             break;
         }
@@ -4649,6 +4496,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);
@@ -5188,12 +5058,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) )