]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/radiobox.cpp
add a simple benchmark for wx and iconv converters benchmarking
[wxWidgets.git] / src / msw / radiobox.cpp
index 9f0c6b131eb9638071897203c9c2541c46e4b3dc..26519adcbb6999bb9f0a7ac4c707d70cc5a37467 100644 (file)
 
 #if wxUSE_RADIOBOX
 
+#include "wx/radiobox.h"
+
 #ifndef WX_PRECOMP
     #include "wx/bitmap.h"
     #include "wx/brush.h"
-    #include "wx/radiobox.h"
     #include "wx/settings.h"
     #include "wx/log.h"
 #endif
@@ -128,6 +129,7 @@ void wxRadioBox::Init()
 {
     m_selectedButton = wxNOT_FOUND;
     m_radioButtons = NULL;
+    m_dummyHwnd = NULL;
     m_radioWidth = NULL;
     m_radioHeight = NULL;
 }
@@ -148,13 +150,26 @@ bool wxRadioBox::Create(wxWindow *parent,
     if ( !wxStaticBox::Create(parent, id, title, pos, size, style, name) )
         return false;
 
+    // the code elsewhere in this file supposes that either wxRA_SPECIFY_COLS
+    // or wxRA_SPECIFY_ROWS is set, ensure that this is indeed the case
+    if ( !(style & (wxRA_SPECIFY_ROWS | wxRA_SPECIFY_COLS)) )
+        style |= wxRA_SPECIFY_COLS;
+
 #if wxUSE_VALIDATORS
     SetValidator(val);
 #else
     wxUnusedVar(val);
 #endif // wxUSE_VALIDATORS/!wxUSE_VALIDATORS
 
+    // We need an extra one to keep track of the 'dummy' item we
+    // create to end the radio group, so it will be destroyed and
+    // it's id will be released.  But we want it separate from the
+    // other buttons since the wxSubwindows will operate on it as
+    // well and we just want to ignore it until destroying it.
+    // For instance, we don't want the bounding box of the radio
+    // buttons to include the dummy button
     m_radioButtons = new wxSubwindows(n);
+
     m_radioWidth = new int[n];
     m_radioHeight = new int[n];
 
@@ -166,14 +181,14 @@ bool wxRadioBox::Create(wxWindow *parent,
         if ( i == 0 )
             styleBtn |= WS_GROUP;
 
-        long newId = NewControlId();
+        wxWindowIDRef subid = NewControlId();
 
         HWND hwndBtn = ::CreateWindow(_T("BUTTON"),
-                                      choices[i],
+                                      choices[i].wx_str(),
                                       styleBtn,
                                       0, 0, 0, 0,   // will be set in SetSize()
                                       GetHwndOf(parent),
-                                      (HMENU)newId,
+                                      (HMENU)wxUIntToPtr(subid.GetValue()),
                                       wxGetInstance(),
                                       NULL);
 
@@ -184,19 +199,25 @@ bool wxRadioBox::Create(wxWindow *parent,
             return false;
         }
 
-        (*m_radioButtons)[i] = hwndBtn;
+        // Keep track of the subwindow
+        m_radioButtons->Set(i, hwndBtn, subid);
 
         SubclassRadioButton((WXHWND)hwndBtn);
 
-        m_subControls.Add(newId);
+        // Also, make it a subcontrol of this control
+        m_subControls.Add(subid);
     }
 
     // Create a dummy radio control to end the group.
-    (void)::CreateWindow(_T("BUTTON"),
+    m_dummyId = NewControlId();
+
+    m_dummyHwnd = (WXHWND)::CreateWindow(_T("BUTTON"),
                          wxEmptyString,
                          WS_GROUP | BS_AUTORADIOBUTTON | WS_CHILD,
                          0, 0, 0, 0, GetHwndOf(parent),
-                         (HMENU)NewControlId(), wxGetInstance(), NULL);
+                         (HMENU)wxUIntToPtr(m_dummyId.GetValue()),
+                         wxGetInstance(), NULL);
+
 
     m_radioButtons->SetFont(GetFont());
 
@@ -210,7 +231,7 @@ bool wxRadioBox::Create(wxWindow *parent,
     SetSize(pos.x, pos.y, size.x, size.y);
 
     // Now that we have items determine what is the best size and set it.
-    SetBestSize(size);
+    SetInitialSize(size);
 
     return true;
 }
@@ -236,6 +257,8 @@ wxRadioBox::~wxRadioBox()
     m_isBeingDeleted = true;
 
     delete m_radioButtons;
+    if ( m_dummyHwnd )
+        DestroyWindow((HWND)m_dummyHwnd);
     delete[] m_radioWidth;
     delete[] m_radioHeight;
 }
@@ -257,8 +280,10 @@ void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn)
 // events generation
 // ----------------------------------------------------------------------------
 
-bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id)
+bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id_)
 {
+    const int id = (signed short)id_;
+
     if ( cmd == BN_CLICKED )
     {
         if (id == GetId())
@@ -269,9 +294,14 @@ bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id)
         const unsigned int count = GetCount();
         for ( unsigned int i = 0; i < count; i++ )
         {
-            if ( id == wxGetWindowId((*m_radioButtons)[i]) )
+            const HWND hwndBtn = (*m_radioButtons)[i];
+            if ( id == wxGetWindowId(hwndBtn) )
             {
-                selectedButton = i;
+                // we can get BN_CLICKED for a button which just became focused
+                // but it may not be checked, in which case we shouldn't
+                // generate a radiobox selection changed event for it
+                if ( ::SendMessage(hwndBtn, BM_GETCHECK, 0, 0) == BST_CHECKED )
+                    selectedButton = i;
 
                 break;
             }
@@ -322,7 +352,7 @@ void wxRadioBox::SendNotificationEvent()
 
 unsigned int wxRadioBox::GetCount() const
 {
-    return m_radioButtons->GetCount();
+    return m_radioButtons ? m_radioButtons->GetCount() : 0u;
 }
 
 void wxRadioBox::SetString(unsigned int item, const wxString& label)
@@ -437,6 +467,25 @@ void wxRadioBox::DoSetItemToolTip(unsigned int item, wxToolTip *tooltip)
 
 #endif // wxUSE_TOOLTIPS
 
+bool wxRadioBox::Reparent(wxWindowBase *newParent)
+{
+    if ( !wxStaticBox::Reparent(newParent) )
+    {
+        return false;
+    }
+
+    HWND hwndParent = GetHwndOf(GetParent());
+    for ( size_t item = 0; item < m_radioButtons->GetCount(); item++ )
+    {
+        ::SetParent((*m_radioButtons)[item], hwndParent);
+    }
+#ifdef __WXWINCE__
+    // put static box under the buttons in the Z-order
+    SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE);
+#endif
+    return true;
+}
+
 WX_FORWARD_STD_METHODS_TO_SUBWINDOWS(wxRadioBox, wxStaticBox, m_radioButtons)
 
 // ----------------------------------------------------------------------------
@@ -494,7 +543,7 @@ wxSize wxRadioBox::GetTotalButtonSize(const wxSize& sizeBtn) const
 
     // and also wide enough for its label
     int widthLabel;
-    GetTextExtent(wxStripMenuCodes(GetLabel()), &widthLabel, NULL);
+    GetTextExtent(GetLabelText(), &widthLabel, NULL);
     widthLabel += RADIO_SIZE; // FIXME this is bogus too
     if ( widthLabel > width )
         width = widthLabel;
@@ -504,6 +553,13 @@ wxSize wxRadioBox::GetTotalButtonSize(const wxSize& sizeBtn) const
 
 wxSize wxRadioBox::DoGetBestSize() const
 {
+    if ( !m_radioButtons )
+    {
+        // if we're not fully initialized yet, we can't meaningfully compute
+        // our best size, we'll do it later
+        return wxSize(1, 1);
+    }
+
     wxSize best = GetTotalButtonSize(GetMaxButtonSize());
     CacheBestSize(best);
     return best;
@@ -655,6 +711,23 @@ void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
     }
 }
 
+int wxRadioBox::GetItemFromPoint(const wxPoint& pt) const
+{
+    const unsigned int count = GetCount();
+    for ( unsigned int i = 0; i < count; i++ )
+    {
+        RECT rect = wxGetWindowRect((*m_radioButtons)[i]);
+
+        if ( rect.left <= pt.x && pt.x < rect.right &&
+                rect.top  <= pt.y && pt.y < rect.bottom )
+        {
+            return i;
+        }
+    }
+
+    return wxNOT_FOUND;
+}
+
 // ----------------------------------------------------------------------------
 // radio box drawing
 // ----------------------------------------------------------------------------
@@ -706,32 +779,6 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
                 return lDlgCode | DLGC_WANTARROWS;
             }
 
-#if wxUSE_TOOLTIPS
-        case WM_NOTIFY:
-            {
-                NMHDR* hdr = (NMHDR *)lParam;
-                if ( hdr->code == TTN_NEEDTEXT )
-                {
-                    wxRadioBox *
-                        radiobox = (wxRadioBox *)wxGetWindowUserData(hwnd);
-
-                    wxCHECK_MSG( radiobox, 0,
-                                 wxT("radio button without radio box?") );
-
-                    wxToolTip *tooltip = radiobox->GetToolTip();
-                    if ( tooltip )
-                    {
-                        TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
-                        ttt->lpszText = (wxChar *)tooltip->GetTip().c_str();
-                    }
-
-                    // processed
-                    return 0;
-                }
-            }
-            break;
-#endif // wxUSE_TOOLTIPS
-
         case WM_KEYDOWN:
             {
                 wxRadioBox *radiobox = (wxRadioBox *)wxGetWindowUserData(hwnd);