Mostly Mingw32/Cygwin corrections
[wxWidgets.git] / src / msw / radiobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: radiobox.cpp
3 // Purpose: wxRadioBox
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "radiobox.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include "wx/bitmap.h"
33 #include "wx/brush.h"
34 #include "wx/radiobox.h"
35 #include "wx/log.h"
36 #endif
37
38 #include "wx/msw/private.h"
39
40 #if wxUSE_TOOLTIPS
41
42 #ifndef __GNUWIN32__
43 #include <commctrl.h>
44 #endif
45
46 #include "wx/tooltip.h"
47 #endif // wxUSE_TOOLTIPS
48
49 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
50
51 // VZ: the new behaviour is to create the radio buttons as children of the
52 // radiobox instead of creating them as children of the radiobox' parent.
53 //
54 // This seems more logical, more consistent with what other frameworks do
55 // and allows tooltips to work with radioboxes, so there should be no
56 // reason to revert to the backward compatible behaviour - but I still
57 // leave this possibility just in case.
58
59 // For some reason, the background colour is set wrongly in WIN16 mode
60 // if we use the new method.
61
62 #ifdef __WIN16__
63 #define RADIOBTN_PARENT_IS_RADIOBOX 0
64 #else
65 #define RADIOBTN_PARENT_IS_RADIOBOX 1
66 #endif
67
68 // ---------------------------------------------------------------------------
69 // private functions
70 // ---------------------------------------------------------------------------
71
72 // wnd proc for radio buttons
73 #ifdef __WIN32__
74 LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hWnd,
75 UINT message,
76 WPARAM wParam,
77 LPARAM lParam);
78
79 // ---------------------------------------------------------------------------
80 // global vars
81 // ---------------------------------------------------------------------------
82
83 // the pointer to standard radio button wnd proc
84 static WXFARPROC s_wndprocRadioBtn = (WXFARPROC)NULL;
85
86 #endif // __WIN32__
87
88 // ===========================================================================
89 // implementation
90 // ===========================================================================
91
92 // ---------------------------------------------------------------------------
93 // wxRadioBox
94 // ---------------------------------------------------------------------------
95
96 int wxRadioBox::GetNumVer() const
97 {
98 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
99 {
100 return m_majorDim;
101 }
102 else
103 {
104 return (m_noItems + m_majorDim - 1)/m_majorDim;
105 }
106 }
107
108 int wxRadioBox::GetNumHor() const
109 {
110 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
111 {
112 return (m_noItems + m_majorDim - 1)/m_majorDim;
113 }
114 else
115 {
116 return m_majorDim;
117 }
118 }
119
120 bool wxRadioBox::MSWCommand(WXUINT cmd, WXWORD id)
121 {
122 if ( cmd == BN_CLICKED )
123 {
124 int selectedButton = -1;
125
126 for ( int i = 0; i < m_noItems; i++ )
127 {
128 if ( id == wxGetWindowId(m_radioButtons[i]) )
129 {
130 selectedButton = i;
131
132 break;
133 }
134 }
135
136 wxASSERT_MSG( selectedButton != -1, wxT("click from alien button?") );
137
138 if ( selectedButton != m_selectedButton )
139 {
140 m_selectedButton = selectedButton;
141
142 SendNotificationEvent();
143 }
144 //else: don't generate events when the selection doesn't change
145
146 return TRUE;
147 }
148 else
149 return FALSE;
150 }
151
152 #if WXWIN_COMPATIBILITY
153 wxRadioBox::wxRadioBox(wxWindow *parent, wxFunction func, const char *title,
154 int x, int y, int width, int height,
155 int n, char **choices,
156 int majorDim, long style, const char *name)
157 {
158 wxString *choices2 = new wxString[n];
159 for ( int i = 0; i < n; i ++) choices2[i] = choices[i];
160 Create(parent, -1, title, wxPoint(x, y), wxSize(width, height), n, choices2, majorDim, style,
161 wxDefaultValidator, name);
162 Callback(func);
163 delete choices2;
164 }
165
166 #endif
167
168 // Radio box item
169 wxRadioBox::wxRadioBox()
170 {
171 m_selectedButton = -1;
172 m_noItems = 0;
173 m_noRowsOrCols = 0;
174 m_radioButtons = NULL;
175 m_majorDim = 0;
176 m_radioWidth = NULL;
177 m_radioHeight = NULL;
178 }
179
180 bool wxRadioBox::Create(wxWindow *parent,
181 wxWindowID id,
182 const wxString& title,
183 const wxPoint& pos,
184 const wxSize& size,
185 int n,
186 const wxString choices[],
187 int majorDim,
188 long style,
189 const wxValidator& val,
190 const wxString& name)
191 {
192 // initialize members
193 m_selectedButton = -1;
194 m_noItems = 0;
195
196 m_majorDim = majorDim == 0 ? n : majorDim;
197 m_noRowsOrCols = majorDim;
198
199 // common initialization
200 if ( !CreateControl(parent, id, pos, size, style, val, name) )
201 return FALSE;
202
203 // create the static box
204 if ( !MSWCreateControl(wxT("BUTTON"), BS_GROUPBOX, pos, size, title, 0) )
205 return FALSE;
206
207 // and now create the buttons
208 m_noItems = n;
209 #if RADIOBTN_PARENT_IS_RADIOBOX
210 HWND hwndParent = GetHwnd();
211 #else
212 HWND hwndParent = GetHwndOf(parent);
213 #endif
214
215 // Some radio boxes test consecutive id.
216 (void)NewControlId();
217 m_radioButtons = new WXHWND[n];
218 m_radioWidth = new int[n];
219 m_radioHeight = new int[n];
220
221 WXHFONT hfont = 0;
222 wxFont& font = GetFont();
223 if ( font.Ok() )
224 {
225 hfont = font.GetResourceHandle();
226 }
227
228 for ( int i = 0; i < n; i++ )
229 {
230 m_radioWidth[i] =
231 m_radioHeight[i] = -1;
232 long styleBtn = BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE;
233 if ( i == 0 && style == 0 )
234 styleBtn |= WS_GROUP;
235
236 long newId = NewControlId();
237
238 HWND hwndBtn = ::CreateWindow(_T("BUTTON"),
239 choices[i],
240 styleBtn,
241 0, 0, 0, 0, // will be set in SetSize()
242 hwndParent,
243 (HMENU)newId,
244 wxGetInstance(),
245 NULL);
246
247 if ( !hwndBtn )
248 {
249 wxLogLastError("CreateWindow(radio btn)");
250
251 return FALSE;
252 }
253
254 m_radioButtons[i] = (WXHWND)hwndBtn;
255
256 SubclassRadioButton((WXHWND)hwndBtn);
257
258 if ( hfont )
259 {
260 ::SendMessage(hwndBtn, WM_SETFONT, (WPARAM)hfont, 0L);
261 }
262
263 m_subControls.Add(newId);
264 }
265
266 // Create a dummy radio control to end the group.
267 (void)::CreateWindow(_T("BUTTON"),
268 _T(""),
269 WS_GROUP | BS_AUTORADIOBUTTON | WS_CHILD,
270 0, 0, 0, 0, hwndParent,
271 (HMENU)NewControlId(), wxGetInstance(), NULL);
272
273 SetSelection(0);
274
275 SetSize(pos.x, pos.y, size.x, size.y);
276
277 return TRUE;
278 }
279
280 wxRadioBox::~wxRadioBox()
281 {
282 m_isBeingDeleted = TRUE;
283
284 if (m_radioButtons)
285 {
286 int i;
287 for (i = 0; i < m_noItems; i++)
288 ::DestroyWindow((HWND)m_radioButtons[i]);
289 delete[] m_radioButtons;
290 }
291
292 if (m_radioWidth)
293 delete[] m_radioWidth;
294 if (m_radioHeight)
295 delete[] m_radioHeight;
296
297 }
298
299 wxString wxRadioBox::GetLabel(int item) const
300 {
301 wxCHECK_MSG( item >= 0 && item < m_noItems, wxT(""), wxT("invalid radiobox index") );
302
303 return wxGetWindowText(m_radioButtons[item]);
304 }
305
306 void wxRadioBox::SetLabel(int item, const wxString& label)
307 {
308 wxCHECK_RET( item >= 0 && item < m_noItems, wxT("invalid radiobox index") );
309
310 m_radioWidth[item] = m_radioHeight[item] = -1;
311 SetWindowText((HWND)m_radioButtons[item], label.c_str());
312 }
313
314 void wxRadioBox::SetLabel(int item, wxBitmap *bitmap)
315 {
316 /*
317 m_radioWidth[item] = bitmap->GetWidth() + FB_MARGIN;
318 m_radioHeight[item] = bitmap->GetHeight() + FB_MARGIN;
319 */
320 wxFAIL_MSG(wxT("not implemented"));
321 }
322
323 int wxRadioBox::FindString(const wxString& s) const
324 {
325 for (int i = 0; i < m_noItems; i++)
326 {
327 if ( s == wxGetWindowText(m_radioButtons[i]) )
328 return i;
329 }
330
331 return wxNOT_FOUND;
332 }
333
334 void wxRadioBox::SetSelection(int N)
335 {
336 wxCHECK_RET( (N >= 0) && (N < m_noItems), wxT("invalid radiobox index") );
337
338 // Following necessary for Win32s, because Win32s translate BM_SETCHECK
339 if (m_selectedButton >= 0 && m_selectedButton < m_noItems)
340 ::SendMessage((HWND) m_radioButtons[m_selectedButton], BM_SETCHECK, 0, 0L);
341
342 ::SendMessage((HWND)m_radioButtons[N], BM_SETCHECK, 1, 0L);
343 ::SetFocus((HWND)m_radioButtons[N]);
344
345 m_selectedButton = N;
346 }
347
348 // Get single selection, for single choice list items
349 int wxRadioBox::GetSelection() const
350 {
351 return m_selectedButton;
352 }
353
354 // Find string for position
355 wxString wxRadioBox::GetString(int N) const
356 {
357 return wxGetWindowText(m_radioButtons[N]);
358 }
359
360 // Restored old code.
361 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
362 {
363 int currentX, currentY;
364 GetPosition(&currentX, &currentY);
365 int widthOld, heightOld;
366 GetSize(&widthOld, &heightOld);
367
368 int xx = x;
369 int yy = y;
370
371 if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
372 xx = currentX;
373 if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
374 yy = currentY;
375
376 #if RADIOBTN_PARENT_IS_RADIOBOX
377 int y_offset = 0;
378 int x_offset = 0;
379 #else
380 int y_offset = yy;
381 int x_offset = xx;
382 #endif
383
384 int current_width, cyf;
385
386 int cx1,cy1;
387 wxGetCharSize(m_hWnd, &cx1, &cy1, & GetFont());
388
389 // Attempt to have a look coherent with other platforms: We compute the
390 // biggest toggle dim, then we align all items according this value.
391 int maxWidth = -1;
392 int maxHeight = -1;
393
394 int i;
395 for (i = 0 ; i < m_noItems; i++)
396 {
397 int eachWidth;
398 int eachHeight;
399 if (m_radioWidth[i]<0)
400 {
401 // It's a labelled toggle
402 GetTextExtent(wxGetWindowText(m_radioButtons[i]),
403 &current_width, &cyf);
404 eachWidth = (int)(current_width + RADIO_SIZE);
405 eachHeight = (int)((3*cyf)/2);
406 }
407 else
408 {
409 eachWidth = m_radioWidth[i];
410 eachHeight = m_radioHeight[i];
411 }
412
413 if (maxWidth<eachWidth)
414 maxWidth = eachWidth;
415 if (maxHeight<eachHeight)
416 maxHeight = eachHeight;
417 }
418
419 if (m_hWnd)
420 {
421 int totWidth;
422 int totHeight;
423
424 int nbHor = GetNumHor(),
425 nbVer = GetNumVer();
426
427 // this formula works, but I don't know why.
428 // Please, be sure what you do if you modify it!!
429 if (m_radioWidth[0]<0)
430 totHeight = (nbVer * maxHeight) + cy1/2;
431 else
432 totHeight = nbVer * (maxHeight+cy1/2);
433 totWidth = nbHor * (maxWidth+cx1);
434
435 int extraHeight = cy1;
436
437 #if defined(CTL3D) && !CTL3D
438 // Requires a bigger group box in plain Windows
439 extraHeight *= 3;
440 extraHeight /= 2;
441 #endif
442
443 // only change our width/height if asked for
444 if ( width == -1 )
445 {
446 if ( sizeFlags & wxSIZE_AUTO_WIDTH )
447 width = totWidth + cx1;
448 else
449 width = widthOld;
450 }
451
452 if ( height == -1 )
453 {
454 if ( sizeFlags & wxSIZE_AUTO_HEIGHT )
455 height = totHeight + extraHeight;
456 else
457 height = heightOld;
458 }
459
460 ::MoveWindow(GetHwnd(), xx, yy, width, height, TRUE);
461
462 x_offset += cx1;
463 y_offset += cy1;
464 }
465
466 #if defined(CTL3D) && (!CTL3D)
467 y_offset += (int)(cy1/2); // Fudge factor since buttons overlapped label
468 // JACS 2/12/93. CTL3D draws group label quite high.
469 #endif
470 int startX = x_offset;
471 int startY = y_offset;
472
473 for ( i = 0 ; i < m_noItems; i++)
474 {
475 // Bidimensional radio adjustment
476 if (i&&((i%m_majorDim)==0)) // Why is this omitted for i = 0?
477 {
478 if (m_windowStyle & wxRA_VERTICAL)
479 {
480 y_offset = startY;
481 x_offset += maxWidth + cx1;
482 }
483 else
484 {
485 x_offset = startX;
486 y_offset += maxHeight;
487 if (m_radioWidth[0]>0)
488 y_offset += cy1/2;
489 }
490 }
491 int eachWidth;
492 int eachHeight;
493 if (m_radioWidth[i]<0)
494 {
495 // It's a labeled item
496 GetTextExtent(wxGetWindowText(m_radioButtons[i]),
497 &current_width, &cyf);
498
499 // How do we find out radio button bitmap size!!
500 // By adjusting them carefully, manually :-)
501 eachWidth = (int)(current_width + RADIO_SIZE);
502 eachHeight = (int)((3*cyf)/2);
503 }
504 else
505 {
506 eachWidth = m_radioWidth[i];
507 eachHeight = m_radioHeight[i];
508 }
509
510 // VZ: make all buttons of the same, maximal size - like this they
511 // cover the radiobox entirely and the radiobox tooltips are always
512 // shown (otherwise they are not when the mouse pointer is in the
513 // radiobox part not belonging to any radiobutton)
514 ::MoveWindow((HWND)m_radioButtons[i],
515 x_offset, y_offset, maxWidth, maxHeight,
516 TRUE);
517
518 if (m_windowStyle & wxRA_SPECIFY_ROWS)
519 {
520 y_offset += maxHeight;
521 if (m_radioWidth[0]>0)
522 y_offset += cy1/2;
523 }
524 else
525 x_offset += maxWidth + cx1;
526 }
527 }
528
529 void wxRadioBox::GetSize(int *width, int *height) const
530 {
531 RECT rect;
532 rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
533
534 if (m_hWnd)
535 wxFindMaxSize(m_hWnd, &rect);
536
537 int i;
538 for (i = 0; i < m_noItems; i++)
539 wxFindMaxSize(m_radioButtons[i], &rect);
540
541 *width = rect.right - rect.left;
542 *height = rect.bottom - rect.top;
543 }
544
545 void wxRadioBox::GetPosition(int *x, int *y) const
546 {
547 wxWindow *parent = GetParent();
548 RECT rect = { -1, -1, -1, -1 };
549
550 int i;
551 for (i = 0; i < m_noItems; i++)
552 wxFindMaxSize(m_radioButtons[i], &rect);
553
554 if (m_hWnd)
555 wxFindMaxSize(m_hWnd, &rect);
556
557 // Since we now have the absolute screen coords, if there's a parent we
558 // must subtract its top left corner
559 POINT point;
560 point.x = rect.left;
561 point.y = rect.top;
562 if (parent)
563 {
564 ::ScreenToClient((HWND) parent->GetHWND(), &point);
565 }
566
567 // We may be faking the client origin. So a window that's really at (0, 30)
568 // may appear (to wxWin apps) to be at (0, 0).
569 if (GetParent())
570 {
571 wxPoint pt(GetParent()->GetClientAreaOrigin());
572 point.x -= pt.x;
573 point.y -= pt.y;
574 }
575
576 *x = point.x;
577 *y = point.y;
578 }
579
580 void wxRadioBox::SetFocus()
581 {
582 if (m_noItems > 0)
583 {
584 if (m_selectedButton == -1)
585 ::SetFocus((HWND) m_radioButtons[0]);
586 else
587 ::SetFocus((HWND) m_radioButtons[m_selectedButton]);
588 }
589
590 }
591
592 bool wxRadioBox::Show(bool show)
593 {
594 if ( !wxControl::Show(show) )
595 return FALSE;
596
597 int nCmdShow = show ? SW_SHOW : SW_HIDE;
598 for ( int i = 0; i < m_noItems; i++ )
599 {
600 ::ShowWindow((HWND)m_radioButtons[i], nCmdShow);
601 }
602
603 return TRUE;
604 }
605
606 // Enable a specific button
607 void wxRadioBox::Enable(int item, bool enable)
608 {
609 wxCHECK_RET( item >= 0 && item < m_noItems,
610 wxT("invalid item in wxRadioBox::Enable()") );
611
612 ::EnableWindow((HWND) m_radioButtons[item], enable);
613 }
614
615 // Enable all controls
616 bool wxRadioBox::Enable(bool enable)
617 {
618 if ( !wxControl::Enable(enable) )
619 return FALSE;
620
621 for (int i = 0; i < m_noItems; i++)
622 ::EnableWindow((HWND) m_radioButtons[i], enable);
623
624 return TRUE;
625 }
626
627 // Show a specific button
628 void wxRadioBox::Show(int item, bool show)
629 {
630 wxCHECK_RET( item >= 0 && item < m_noItems,
631 wxT("invalid item in wxRadioBox::Show()") );
632
633 ::ShowWindow((HWND)m_radioButtons[item], show ? SW_SHOW : SW_HIDE);
634 }
635
636 // For single selection items only
637 wxString wxRadioBox::GetStringSelection() const
638 {
639 wxString result;
640 int sel = GetSelection();
641 if (sel > -1)
642 result = GetString(sel);
643
644 return result;
645 }
646
647 bool wxRadioBox::SetStringSelection(const wxString& s)
648 {
649 int sel = FindString (s);
650 if (sel > -1)
651 {
652 SetSelection (sel);
653 return TRUE;
654 }
655 else
656 return FALSE;
657 }
658
659 bool wxRadioBox::ContainsHWND(WXHWND hWnd) const
660 {
661 int i;
662 for (i = 0; i < Number(); i++)
663 {
664 if (GetRadioButtons()[i] == hWnd)
665 return TRUE;
666 }
667
668 return FALSE;
669 }
670
671 void wxRadioBox::Command(wxCommandEvent & event)
672 {
673 SetSelection (event.m_commandInt);
674 ProcessCommand (event);
675 }
676
677 void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn)
678 {
679 #ifdef __WIN32__
680 HWND hwndBtn = (HWND)hWndBtn;
681
682 if ( !s_wndprocRadioBtn )
683 s_wndprocRadioBtn = (WXFARPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC);
684
685 // No GWL_USERDATA in Win16, so omit this subclassing.
686 ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc);
687 ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this);
688 #endif // __WIN32__
689 }
690
691 void wxRadioBox::SendNotificationEvent()
692 {
693 wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId);
694 event.SetInt( m_selectedButton );
695 event.SetString( GetString(m_selectedButton) );
696 event.SetEventObject( this );
697 ProcessCommand(event);
698 }
699
700 bool wxRadioBox::SetFont(const wxFont& font)
701 {
702 if ( !wxControl::SetFont(font) )
703 {
704 // nothing to do
705 return FALSE;
706 }
707
708 // also set the font of our radio buttons
709 WXHFONT hfont = wxFont(font).GetResourceHandle();
710 for ( int n = 0; n < m_noItems; n++ )
711 {
712 ::SendMessage((HWND)m_radioButtons[n], WM_SETFONT, (WPARAM)hfont, 0L);
713 }
714
715 return TRUE;
716 }
717
718 long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
719 {
720 // This is required for the radiobox to be sensitive to mouse input,
721 // e.g. for Dialog Editor.
722 if (nMsg == WM_NCHITTEST)
723 {
724 int xPos = LOWORD(lParam); // horizontal position of cursor
725 int yPos = HIWORD(lParam); // vertical position of cursor
726
727 ScreenToClient(&xPos, &yPos);
728
729 // Make sure you can drag by the top of the groupbox, but let
730 // other (enclosed) controls get mouse events also
731 if (yPos < 10)
732 return (long)HTCLIENT;
733 }
734
735 return wxControl::MSWWindowProc(nMsg, wParam, lParam);
736 }
737
738 // ---------------------------------------------------------------------------
739 // window proc for radio buttons
740 // ---------------------------------------------------------------------------
741
742 #ifdef __WIN32__
743
744 LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
745 UINT msg,
746 WPARAM wParam,
747 LPARAM lParam)
748 {
749 bool processed = FALSE;
750 if ( msg == WM_KEYDOWN
751 #if wxUSE_TOOLTIPS
752 || msg == WM_NOTIFY
753 #endif // wxUSE_TOOLTIPS
754 )
755 {
756 wxRadioBox *radiobox = (wxRadioBox *)::GetWindowLong(hwnd, GWL_USERDATA);
757
758 wxCHECK_MSG( radiobox, 0, wxT("radio button without radio box?") );
759
760 #if wxUSE_TOOLTIPS && !defined(__GNUWIN32__)
761 if ( msg == WM_NOTIFY )
762 {
763 NMHDR* hdr = (NMHDR *)lParam;
764 if ( (int)hdr->code == TTN_NEEDTEXT )
765 {
766 wxToolTip *tt = radiobox->GetToolTip();
767 if ( tt )
768 {
769 TOOLTIPTEXT *ttt = (TOOLTIPTEXT *)lParam;
770 ttt->lpszText = (wxChar *)tt->GetTip().c_str();
771
772 processed = TRUE;
773 }
774 }
775 }
776 else // msg == WM_KEYDOWN
777 #endif // wxUSE_TOOLTIPS
778 {
779 processed = TRUE;
780
781 int sel = radiobox->GetSelection();
782
783 switch ( wParam )
784 {
785 case VK_UP:
786 sel--;
787 break;
788
789 case VK_LEFT:
790 sel -= radiobox->GetNumVer();
791 break;
792
793 case VK_DOWN:
794 sel++;
795 break;
796
797 case VK_RIGHT:
798 sel += radiobox->GetNumVer();
799 break;
800
801 case VK_TAB:
802 {
803 wxNavigationKeyEvent event;
804 event.SetDirection(!(::GetKeyState(VK_SHIFT) & 0x100));
805 event.SetWindowChange(FALSE);
806 event.SetEventObject(radiobox);
807
808 if ( radiobox->GetEventHandler()->ProcessEvent(event) )
809 return 0;
810 }
811 // fall through
812
813 default:
814 processed = FALSE;
815 }
816
817 if ( processed )
818 {
819 if ( sel >= 0 && sel < radiobox->Number() )
820 {
821 radiobox->SetSelection(sel);
822
823 // emulate the button click
824 radiobox->SendNotificationEvent();
825 }
826 }
827 }
828 }
829
830 if ( processed )
831 return 0;
832
833 return ::CallWindowProc(CASTWNDPROC s_wndprocRadioBtn, hwnd, msg, wParam, lParam);
834 }
835
836 #endif // __WIN32__
837