X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/c670c85582ca995105f14a6c62b54c580582f624..fe5451982ec9e67a4b5b54d7f81d0bd09baefd56:/src/msw/radiobox.cpp diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 9f0c6b131e..9108095f93 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -26,10 +26,11 @@ #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; } @@ -154,7 +156,15 @@ bool wxRadioBox::Create(wxWindow *parent, 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 +176,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 +194,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 +226,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 +252,8 @@ wxRadioBox::~wxRadioBox() m_isBeingDeleted = true; delete m_radioButtons; + if ( m_dummyHwnd ) + DestroyWindow((HWND)m_dummyHwnd); delete[] m_radioWidth; delete[] m_radioHeight; } @@ -257,8 +275,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 +289,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 +347,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 +462,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 +538,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 +548,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 +706,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 +774,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);