X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50c8b82054d96a9cc846d09ed98eecad07907be0..3cfde7c049bddf6fd3b4c2e35a6b8ecdcdc1d74f:/src/msw/radiobox.cpp?ds=sidebyside diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index af016c9a15..cdf5141085 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -129,6 +129,7 @@ void wxRadioBox::Init() { m_selectedButton = wxNOT_FOUND; m_radioButtons = NULL; + m_dummyHwnd = NULL; m_radioWidth = NULL; m_radioHeight = NULL; } @@ -149,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]; @@ -167,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); @@ -185,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()); @@ -206,10 +226,6 @@ bool wxRadioBox::Create(wxWindow *parent, SetWindowPos(GetHwnd(), HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); #endif - // Have to invalidate the best size as it may have been calculated - // before the number of buttons was known - InvalidateBestSize(); - SetMajorDim(majorDim == 0 ? n : majorDim, style); SetSelection(0); SetSize(pos.x, pos.y, size.x, size.y); @@ -238,9 +254,11 @@ bool wxRadioBox::Create(wxWindow *parent, wxRadioBox::~wxRadioBox() { - m_isBeingDeleted = true; + SendDestroyEvent(); delete m_radioButtons; + if ( m_dummyHwnd ) + DestroyWindow((HWND)m_dummyHwnd); delete[] m_radioWidth; delete[] m_radioHeight; } @@ -262,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()) @@ -274,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; } @@ -442,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) // ---------------------------------------------------------------------------- @@ -509,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;