X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0826c4d39a53f8691b9430207420e9d9e175a73f..b960795ea82b702f302e99e547416cb573865413:/src/msw/radiobox.cpp?ds=sidebyside diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 634d598476..70665bdf84 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -29,6 +29,7 @@ #include "wx/radiobox.h" #ifndef WX_PRECOMP + #include "wx/hashmap.h" #include "wx/bitmap.h" #include "wx/brush.h" #include "wx/settings.h" @@ -80,7 +81,7 @@ wxEND_FLAGS( wxRadioBoxStyle ) IMPLEMENT_DYNAMIC_CLASS_XTI(wxRadioBox, wxControl,"wx/radiobox.h") wxBEGIN_PROPERTIES_TABLE(wxRadioBox) - wxEVENT_PROPERTY( Select , wxEVT_COMMAND_RADIOBOX_SELECTED , wxCommandEvent ) + wxEVENT_PROPERTY( Select , wxEVT_RADIOBOX , wxCommandEvent ) wxPROPERTY_FLAGS( WindowStyle , wxRadioBoxStyle , long , SetWindowStyleFlag , GetWindowStyleFlag , , 0 /*flags*/ , wxT("Helpstring") , wxT("group")) // style wxEND_PROPERTIES_TABLE() @@ -110,13 +111,34 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hWnd, // global vars // --------------------------------------------------------------------------- +namespace +{ + // the pointer to standard radio button wnd proc -static WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL; +WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL; + +// Hash allowing to find wxRadioBox containing the given radio button by its +// HWND. This is used by (subclassed) radio button window proc to find the +// radio box it belongs to. +WX_DECLARE_HASH_MAP(HWND, wxRadioBox *, + wxPointerHash, wxPointerEqual, + RadioBoxFromButton); + +RadioBoxFromButton gs_boxFromButton; + +} // anonymous namespace // =========================================================================== // implementation // =========================================================================== +/* static */ +wxRadioBox* wxRadioBox::GetFromRadioButtonHWND(WXHWND hwnd) +{ + const RadioBoxFromButton::const_iterator it = gs_boxFromButton.find(hwnd); + return it == gs_boxFromButton.end() ? NULL : it->second; +} + // --------------------------------------------------------------------------- // wxRadioBox creation // --------------------------------------------------------------------------- @@ -181,7 +203,7 @@ bool wxRadioBox::Create(wxWindow *parent, wxWindowIDRef subid = NewControlId(); HWND hwndBtn = ::CreateWindow(wxT("BUTTON"), - choices[i].wx_str(), + choices[i].t_str(), styleBtn, 0, 0, 0, 0, // will be set in SetSize() GetHwndOf(parent), @@ -230,6 +252,10 @@ bool wxRadioBox::Create(wxWindow *parent, // Now that we have items determine what is the best size and set it. SetInitialSize(size); + // And update all the buttons positions to match it. + const wxSize actualSize = GetSize(); + PositionAllButtons(pos.x, pos.y, actualSize.x, actualSize.y); + return true; } @@ -253,9 +279,23 @@ wxRadioBox::~wxRadioBox() { SendDestroyEvent(); + // Unsubclass all the radio buttons and remove their soon-to-be-invalid + // HWNDs from the global map. Notice that we need to unsubclass because + // otherwise we'd need the entries in gs_boxFromButton for the buttons + // being deleted to handle the messages generated during their destruction. + for ( size_t item = 0; item < m_radioButtons->GetCount(); item++ ) + { + HWND hwnd = m_radioButtons->Get(item); + + wxSetWindowProc(hwnd, reinterpret_cast(s_wndprocRadioBtn)); + gs_boxFromButton.erase(hwnd); + } + delete m_radioButtons; + if ( m_dummyHwnd ) DestroyWindow((HWND)m_dummyHwnd); + delete[] m_radioWidth; delete[] m_radioHeight; } @@ -270,7 +310,8 @@ void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn) s_wndprocRadioBtn = (WXFARPROC)wxGetWindowProc(hwndBtn); wxSetWindowProc(hwndBtn, wxRadioBtnWndProc); - wxSetWindowUserData(hwndBtn, this); + + gs_boxFromButton[hwndBtn] = this; } // ---------------------------------------------------------------------------- @@ -336,7 +377,7 @@ void wxRadioBox::Command(wxCommandEvent & event) void wxRadioBox::SendNotificationEvent() { - wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId); + wxCommandEvent event(wxEVT_RADIOBOX, m_windowId); event.SetInt( m_selectedButton ); event.SetString(GetString(m_selectedButton)); event.SetEventObject( this ); @@ -457,7 +498,7 @@ void wxRadioBox::DoSetItemToolTip(unsigned int item, wxToolTip *tooltip) // we have already checked for the item to be valid in wxRadioBoxBase const HWND hwndRbtn = (*m_radioButtons)[item]; if ( tooltip != NULL ) - tooltip->Add(hwndRbtn); + tooltip->AddOtherWindow(hwndRbtn); else // unset the tooltip wxToolTip::Remove(hwndRbtn, 0, wxRect(0,0,0,0)); // the second parameter can be zero since it's ignored by Remove() @@ -588,6 +629,12 @@ void wxRadioBox::DoMoveWindow(int x, int y, int width, int height) { wxStaticBox::DoMoveWindow(x, y, width, height); + PositionAllButtons(x, y, width, height); +} + +void +wxRadioBox::PositionAllButtons(int x, int y, int width, int WXUNUSED(height)) +{ wxSize maxSize = GetMaxButtonSize(); int maxWidth = maxSize.x, maxHeight = maxSize.y; @@ -745,6 +792,10 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, WPARAM wParam, LPARAM lParam) { + + wxRadioBox * const radiobox = wxRadioBox::GetFromRadioButtonHWND(hwnd); + wxCHECK_MSG( radiobox, 0, wxT("Should have the associated radio box") ); + switch ( message ) { case WM_GETDLGCODE: @@ -760,10 +811,6 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, case WM_KEYDOWN: { - wxRadioBox *radiobox = (wxRadioBox *)wxGetWindowUserData(hwnd); - - wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") ); - bool processed = true; wxDirection dir; @@ -819,10 +866,6 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, case WM_SETFOCUS: case WM_KILLFOCUS: { - wxRadioBox *radiobox = (wxRadioBox *)wxGetWindowUserData(hwnd); - - wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") ); - // if we don't do this, no focus events are generated for the // radiobox and, besides, we need to notify the parent about // the focus change, otherwise the focus handling logic in @@ -837,10 +880,6 @@ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, #ifndef __WXWINCE__ case WM_HELP: { - wxRadioBox *radiobox = (wxRadioBox *)wxGetWindowUserData(hwnd); - - wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") ); - bool processed = false; wxEvtHandler * const handler = radiobox->GetEventHandler();