]> git.saurik.com Git - wxWidgets.git/blobdiff - src/os2/radiobut.cpp
move code ignoring VK_SPACE and VK_RETURN WM_CHAR messages to MSWDefWindowProc()...
[wxWidgets.git] / src / os2 / radiobut.cpp
index d4cc561bab90567044f0607d78fc7a8a307ec271..e0eaed2b65785f6dd8b8ee460c050b0574dcd9de 100644 (file)
 
 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
 
 
 IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl)
 
+extern void  wxAssociateWinWithHandle( HWND         hWnd
+                                      ,wxWindowOS2* pWin
+                                     );
+
 void wxRadioButton::Init()
 {
     m_bFocusJustSet = FALSE;
 void wxRadioButton::Init()
 {
     m_bFocusJustSet = FALSE;
@@ -49,9 +53,7 @@ bool wxRadioButton::Create(
 , const wxPoint&                    rPos
 , const wxSize&                     rSize
 , long                              lStyle
 , const wxPoint&                    rPos
 , const wxSize&                     rSize
 , long                              lStyle
-#if wxUSE_VALIDATORS
 , const wxValidator&                rValidator
 , const wxValidator&                rValidator
-#endif
 , const wxString&                   rsName
 )
 {
 , const wxString&                   rsName
 )
 {
@@ -60,15 +62,27 @@ bool wxRadioButton::Create(
                         ,rPos
                         ,rSize
                         ,lStyle
                         ,rPos
                         ,rSize
                         ,lStyle
-#if wxUSE_VALIDATORS
                         ,rValidator
                         ,rValidator
-#endif
                         ,rsName))
         return FALSE;
 
                         ,rsName))
         return FALSE;
 
-    long                            lSstyle = HasFlag(wxRB_GROUP) ? WS_GROUP : 0;
+    long                            lSstyle = WS_TABSTOP;
 
 
-    lSstyle |= BS_AUTORADIOBUTTON;
+    if (HasFlag(wxRB_GROUP))
+        lSstyle |= WS_GROUP;
+
+    //
+    // wxRB_SINGLE is a temporary workaround for the following problem: if you
+    // have 2 radiobuttons in the same group but which are not consecutive in
+    // the dialog, Windows can enter an infinite loop! The simplest way to
+    // reproduce it is to create radio button, then a panel and then another
+    // radio button: then checking the last button hangs the app.
+    //
+    // Ideally, we'd detect (and avoid) such situation automatically but for
+    // now, as I don't know how to do it, just allow the user to create
+    // BS_RADIOBUTTON buttons for such situations.
+    //
+    lSstyle |= HasFlag(wxRB_SINGLE) ? BS_RADIOBUTTON : BS_AUTORADIOBUTTON;
 
     if (HasFlag(wxCLIP_SIBLINGS))
         lSstyle |= WS_CLIPSIBLINGS;
 
     if (HasFlag(wxCLIP_SIBLINGS))
         lSstyle |= WS_CLIPSIBLINGS;
@@ -82,21 +96,16 @@ bool wxRadioButton::Create(
                          ))
         return FALSE;
 
                          ))
         return FALSE;
 
+    wxAssociateWinWithHandle(m_hWnd, this);
     if (HasFlag(wxRB_GROUP))
         SetValue(TRUE);
 
     if (HasFlag(wxRB_GROUP))
         SetValue(TRUE);
 
-    wxFont*                          pTextFont = new wxFont( 10
-                                                            ,wxMODERN
-                                                            ,wxNORMAL
-                                                            ,wxNORMAL
-                                                           );
-    SetFont(*pTextFont);
+    SetFont(*wxSMALL_FONT);
     SetSize( rPos.x
             ,rPos.y
             ,rSize.x
             ,rSize.y
            );
     SetSize( rPos.x
             ,rPos.y
             ,rSize.x
             ,rSize.y
            );
-    delete pTextFont;
     return TRUE;
 } // end of wxRadioButton::Create
 
     return TRUE;
 } // end of wxRadioButton::Create
 
