X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d1e418eaea09da4d74cc0d2b9d6bb1f9decbfa49..18d2e17080a0bea4b85e0ad7223cfc6bcdab0e1e:/src/msw/radiobox.cpp diff --git a/src/msw/radiobox.cpp b/src/msw/radiobox.cpp index 26868c3ec0..e54fa2c71c 100644 --- a/src/msw/radiobox.cpp +++ b/src/msw/radiobox.cpp @@ -38,24 +38,35 @@ #include "wx/msw/private.h" #if wxUSE_TOOLTIPS - -#ifndef __GNUWIN32__ - #include -#endif - + #ifndef __GNUWIN32_OLD__ + #include + #endif #include "wx/tooltip.h" #endif // wxUSE_TOOLTIPS IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl) -// VZ: the new behaviour is to create the radio buttons as children of the -// radiobox instead of creating them as children of the radiobox' parent. +// there are two possible ways to create the radio buttons: either as children +// of the radiobox or as siblings of it - allow playing with both variants for +// now, eventually we will choose the best one for our purposes // -// This seems more logical, more consistent with what other frameworks do -// and allows tooltips to work with radioboxes, so there should be no -// reason to revert to the backward compatible behaviour - but I still -// leave this possibility just in case. - +// two main problems are the keyboard navigation inside the radiobox (arrows +// should switch between buttons, not pass focus to the next control) and the +// tooltips - a tooltip is associated with the radiobox itself, not the +// children... +// +// the problems with setting this to 1: +// a) Alt- isn't handled properly by IsDialogMessage() +// because it sets focus to the next control accepting it which is not a +// radio button but a radiobox sibling in this case - the only solution to +// this would be to handle Alt- ourselves +// b) the problems with setting radiobox colours under Win98/2K were reported +// but I couldn't reproduce it so I have no idea about what causes it +// +// the problems with setting this to 0: +// a) the tooltips are not shown for the radiobox - possible solution: make +// TTM_WINDOWFROMPOS handling code in msw/tooltip.cpp work (easier said than +// done because I don't know why it doesn't work) #define RADIOBTN_PARENT_IS_RADIOBOX 0 // --------------------------------------------------------------------------- @@ -156,7 +167,7 @@ wxRadioBox::wxRadioBox(wxWindow *parent, wxFunction func, const char *title, delete choices2; } -#endif +#endif // WXWIN_COMPATIBILITY // Radio box item wxRadioBox::wxRadioBox() @@ -194,7 +205,8 @@ bool wxRadioBox::Create(wxWindow *parent, return FALSE; // create the static box - if ( !MSWCreateControl(wxT("BUTTON"), BS_GROUPBOX, pos, size, title, 0) ) + if ( !MSWCreateControl(wxT("BUTTON"), BS_GROUPBOX | WS_GROUP, + pos, size, title, 0) ) return FALSE; // and now create the buttons @@ -667,15 +679,17 @@ void wxRadioBox::Command(wxCommandEvent & event) ProcessCommand (event); } +// NB: if this code is changed, wxGetWindowForHWND() which relies on having the +// radiobox pointer in GWL_USERDATA for radio buttons must be updated too! void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn) { + // No GWL_USERDATA in Win16, so omit this subclassing. #ifdef __WIN32__ HWND hwndBtn = (HWND)hWndBtn; if ( !s_wndprocRadioBtn ) s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC); - // No GWL_USERDATA in Win16, so omit this subclassing. ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc); ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this); #endif // __WIN32__ @@ -705,13 +719,21 @@ bool wxRadioBox::SetFont(const wxFont& font) ::SendMessage((HWND)m_radioButtons[n], WM_SETFONT, (WPARAM)hfont, 0L); } + // this is needed because otherwise the buttons are not redrawn correctly + Refresh(); + return TRUE; } +// ---------------------------------------------------------------------------- +// our window proc +// ---------------------------------------------------------------------------- + long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) { switch ( nMsg ) { +#ifdef __WIN32__ case WM_CTLCOLORSTATIC: // set the colour of the radio buttons to be the same as ours { @@ -725,6 +747,7 @@ long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) return (WXHBRUSH)brush->GetResourceHandle(); } +#endif // Win32 // This is required for the radiobox to be sensitive to mouse input, // e.g. for Dialog Editor. @@ -740,11 +763,10 @@ long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) if (yPos < 10) return (long)HTCLIENT; } - // fall through - - default: - return wxControl::MSWWindowProc(nMsg, wParam, lParam); + break; } + + return wxControl::MSWWindowProc(nMsg, wParam, lParam); } // --------------------------------------------------------------------------- @@ -754,95 +776,104 @@ long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) #ifdef __WIN32__ LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd, - UINT msg, + UINT message, WPARAM wParam, LPARAM lParam) { - bool processed = FALSE; - if ( msg == WM_KEYDOWN -#if wxUSE_TOOLTIPS - || msg == WM_NOTIFY -#endif // wxUSE_TOOLTIPS - ) + switch ( message ) { - wxRadioBox *radiobox = (wxRadioBox *)::GetWindowLong(hwnd, GWL_USERDATA); + case WM_GETDLGCODE: + // we must tell IsDialogMessage()/our kbd processing code that we + // want to process arrows ourselves because neither of them is + // smart enough to handle arrows properly for us + { + long lDlgCode = ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, + message, wParam, lParam); - wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") ); + return lDlgCode | DLGC_WANTARROWS; + } -#if wxUSE_TOOLTIPS && !defined(__GNUWIN32__) - if ( msg == WM_NOTIFY ) - { - NMHDR* hdr = (NMHDR *)lParam; - if ( (int)hdr->code == TTN_NEEDTEXT ) +#if wxUSE_TOOLTIPS + case WM_NOTIFY: { - wxToolTip *tt = radiobox->GetToolTip(); - if ( tt ) + NMHDR* hdr = (NMHDR *)lParam; + if ( (int)hdr->code == TTN_NEEDTEXT ) { - TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam; - ttt->lpszText = (wxChar *)tt->GetTip().c_str(); + wxRadioBox *radiobox = (wxRadioBox *) + ::GetWindowLong(hwnd, GWL_USERDATA); - processed = TRUE; + 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; } } - } - else // msg == WM_KEYDOWN + break; #endif // wxUSE_TOOLTIPS - { - processed = TRUE; - int sel = radiobox->GetSelection(); - - switch ( wParam ) + case WM_KEYDOWN: { - case VK_UP: - sel--; - break; + wxRadioBox *radiobox = (wxRadioBox *) + ::GetWindowLong(hwnd, GWL_USERDATA); - case VK_LEFT: - sel -= radiobox->GetNumVer(); - break; + wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") ); - case VK_DOWN: - sel++; - break; + bool processed = TRUE; - case VK_RIGHT: - sel += radiobox->GetNumVer(); - break; + int selOld = radiobox->GetSelection(); + int selNew = selOld; - case VK_TAB: - { - wxNavigationKeyEvent event; - event.SetDirection(!(::GetKeyState(VK_SHIFT) & 0x100)); - event.SetWindowChange(FALSE); - event.SetEventObject(radiobox); + switch ( wParam ) + { + case VK_UP: + selNew--; + break; - if ( radiobox->GetEventHandler()->ProcessEvent(event) ) - return 0; - } - // fall through + case VK_LEFT: + selNew -= radiobox->GetNumVer(); + break; - default: - processed = FALSE; - } + case VK_DOWN: + selNew++; + break; - if ( processed ) - { - if ( sel >= 0 && sel < radiobox->Number() ) + case VK_RIGHT: + selNew += radiobox->GetNumVer(); + break; + + default: + processed = FALSE; + } + + if ( processed ) { - radiobox->SetSelection(sel); + // ensure that selNew is in range [0..num) + int num = radiobox->Number(); + selNew += num; + selNew %= num; + + if ( selNew != selOld ) + { + radiobox->SetSelection(selNew); + + // emulate the button click + radiobox->SendNotificationEvent(); - // emulate the button click - radiobox->SendNotificationEvent(); + return 0; + } } } - } } - if ( processed ) - return 0; - - return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, msg, wParam, lParam); + return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, message, wParam, lParam); } #endif // __WIN32__