The rounded corners look really dumb at this size.
[wxWidgets.git] / src / os2 / radiobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/radiobox.cpp
3 // Purpose: wxRadioBox
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/12/99
7 // Copyright: (c) David Webster
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // For compilers that support precompilation, includes "wx.h".
12 #include "wx/wxprec.h"
13
14 #if wxUSE_RADIOBOX
15
16 #include "wx/radiobox.h"
17
18 #ifndef WX_PRECOMP
19 #include <stdio.h>
20 #include "wx/crt.h"
21 #include "wx/string.h"
22 #include "wx/bitmap.h"
23 #include "wx/brush.h"
24 #endif
25
26 #include "wx/os2/private.h"
27
28 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
29
30 // ---------------------------------------------------------------------------
31 // private functions
32 // ---------------------------------------------------------------------------
33
34 // wnd proc for radio buttons
35 MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
36 ,UINT uMessage
37 ,MPARAM wParam
38 ,MPARAM lParam
39 );
40 MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd
41 ,UINT uMessage
42 ,MPARAM wParam
43 ,MPARAM lParam
44 );
45
46 // ---------------------------------------------------------------------------
47 // global vars
48 // ---------------------------------------------------------------------------
49
50 extern void wxAssociateWinWithHandle( HWND hWnd
51 ,wxWindowOS2* pWin
52 );
53 extern void wxRemoveHandleAssociation( wxWindowOS2 *pWin );
54 // the pointer to standard radio button & box wnd procs
55 static WXFARPROC fnWndProcRadioBtn = NULL;
56 static WXFARPROC fnWndProcRadioBox = NULL;
57
58 // ===========================================================================
59 // implementation
60 // ===========================================================================
61
62 // ---------------------------------------------------------------------------
63 // wxRadioBox
64 // ---------------------------------------------------------------------------
65
66 // Radio box item
67 wxRadioBox::wxRadioBox()
68 {
69 m_nSelectedButton = -1;
70 m_nNoItems = 0;
71 m_ahRadioButtons = NULL;
72 m_pnRadioWidth = NULL;
73 m_pnRadioHeight = NULL;
74 } // end of wxRadioBox::wxRadioBox
75
76 wxRadioBox::~wxRadioBox()
77 {
78 SendDestroyEvent();
79
80 if (m_hWnd)
81 wxRemoveHandleAssociation(this);
82 if (m_ahRadioButtons)
83 {
84 for (unsigned int i = 0; i < m_nNoItems; i++)
85 {
86 wxWindow* pWin = wxFindWinFromHandle((WXHWND)m_ahRadioButtons[i]);
87 wxRemoveHandleAssociation(pWin);
88
89 ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
90 }
91 delete[] m_ahRadioButtons;
92 }
93 if (m_pnRadioWidth)
94 delete[] m_pnRadioWidth;
95 if (m_pnRadioHeight)
96 delete[] m_pnRadioHeight;
97 } // end of wxRadioBox::~wxRadioBox
98
99 void wxRadioBox::Command ( wxCommandEvent& rEvent )
100 {
101 SetSelection (rEvent.GetInt());
102 ProcessCommand(rEvent);
103 } // end of wxRadioBox::Command
104
105 bool wxRadioBox::ContainsHWND( WXHWND hWnd ) const
106 {
107 unsigned int nCount = GetCount();
108 unsigned int i;
109
110 for (i = 0; i < nCount; i++)
111 {
112 if (GetRadioButtons()[i] == hWnd)
113 return true;
114 }
115 return false;
116 } // end of wxRadioBox::ContainsHWND
117
118 bool wxRadioBox::Create( wxWindow* pParent,
119 wxWindowID vId,
120 const wxString& rsTitle,
121 const wxPoint& rPos,
122 const wxSize& rSize,
123 const wxArrayString& asChoices,
124 int nMajorDim,
125 long lStyle,
126 const wxValidator& rVal,
127 const wxString& rsName )
128 {
129 wxCArrayString chs(asChoices);
130
131 return Create(pParent, vId, rsTitle, rPos, rSize, chs.GetCount(),
132 chs.GetStrings(), nMajorDim, lStyle, rVal, rsName);
133 }
134
135 bool wxRadioBox::Create( wxWindow* pParent,
136 wxWindowID vId,
137 const wxString& rsTitle,
138 const wxPoint& rPos,
139 const wxSize& rSize,
140 int nNum,
141 const wxString asChoices[],
142 int nMajorDim,
143 long lStyle,
144 const wxValidator& rVal,
145 const wxString& rsName )
146 {
147 wxColour vColour(*wxBLACK);
148 LONG lColor;
149 HWND hWndParent = GetHwndOf(pParent);
150
151 m_backgroundColour = pParent->GetBackgroundColour();
152 m_nSelectedButton = -1;
153 m_nNoItems = 0;
154
155 //
156 // Common initialization
157 //
158 if (!CreateControl( pParent
159 ,vId
160 ,rPos
161 ,rSize
162 ,lStyle
163 ,rVal
164 ,rsName
165 ))
166 return false;
167 if (!OS2CreateControl( wxT("STATIC")
168 ,SS_GROUPBOX
169 ,rPos
170 ,rSize
171 ,rsTitle
172 ))
173 return false;
174
175 wxAssociateWinWithHandle(m_hWnd, this);
176
177 //
178 // Now we can set m_nNoItems and let SetMajorDim set m_numCols/m_numRows
179 //
180 m_nNoItems = (unsigned int)nNum;
181 SetMajorDim(nMajorDim == 0 ? nNum : nMajorDim, lStyle);
182
183 m_ahRadioButtons = new WXHWND[nNum];
184 m_pnRadioWidth = new int[nNum];
185 m_pnRadioHeight = new int[nNum];
186
187 for (int i = 0; i < nNum; i++)
188 {
189 m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
190 long lStyleBtn = BS_AUTORADIOBUTTON | WS_VISIBLE;
191 int nNewId = NewControlId();
192
193 if (i == 0)
194 lStyleBtn |= WS_GROUP | WS_TABSTOP;
195
196 wxString sLabel = ::wxPMTextToLabel(asChoices[i]);
197
198 HWND hWndBtn = (WXHWND)::WinCreateWindow ( hWndParent,
199 WC_BUTTON,
200 sLabel.c_str(),
201 lStyleBtn,
202 0, 0, 0, 0,
203 hWndParent,
204 HWND_BOTTOM,
205 (HMENU)nNewId,
206 NULL,
207 NULL
208 );
209 if (!hWndBtn)
210 {
211 return false;
212 }
213 lColor = (LONG)vColour.GetPixel();
214 ::WinSetPresParam( hWndBtn
215 ,PP_FOREGROUNDCOLOR
216 ,sizeof(LONG)
217 ,(PVOID)&lColor
218 );
219
220 lColor = (LONG)m_backgroundColour.GetPixel();
221 ::WinSetPresParam( hWndBtn
222 ,PP_BACKGROUNDCOLOR
223 ,sizeof(LONG)
224 ,(PVOID)&lColor
225 );
226 m_ahRadioButtons[i] = (WXHWND)hWndBtn;
227 SubclassRadioButton((WXHWND)hWndBtn);
228 wxAssociateWinWithHandle(hWndBtn, this);
229 wxOS2SetFont( hWndBtn
230 ,*wxSMALL_FONT
231 );
232 ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
233 m_aSubControls.Add(nNewId);
234 }
235
236 //
237 // Create a dummy control to end the group.
238 //
239 (void)::WinCreateWindow ( hWndParent,
240 WC_BUTTON,
241 "",
242 WS_GROUP,
243 0, 0, 0, 0,
244 hWndParent,
245 HWND_TOP,
246 (HMENU)NewControlId(),
247 NULL,
248 NULL
249 );
250 fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
251 ,(PFNWP)wxRadioBoxWndProc
252 );
253 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
254 lColor = (LONG)vColour.GetPixel();
255 ::WinSetPresParam( m_hWnd
256 ,PP_FOREGROUNDCOLOR
257 ,sizeof(LONG)
258 ,(PVOID)&lColor
259 );
260
261 lColor = (LONG)m_backgroundColour.GetPixel();
262 ::WinSetPresParam( m_hWnd
263 ,PP_BACKGROUNDCOLOR
264 ,sizeof(LONG)
265 ,(PVOID)&lColor
266 );
267 SetXComp(0);
268 SetYComp(0);
269 SetSelection(0);
270 SetSize( rPos.x
271 ,rPos.y
272 ,rSize.x
273 ,rSize.y
274 );
275 return true;
276 } // end of wxRadioBox::Create
277
278 wxSize wxRadioBox::DoGetBestSize() const
279 {
280 return (GetTotalButtonSize(GetMaxButtonSize()));
281 } // end of wxRadioBox::DoGetBestSize
282
283 void wxRadioBox::DoSetSize(
284 int nX
285 , int nY
286 , int nWidth
287 , int nHeight
288 , int nSizeFlags
289 )
290 {
291 //
292 // Input parameters assume wxWidgets coordinate system
293 //
294 int nCurrentX;
295 int nCurrentY;
296 int nWidthOld;
297 int nHeightOld;
298 int nXx = nX;
299 int nYy = nY;
300 int nXOffset = nXx;
301 int nYOffset = nYy;
302 int nCx1;
303 int nCy1;
304 wxSize vMaxSize = GetMaxButtonSize();
305 int nMaxWidth;
306 int nMaxHeight;
307 wxSize vTotSize;
308 int nTotWidth;
309 int nTotHeight;
310 int nStartX;
311 int nStartY;
312 wxFont vFont = GetFont();
313
314 m_nSizeFlags = nSizeFlags;
315 GetPosition( &nCurrentX
316 ,&nCurrentY
317 );
318 GetSize( &nWidthOld
319 ,&nHeightOld
320 );
321
322 if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
323 nXx = nCurrentX;
324 if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
325 nYy = nCurrentY;
326 if (nYy < 0)
327 nYy = 0;
328 if (nXx < 0)
329 nXx = 0;
330
331 wxGetCharSize( m_hWnd
332 ,&nCx1
333 ,&nCy1
334 ,&vFont
335 );
336
337 //
338 // Attempt to have a look coherent with other platforms: We compute the
339 // biggest toggle dim, then we align all items according this value.
340 //
341 vMaxSize = GetMaxButtonSize();
342 nMaxWidth = vMaxSize.x;
343 nMaxHeight = vMaxSize.y;
344
345 vTotSize = GetTotalButtonSize(vMaxSize);
346 nTotWidth = vTotSize.x;
347 nTotHeight = vTotSize.y;
348
349 //
350 // Only change our width/height if asked for
351 //
352 if (nWidth == -1)
353 {
354 if (nSizeFlags & wxSIZE_AUTO_WIDTH )
355 nWidth = nTotWidth;
356 else
357 nWidth = nWidthOld;
358 }
359
360 if (nHeight == -1)
361 {
362 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
363 nHeight = nTotHeight;
364 else
365 nHeight = nHeightOld;
366 }
367
368 //
369 // Now convert to OS/2 coordinate system
370 //
371 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
372 if (pParent)
373 nYy = GetOS2ParentHeight(pParent) - nYy - nHeight;
374 else
375 {
376 RECTL vRect;
377 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
378 nYy = vRect.yTop - nYy - nHeight;
379 }
380 nYOffset = nYy + nHeight;
381 ::WinSetWindowPos( GetHwnd()
382 ,HWND_TOP
383 ,(LONG)nXx
384 ,(LONG)nYy
385 ,(LONG)nWidth
386 ,(LONG)nHeight
387 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
388 );
389
390 //
391 // Now position all the buttons: the current button will be put at
392 // wxPoint(x_offset, y_offset) and the new row/column will start at
393 // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
394 // maxHeight) except for the buttons in the last column which should extend
395 // to the right border of radiobox and thus can be wider than this.
396 //
397 // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
398 // left to right order and m_majorDim is the number of columns while
399 // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
400 // m_majorDim is the number of rows.
401 //
402 nXOffset += nCx1;
403 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
404
405 nStartX = nXOffset;
406 nStartY = nYOffset;
407
408 for (unsigned int i = 0; i < m_nNoItems; i++)
409 {
410 //
411 // The last button in the row may be wider than the other ones as the
412 // radiobox may be wider than the sum of the button widths (as it
413 // happens, for example, when the radiobox label is very long)
414 //
415 bool bIsLastInTheRow;
416
417 if (m_windowStyle & wxRA_SPECIFY_COLS)
418 {
419 //
420 // Item is the last in its row if it is a multiple of the number of
421 // columns or if it is just the last item
422 //
423 int n = i + 1;
424
425 bIsLastInTheRow = ((n % GetMajorDim()) == 0) || (n == (int)m_nNoItems);
426 }
427 else // winRA_SPECIFY_ROWS
428 {
429 //
430 // Item is the last in the row if it is in the last columns
431 //
432 bIsLastInTheRow = i >= (m_nNoItems/GetMajorDim()) * GetMajorDim();
433 }
434
435 //
436 // Is this the start of new row/column?
437 //
438 if (i && (i % GetMajorDim() == 0))
439 {
440 if (m_windowStyle & wxRA_SPECIFY_ROWS)
441 {
442 //
443 // Start of new column
444 //
445 nYOffset = nStartY;
446 nXOffset += nMaxWidth + nCx1;
447 }
448 else // start of new row
449 {
450 nXOffset = nStartX;
451 nYOffset -= nMaxHeight;
452 if (m_pnRadioWidth[0] > 0L)
453 nYOffset -= nCy1/2;
454 }
455 }
456
457 int nWidthBtn;
458
459 if (bIsLastInTheRow)
460 {
461 //
462 // Make the button go to the end of radio box
463 //
464 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
465 if (nWidthBtn < nMaxWidth)
466 nWidthBtn = nMaxWidth;
467 }
468 else
469 {
470 //
471 // Normal button, always of the same size
472 //
473 nWidthBtn = nMaxWidth;
474 }
475
476 //
477 // Make all buttons of the same, maximal size - like this they
478 // cover the radiobox entirely and the radiobox tooltips are always
479 // shown (otherwise they are not when the mouse pointer is in the
480 // radiobox part not belonging to any radiobutton)
481 //
482 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
483 ,HWND_BOTTOM
484 ,(LONG)nXOffset
485 ,(LONG)nYOffset
486 ,(LONG)nWidthBtn
487 ,(LONG)nMaxHeight
488 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
489 );
490 //
491 // Where do we put the next button?
492 //
493 if (m_windowStyle & wxRA_SPECIFY_ROWS)
494 {
495 //
496 // Below this one
497 //
498 nYOffset -= nMaxHeight;
499 if (m_pnRadioWidth[0] > 0)
500 nYOffset -= nCy1/2;
501 }
502 else
503 {
504 //
505 // To the right of this one
506 //
507 nXOffset += nWidthBtn + nCx1;
508 }
509 }
510 } // end of wxRadioBox::DoSetSize
511
512 bool wxRadioBox::Enable(unsigned int nItem, bool bEnable)
513 {
514 wxCHECK_MSG( IsValid(nItem), false,
515 wxT("invalid item in wxRadioBox::Enable()") );
516
517 ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
518 return true;
519 } // end of wxRadioBox::Enable
520
521 bool wxRadioBox::Enable(bool bEnable)
522 {
523 if ( !wxControl::Enable(bEnable) )
524 return false;
525 for (unsigned int i = 0; i < m_nNoItems; i++)
526 ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
527 return true;
528 } // end of wxRadioBox::Enable
529
530 unsigned int wxRadioBox::GetCount() const
531 {
532 return m_nNoItems;
533 } // end of wxRadioBox::GetCount
534
535 wxString wxRadioBox::GetLabel(int nItem) const
536 {
537 wxCHECK_MSG( IsValid(nItem), wxEmptyString, wxT("invalid radiobox index") );
538
539 return wxGetWindowText(m_ahRadioButtons[nItem]);
540 } // end of wxRadioBox::GetLabel
541
542 wxSize wxRadioBox::GetMaxButtonSize() const
543 {
544 int nWidthMax = 0;
545 int nHeightMax = 0;
546
547 for (unsigned int i = 0 ; i < m_nNoItems; i++)
548 {
549 int nWidth;
550 int nHeight;
551
552 if (m_pnRadioWidth[i] < 0L)
553 {
554 GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
555 ,&nWidth
556 ,&nHeight
557 );
558
559 //
560 // Adjust the size to take into account the radio box itself
561 // FIXME this is totally bogus!
562 //
563 nWidth += RADIO_SIZE;
564 nHeight *= 3;
565 nHeight /= 2;
566 }
567 else
568 {
569 nWidth = m_pnRadioWidth[i];
570 nHeight = m_pnRadioHeight[i];
571 }
572 if (nWidthMax < nWidth )
573 nWidthMax = nWidth;
574 if (nHeightMax < nHeight )
575 nHeightMax = nHeight;
576 }
577 wxSize maxsize( nWidthMax, nHeightMax);
578 return maxsize;
579 } // end of wxRadioBox::GetMaxButtonSize
580
581 // Get single selection, for single choice list items
582 int wxRadioBox::GetSelection() const
583 {
584 return m_nSelectedButton;
585 } // end of wxRadioBox::GetSelection
586
587 void wxRadioBox::GetSize( int* pnWidth, int* pnHeight ) const
588 {
589 RECT vRect;
590
591 vRect.xLeft = -1;
592 vRect.xRight = -1;
593 vRect.yTop = -1;
594 vRect.yBottom = -1;
595
596 if (m_hWnd)
597 wxFindMaxSize( m_hWnd, &vRect );
598
599 for (unsigned int i = 0; i < m_nNoItems; i++)
600 wxFindMaxSize( m_ahRadioButtons[i], &vRect );
601
602 if (pnWidth)
603 *pnWidth = vRect.xRight - vRect.xLeft;
604 if (pnHeight)
605 *pnHeight = vRect.yTop - vRect.yBottom;
606 } // end of wxRadioBox::GetSize
607
608 // Find string for position
609 wxString wxRadioBox::GetString(unsigned int nNum) const
610 {
611 wxCHECK_MSG( IsValid(nNum), wxEmptyString, wxT("invalid radiobox index") );
612 return wxGetWindowText(m_ahRadioButtons[nNum]);
613 } // end of wxRadioBox::GetString
614
615 // For single selection items only
616 wxString wxRadioBox::GetStringSelection() const
617 {
618 wxString sResult;
619 int nSel = GetSelection();
620
621 if (nSel != wxNOT_FOUND)
622 sResult = GetString(nSel);
623
624 return sResult;
625 } // end of wxRadioBox::GetStringSelection
626
627 wxSize wxRadioBox::GetTotalButtonSize( const wxSize& rSizeBtn ) const
628 {
629 int nCx1;
630 int nCy1;
631 int nHeight;
632 int nWidth;
633 int nWidthLabel = 0;
634
635 nCx1 = GetCharWidth();
636 nCy1 = GetCharHeight();
637 nHeight = GetRowCount() * rSizeBtn.y + (2 * nCy1);
638 nWidth = GetColumnCount() * (rSizeBtn.x + nCx1) + nCx1;
639
640 //
641 // And also wide enough for its label
642 //
643 wxString sStr = wxGetWindowText(GetHwnd());
644 if (!sStr.empty())
645 {
646 GetTextExtent( sStr
647 ,&nWidthLabel
648 ,NULL
649 );
650 nWidthLabel += 2*nCx1;
651 }
652 if (nWidthLabel > nWidth)
653 nWidth = nWidthLabel;
654
655 wxSize total( nWidth, nHeight );
656 return total;
657 } // end of wxRadioBox::GetTotalButtonSize
658
659 WXHBRUSH wxRadioBox::OnCtlColor( WXHDC hwinDC,
660 WXHWND WXUNUSED(hWnd),
661 WXUINT WXUNUSED(uCtlColor),
662 WXUINT WXUNUSED(uMessage),
663 WXWPARAM WXUNUSED(wParam),
664 WXLPARAM WXUNUSED(lParam) )
665 {
666 HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
667
668 if (GetParent()->GetTransparentBackground())
669 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
670 else
671 ::GpiSetBackMix(hPS, BM_OVERPAINT);
672
673 wxColour vColBack = GetBackgroundColour();
674
675 ::GpiSetBackColor(hPS, vColBack.GetPixel());
676 ::GpiSetColor(hPS, vColBack.GetPixel());
677
678 wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID );
679 return ((WXHBRUSH)pBrush->GetResourceHandle());
680 } // end of wxRadioBox::OnCtlColor
681
682 bool wxRadioBox::OS2Command( WXUINT uCmd,
683 WXWORD wId)
684 {
685 int nSelectedButton = -1;
686
687 if (uCmd == BN_CLICKED)
688 {
689 if (wId == GetId())
690 return true;
691
692 for (unsigned int i = 0; i < m_nNoItems; i++)
693 {
694 if (wId == wxGetWindowId(m_ahRadioButtons[i]))
695 {
696 nSelectedButton = i;
697 break;
698 }
699 }
700 if (nSelectedButton == -1)
701 {
702 //
703 // Just ignore it
704 //
705 return false;
706 }
707 if (nSelectedButton != m_nSelectedButton)
708 {
709 m_nSelectedButton = nSelectedButton;
710 SendNotificationEvent();
711 }
712 return true;
713 }
714 else
715 return false;
716 } // end of wxRadioBox::OS2Command
717
718 void wxRadioBox::SendNotificationEvent()
719 {
720 wxCommandEvent vEvent(
721 wxEVT_RADIOBOX,
722 m_windowId
723 );
724
725 vEvent.SetInt( m_nSelectedButton );
726 vEvent.SetString( GetString(m_nSelectedButton) );
727 vEvent.SetEventObject(this);
728 ProcessCommand(vEvent);
729 } // end of wxRadioBox::SendNotificationEvent
730
731 void wxRadioBox::SetFocus()
732 {
733 if (m_nNoItems > 0)
734 {
735 if (m_nSelectedButton == -1)
736 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
737 else
738 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
739 }
740 } // end of wxRadioBox::SetFocus
741
742 bool wxRadioBox::SetFont(const wxFont& rFont)
743 {
744 if (!wxControl::SetFont(rFont))
745 {
746 //
747 // Nothing to do
748 //
749 return false;
750 }
751 //
752 // Also set the font of our radio buttons
753 //
754 for (unsigned int n = 0; n < m_nNoItems; n++)
755 {
756 HWND hWndBtn = (HWND)m_ahRadioButtons[n];
757
758 wxOS2SetFont( hWndBtn, rFont );
759 ::WinInvalidateRect(hWndBtn, NULL, FALSE);
760 }
761 return true;
762 } // end of wxRadioBox::SetFont
763
764 void wxRadioBox::SetSelection(
765 int nNum
766 )
767 {
768 wxCHECK_RET( IsValid(nNum), wxT("invalid radiobox index") );
769
770 if ( IsValid(m_nSelectedButton) )
771 ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
772
773 ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
774 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
775 m_nSelectedButton = nNum;
776 } // end of wxRadioBox::SetSelection
777
778 void wxRadioBox::SetString(unsigned int nItem, const wxString& rsLabel)
779 {
780 wxCHECK_RET( IsValid(nItem), wxT("invalid radiobox index") );
781
782 m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
783 ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], rsLabel.c_str());
784 } // end of wxRadioBox::SetString
785
786 bool wxRadioBox::SetStringSelection(const wxString& rsStr)
787 {
788 int nSel = FindString(rsStr);
789
790 if (nSel > -1)
791 {
792 SetSelection(nSel);
793 return true;
794 }
795 else
796 return false;
797 } // end of wxRadioBox::SetStringSelection
798
799 bool wxRadioBox::Show(bool bShow)
800 {
801 if (!wxControl::Show(bShow))
802 return false;
803
804 for (unsigned int i = 0; i < m_nNoItems; i++)
805 {
806 ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
807 }
808 return true;
809 } // end of wxRadioBox::Show
810
811 // Show a specific button
812 bool wxRadioBox::Show(unsigned int nItem, bool bShow)
813 {
814 wxCHECK_MSG( IsValid(nItem), false,
815 wxT("invalid item in wxRadioBox::Show()") );
816
817 ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
818
819 return true;
820 } // end of wxRadioBox::Show
821
822 void wxRadioBox::SubclassRadioButton(
823 WXHWND hWndBtn
824 )
825 {
826 fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
827 } // end of wxRadioBox::SubclassRadioButton
828
829 MRESULT wxRadioBox::WindowProc(
830 WXUINT uMsg
831 , WXWPARAM wParam
832 , WXLPARAM lParam
833 )
834 {
835 return (wxControl::OS2WindowProc( uMsg
836 ,wParam
837 ,lParam
838 ));
839 } // end of wxRadioBox::WindowProc
840
841 // ---------------------------------------------------------------------------
842 // window proc for radio buttons
843 // ---------------------------------------------------------------------------
844
845 MRESULT wxRadioBtnWndProc(
846 HWND hWnd
847 , UINT uMessage
848 , MPARAM wParam
849 , MPARAM lParam
850 )
851 {
852 switch (uMessage)
853 {
854 case WM_CHAR:
855 {
856 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
857
858 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
859 {
860 if (uKeyFlags & KC_VIRTUALKEY)
861 {
862 wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
863 ,QWL_USER
864 );
865 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
866 bool bProcessed = true;
867 wxDirection eDir;
868
869 switch(uVk)
870 {
871 case VK_LEFT:
872 eDir = wxLEFT;
873 break;
874
875 case VK_RIGHT:
876 eDir = wxRIGHT;
877 break;
878
879 case VK_DOWN:
880 eDir = wxDOWN;
881 break;
882
883 case VK_UP:
884 eDir = wxUP;
885 break;
886
887 default:
888 bProcessed = false;
889
890 //
891 // Just to suppress the compiler warning
892 //
893 eDir = wxALL;
894 }
895
896 if (bProcessed)
897 {
898 int nSelOld = pRadiobox->GetSelection();
899 int nSelNew = pRadiobox->GetNextItem( nSelOld
900 ,eDir
901 ,pRadiobox->GetWindowStyleFlag()
902 );
903
904 if (nSelNew != nSelOld)
905 {
906 pRadiobox->SetSelection(nSelNew);
907
908 //
909 // Emulate the button click
910 //
911 pRadiobox->SendNotificationEvent();
912 return 0;
913 }
914 }
915 }
916 }
917 }
918 break;
919 }
920
921 return fnWndProcRadioBtn( hWnd
922 ,(ULONG)uMessage
923 ,(MPARAM)wParam
924 ,(MPARAM)lParam
925 );
926 } // end of wxRadioBtnWndProc
927
928 MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd,
929 UINT uMessage,
930 MPARAM wParam,
931 MPARAM lParam )
932 {
933 return (fnWndProcRadioBox( hWnd,
934 (ULONG)uMessage,
935 (MPARAM)wParam,
936 (MPARAM)lParam )
937 );
938 } // end of wxRadioBoxWndProc
939
940 #endif // wxUSE_RADIOBOX