@@ -149,18 +158,38 @@ bool wxRadioButton::OS2Command(
 , WXWORD                            wId
 )
 {
 , WXWORD                            wId
 )
 {
-    if (wParam == BN_CLICKED)
+    if (wParam != BN_CLICKED)
+        return FALSE;
+
+    if (m_bFocusJustSet)
+    {
+        //
+        // See above: we want to ignore this event
+        //
+        m_bFocusJustSet = FALSE;
+    }
+    else
     {
     {
+        bool                        bIsChecked = GetValue();
+
+        if (HasFlag(wxRB_SINGLE))
+        {
+            //
+            // When we use a "manual" radio button, we have to check the button
+            // ourselves -- but it's reset to unchecked state by the user code
+            // (presumably when another button is pressed)
+            //
+            if (!bIsChecked )
+                SetValue(TRUE);
+        }
         wxCommandEvent              rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
                                            ,m_windowId
                                           );
 
         rEvent.SetEventObject(this);
         ProcessCommand(rEvent);
         wxCommandEvent              rEvent( wxEVT_COMMAND_RADIOBUTTON_SELECTED
                                            ,m_windowId
                                           );
 
         rEvent.SetEventObject(this);
         ProcessCommand(rEvent);
-        return TRUE;
     }
     }
-    else
-        return FALSE;
+    return TRUE;
 } // end of wxRadioButton::OS2Command
 
 void wxRadioButton::SetFocus()
 } // end of wxRadioButton::OS2Command
 
 void wxRadioButton::SetFocus()
@@ -191,6 +220,69 @@ void wxRadioButton::SetValue(
 )
 {
     ::WinSendMsg((HWND)GetHWND(), BM_SETCHECK, (MPARAM)bValue, (MPARAM)0);
 )
 {
     ::WinSendMsg((HWND)GetHWND(), BM_SETCHECK, (MPARAM)bValue, (MPARAM)0);
+    if (bValue)
+    {
+        const wxWindowList&         rSiblings = GetParent()->GetChildren();
+        wxWindowList::compatibility_iterator nodeThis = rSiblings.Find(this);
+
+        wxCHECK_RET(nodeThis, _T("radio button not a child of its parent?"));
+
+        //
+        // If it's not the first item of the group ...
+        //
+        if ( !HasFlag(wxRB_GROUP) )
+        {
+            //
+            // ...turn off all radio buttons before this one
+            //
+            for ( wxWindowList::compatibility_iterator nodeBefore = nodeThis->GetPrevious();
+                  nodeBefore;
+                  nodeBefore = nodeBefore->GetPrevious() )
+            {
+                wxRadioButton*      pBtn = wxDynamicCast( nodeBefore->GetData()
+                                                         ,wxRadioButton
+                                                        );
+                if (!pBtn)
+                {
+                    //
+                    // The radio buttons in a group must be consecutive, so there
+                    // are no more of them
+                    //
+                    break;
+                }
+                pBtn->SetValue(FALSE);
+                if (pBtn->HasFlag(wxRB_GROUP))
+                {
+                    //
+                    // Even if there are other radio buttons before this one,
+                    // they're not in the same group with us
+                    //
+                    break;
+                }
+            }
+        }
+
+        //
+        // ... and all after this one
+        //
+        for (wxWindowList::compatibility_iterator nodeAfter = nodeThis->GetNext();
+             nodeAfter;
+             nodeAfter = nodeAfter->GetNext())
+        {
+            wxRadioButton*          pBtn = wxDynamicCast( nodeAfter->GetData()
+                                                         ,wxRadioButton
+                                                        );
+
+            if (!pBtn || pBtn->HasFlag(wxRB_GROUP) )
+            {
+                //
+                // No more buttons or the first button of the next group
+                //
+                break;
+            }
+            pBtn->SetValue(FALSE);
+        }
+    }
 } // end of wxRadioButton::SetValue
 
 MRESULT wxRadioButton::OS2WindowProc(
 } // end of wxRadioButton::SetValue
 
 MRESULT wxRadioButton::OS2WindowProc(