]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/window.cpp
Fix for crash when opening empty node
[wxWidgets.git] / src / os2 / window.cpp
index 6af67866bbbd54f8cfac9df1ba08f9b5b67f7b9d..44fdde685bfa3403f14fae76a6e9e40086809300 100644 (file)
@@ -46,6 +46,8 @@
     #include "wx/settings.h"
     #include "wx/intl.h"
     #include "wx/log.h"
+    #include "wx/textctrl.h"
+    #include "wx/menuitem.h"
     #include <stdio.h>
 #endif
 
@@ -57,8 +59,6 @@
     #include "wx/dnd.h"
 #endif
 
-#include "wx/menuitem.h"
-
 #include "wx/os2/private.h"
 
 #if wxUSE_TOOLTIPS
@@ -73,9 +73,6 @@
     #include "wx/caret.h"
 #endif // wxUSE_CARET
 
-
-#include "wx/textctrl.h"
-
 #include <string.h>
 
 //
@@ -157,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;
 
@@ -297,7 +295,6 @@ void wxWindowOS2::Init()
     m_bUseCtl3D             = false;
     m_bMouseInWindow        = false;
     m_bLastKeydownProcessed = false;
-    m_pChildrenDisabled     = NULL;
 
     //
     // wxWnd
@@ -359,7 +356,6 @@ wxWindowOS2::~wxWindowOS2()
         //
         wxRemoveHandleAssociation(this);
     }
-    delete m_pChildrenDisabled;
 } // end of wxWindowOS2::~wxWindowOS2
 
 // real construction (Init() must have been called before!)
@@ -481,70 +477,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 )
 {
@@ -574,7 +512,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
@@ -1735,7 +1673,6 @@ void wxWindowOS2::GetTextExtent( const wxString& rString,
     int         l;
     FONTMETRICS vFM; // metrics structure
     BOOL        bRc = FALSE;
-    char*       pStr;
     HPS         hPS;
 
     hPS = ::WinGetPS(GetHwnd());
@@ -1743,14 +1680,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
                                 );
@@ -2023,9 +1958,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())
                             {
@@ -2394,9 +2333,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);
 
@@ -2419,7 +2355,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
@@ -2642,6 +2578,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));
@@ -2698,11 +2635,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);
@@ -3023,8 +2968,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()
+                                       ,(zTitle ? zTitle : wxEmptyString)
                                        ,(ULONG)dwStyle
                                        ,(LONG)0L
                                        ,(LONG)0L
@@ -3569,15 +3514,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;
@@ -3607,14 +3547,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);
@@ -3888,12 +3827,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());
@@ -4441,7 +4377,8 @@ int wxCharCodeWXToOS2( int nId,
 {
     int nKeySym = 0;
 
-    *bIsVirtual = true;
+    if ( bIsVirtual )
+        *bIsVirtual = true;
     switch (nId)
     {
         case WXK_CLEAR:     nKeySym = VK_CLEAR; break;
@@ -4487,7 +4424,8 @@ int wxCharCodeWXToOS2( int nId,
         case WXK_SCROLL:    nKeySym = VK_SCRLLOCK; break;
         default:
         {
-            *bIsVirtual = false;
+            if ( bIsVirtual )
+                *bIsVirtual = false;
             nKeySym = nId;
             break;
         }
@@ -4501,9 +4439,20 @@ bool wxGetKeyState(wxKeyCode key)
     wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
         WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
 
-    // TODO
+    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;
 
-    return false;
+    }
+    else // normal key
+    {
+        return IsKeyDown(vk);
+    }
 }
 
 
@@ -5046,12 +4995,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) )