wxItemContainerImmutable::FindString unified.
[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 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #ifndef WX_PRECOMP
16 #include <stdio.h>
17 #include "wx/setup.h"
18 #include "wx/wxchar.h"
19 #include "wx/string.h"
20 #include "wx/bitmap.h"
21 #include "wx/brush.h"
22 #include "wx/radiobox.h"
23 #endif
24
25 #include "wx/os2/private.h"
26
27 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
28
29 // ---------------------------------------------------------------------------
30 // private functions
31 // ---------------------------------------------------------------------------
32
33 // wnd proc for radio buttons
34 MRESULT EXPENTRY wxRadioBtnWndProc( HWND hWnd
35 ,UINT uMessage
36 ,MPARAM wParam
37 ,MPARAM lParam
38 );
39 MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd
40 ,UINT uMessage
41 ,MPARAM wParam
42 ,MPARAM lParam
43 );
44
45 // ---------------------------------------------------------------------------
46 // global vars
47 // ---------------------------------------------------------------------------
48
49 // the pointer to standard radio button wnd proc
50 extern void wxAssociateWinWithHandle( HWND hWnd
51 ,wxWindowOS2* pWin
52 );
53 static WXFARPROC fnWndProcRadioBtn = NULL;
54 static WXFARPROC fnWndProcRadioBox = NULL;
55
56 // ===========================================================================
57 // implementation
58 // ===========================================================================
59
60 // ---------------------------------------------------------------------------
61 // wxRadioBox
62 // ---------------------------------------------------------------------------
63
64 // Radio box item
65 wxRadioBox::wxRadioBox()
66 {
67 m_nSelectedButton = -1;
68 m_nNoItems = 0;
69 m_nNoRowsOrCols = 0;
70 m_ahRadioButtons = NULL;
71 m_nMajorDim = 0;
72 m_pnRadioWidth = NULL;
73 m_pnRadioHeight = NULL;
74 } // end of wxRadioBox::wxRadioBox
75
76 wxRadioBox::~wxRadioBox()
77 {
78 m_isBeingDeleted = true;
79
80 if (m_ahRadioButtons)
81 {
82 int i;
83 for (i = 0; i < m_nNoItems; i++)
84 ::WinDestroyWindow((HWND)m_ahRadioButtons[i]);
85 delete[] m_ahRadioButtons;
86 }
87 if (m_pnRadioWidth)
88 delete[] m_pnRadioWidth;
89 if (m_pnRadioHeight)
90 delete[] m_pnRadioHeight;
91 } // end of wxRadioBox::~wxRadioBox
92
93 void wxRadioBox::AdjustButtons( int nX,
94 int nY,
95 int nWidth,
96 int nHeight,
97 int WXUNUSED(nSizeFlags) )
98 {
99 wxSize vMaxSize;
100 int nXOffset = nX;
101 int nYOffset = nY + nHeight;
102 int nCx1;
103 int nCy1;
104 int nStartX;
105 int nStartY;
106 int nMaxWidth;
107 int nMaxHeight;
108 wxFont vFont = GetFont();
109
110 wxGetCharSize( m_hWnd
111 ,&nCx1
112 ,&nCy1
113 ,&vFont
114 );
115 vMaxSize = GetMaxButtonSize();
116 nMaxWidth = vMaxSize.x;
117 nMaxHeight = vMaxSize.y;
118
119 nXOffset += nCx1;
120 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
121
122 nStartX = nXOffset;
123 nStartY = nYOffset;
124
125 for (int i = 0; i < m_nNoItems; i++)
126 {
127 //
128 // The last button in the row may be wider than the other ones as the
129 // radiobox may be wider than the sum of the button widths (as it
130 // happens, for example, when the radiobox label is very long)
131 //
132 bool bIsLastInTheRow;
133
134 if (m_windowStyle & wxRA_SPECIFY_COLS)
135 {
136 //
137 // Item is the last in its row if it is a multiple of the number of
138 // columns or if it is just the last item
139 //
140 int n = i + 1;
141
142 bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
143 }
144 else // winRA_SPECIFY_ROWS
145 {
146 //
147 // Item is the last in the row if it is in the last columns
148 //
149 bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
150 }
151
152 //
153 // Is this the start of new row/column?
154 //
155 if (i && (i % m_nMajorDim == 0))
156 {
157 if (m_windowStyle & wxRA_SPECIFY_ROWS)
158 {
159
160 //
161 // Start of new column
162 //
163 nYOffset = nStartY;
164 nXOffset += nMaxWidth + nCx1;
165 }
166 else // start of new row
167 {
168 nXOffset = nStartX;
169 nYOffset -= nMaxHeight;
170 if (m_pnRadioWidth[0] > 0L)
171 nYOffset -= nCy1/2;
172 }
173 }
174
175 int nWidthBtn;
176
177 if (bIsLastInTheRow)
178 {
179 //
180 // Make the button go to the end of radio box
181 //
182 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
183 if (nWidthBtn < nMaxWidth)
184 nWidthBtn = nMaxWidth;
185 }
186 else
187 {
188 //
189 // Normal button, always of the same size
190 //
191 nWidthBtn = nMaxWidth;
192 }
193
194 //
195 // Make all buttons of the same, maximal size - like this they
196 // cover the radiobox entirely and the radiobox tooltips are always
197 // shown (otherwise they are not when the mouse pointer is in the
198 // radiobox part not beYInt32ing to any radiobutton)
199 //
200 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
201 ,HWND_TOP
202 ,(LONG)nXOffset
203 ,(LONG)nYOffset
204 ,(LONG)nWidthBtn
205 ,(LONG)nMaxHeight
206 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
207 );
208 //
209 // Where do we put the next button?
210 //
211 if (m_windowStyle & wxRA_SPECIFY_ROWS)
212 {
213 //
214 // Below this one
215 //
216 nYOffset -= nMaxHeight;
217 if (m_pnRadioWidth[0] > 0)
218 nYOffset -= nCy1/2;
219 }
220 else
221 {
222 //
223 // To the right of this one
224 //
225 nXOffset += nWidthBtn + nCx1;
226 }
227 }
228 } // end of wxRadioBox::AdjustButtons
229
230 void wxRadioBox::Command (
231 wxCommandEvent& rEvent
232 )
233 {
234 SetSelection (rEvent.GetInt());
235 ProcessCommand(rEvent);
236 } // end of wxRadioBox::Command
237
238 bool wxRadioBox::ContainsHWND(
239 WXHWND hWnd
240 ) const
241 {
242 size_t nCount = GetCount();
243 size_t i;
244
245 for (i = 0; i < nCount; i++)
246 {
247 if (GetRadioButtons()[i] == hWnd)
248 return true;
249 }
250 return false;
251 } // end of wxRadioBox::ContainsHWND
252
253 bool wxRadioBox::Create(
254 wxWindow* pParent
255 , wxWindowID vId
256 , const wxString& rsTitle
257 , const wxPoint& rPos
258 , const wxSize& rSize
259 , const wxArrayString& asChoices
260 , int nMajorDim
261 , long lStyle
262 , const wxValidator& rVal
263 , const wxString& rsName
264 )
265 {
266 wxCArrayString chs(asChoices);
267
268 return Create(pParent, vId, rsTitle, rPos, rSize, chs.GetCount(),
269 chs.GetStrings(), nMajorDim, lStyle, rVal, rsName);
270 }
271
272 bool wxRadioBox::Create(
273 wxWindow* pParent
274 , wxWindowID vId
275 , const wxString& rsTitle
276 , const wxPoint& rPos
277 , const wxSize& rSize
278 , int nNum
279 , const wxString asChoices[]
280 , int nMajorDim
281 , long lStyle
282 , const wxValidator& rVal
283 , const wxString& rsName
284 )
285 {
286 wxColour vColour;
287 LONG lColor;
288
289 vColour.Set(wxString(wxT("BLACK")));
290 m_backgroundColour = pParent->GetBackgroundColour();
291 m_nSelectedButton = -1;
292 m_nNoItems = 0;
293
294 m_nMajorDim = nMajorDim == 0 ? nNum : nMajorDim;
295 m_nNoRowsOrCols = nMajorDim;
296
297 //
298 // Common initialization
299 //
300 if (!CreateControl( pParent
301 ,vId
302 ,rPos
303 ,rSize
304 ,lStyle
305 ,rVal
306 ,rsName
307 ))
308 return false;
309 if (!OS2CreateControl( wxT("STATIC")
310 ,SS_GROUPBOX
311 ,rPos
312 ,rSize
313 ,rsTitle
314 ))
315 return false;
316
317 wxAssociateWinWithHandle(m_hWnd, this);
318
319 //
320 // Some radio boxes test consecutive id.
321 //
322 m_nNoItems = nNum;
323 (void)NewControlId();
324 m_ahRadioButtons = new WXHWND[nNum];
325 m_pnRadioWidth = new int[nNum];
326 m_pnRadioHeight = new int[nNum];
327
328 for (int i = 0; i < nNum; i++)
329 {
330 m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
331
332 long lStyleBtn = BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE;
333 int nNewId = NewControlId();
334
335 if (i == 0 && lStyle == 0)
336 lStyleBtn |= WS_GROUP;
337
338 HWND hWndBtn = (WXHWND)::WinCreateWindow ( GetHwndOf(pParent)
339 ,WC_BUTTON
340 ,(PSZ)asChoices[i].c_str()
341 ,lStyleBtn
342 ,0, 0, 0, 0
343 ,GetWinHwnd(pParent)
344 ,HWND_TOP
345 ,(HMENU)nNewId
346 ,NULL
347 ,NULL
348 );
349 lColor = (LONG)vColour.GetPixel();
350 ::WinSetPresParam( hWndBtn
351 ,PP_FOREGROUNDCOLOR
352 ,sizeof(LONG)
353 ,(PVOID)&lColor
354 );
355 lColor = (LONG)m_backgroundColour.GetPixel();
356
357 ::WinSetPresParam( hWndBtn
358 ,PP_BACKGROUNDCOLOR
359 ,sizeof(LONG)
360 ,(PVOID)&lColor
361 );
362 if (!hWndBtn)
363 {
364 return false;
365 }
366 m_ahRadioButtons[i] = (WXHWND)hWndBtn;
367 SubclassRadioButton((WXHWND)hWndBtn);
368 wxAssociateWinWithHandle(hWndBtn, this);
369 wxOS2SetFont( hWndBtn
370 ,*wxSMALL_FONT
371 );
372 ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
373 m_aSubControls.Add(nNewId);
374 }
375
376 //
377 // Create a dummy radio control to end the group.
378 //
379 (void)::WinCreateWindow ( GetHwndOf(pParent)
380 ,WC_BUTTON
381 ,""
382 ,WS_GROUP | BS_AUTORADIOBUTTON
383 ,0, 0, 0, 0
384 ,GetWinHwnd(pParent)
385 ,HWND_TOP
386 ,(HMENU)NewControlId()
387 ,NULL
388 ,NULL
389 );
390 SetFont(*wxSMALL_FONT);
391 fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
392 ,(PFNWP)wxRadioBoxWndProc
393 );
394 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
395 lColor = (LONG)vColour.GetPixel();
396 ::WinSetPresParam( m_hWnd
397 ,PP_FOREGROUNDCOLOR
398 ,sizeof(LONG)
399 ,(PVOID)&lColor
400 );
401 ::WinSetPresParam( m_hWnd
402 ,PP_BORDERDARKCOLOR
403 ,sizeof(LONG)
404 ,(PVOID)&lColor
405 );
406 lColor = (LONG)m_backgroundColour.GetPixel();
407
408 ::WinSetPresParam( m_hWnd
409 ,PP_BACKGROUNDCOLOR
410 ,sizeof(LONG)
411 ,(PVOID)&lColor
412 );
413 ::WinSetPresParam( m_hWnd
414 ,PP_BORDERLIGHTCOLOR
415 ,sizeof(LONG)
416 ,(PVOID)&lColor
417 );
418 SetXComp(0);
419 SetYComp(0);
420 SetSelection(0);
421 SetSize( rPos.x
422 ,rPos.y
423 ,rSize.x
424 ,rSize.y
425 );
426 return true;
427 } // end of wxRadioBox::Create
428
429 wxSize wxRadioBox::DoGetBestSize() const
430 {
431 return (GetTotalButtonSize(GetMaxButtonSize()));
432 } // end of WinGuiBase_CRadioBox::DoGetBestSize
433
434 void wxRadioBox::DoSetSize(
435 int nX
436 , int nY
437 , int nWidth
438 , int nHeight
439 , int nSizeFlags
440 )
441 {
442 int nCurrentX;
443 int nCurrentY;
444 int nWidthOld;
445 int nHeightOld;
446 int nXx = nX;
447 int nYy = nY;
448 #if RADIOBTN_PARENT_IS_RADIOBOX
449 int nXOffset = 0;
450 int nYOffset = 0;
451 #else
452 int nXOffset = nXx;
453 int nYOffset = nYy;
454 #endif
455 int nCx1;
456 int nCy1;
457 wxSize vMaxSize = GetMaxButtonSize();
458 int nMaxWidth;
459 int nMaxHeight;
460 wxSize vTotSize;
461 int nTotWidth;
462 int nTotHeight;
463 int nStartX;
464 int nStartY;
465 wxFont vFont = GetFont();
466
467 m_nSizeFlags = nSizeFlags;
468 GetPosition( &nCurrentX
469 ,&nCurrentY
470 );
471 GetSize( &nWidthOld
472 ,&nHeightOld
473 );
474
475 if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
476 nXx = nCurrentX;
477 if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
478 nYy = nCurrentY;
479 if (nYy < 0)
480 nYy = 0;
481 if (nXx < 0)
482 nXx = 0;
483
484 wxGetCharSize( m_hWnd
485 ,&nCx1
486 ,&nCy1
487 ,&vFont
488 );
489
490 //
491 // Attempt to have a look coherent with other platforms: We compute the
492 // biggest toggle dim, then we align all items according this value.
493 //
494 vMaxSize = GetMaxButtonSize();
495 nMaxWidth = vMaxSize.x;
496 nMaxHeight = vMaxSize.y;
497
498 vTotSize = GetTotalButtonSize(vMaxSize);
499 nTotWidth = vTotSize.x;
500 nTotHeight = vTotSize.y;
501
502 //
503 // Only change our width/height if asked for
504 //
505 if (nWidth == -1)
506 {
507 if (nSizeFlags & wxSIZE_AUTO_WIDTH )
508 nWidth = nTotWidth;
509 else
510 nWidth = nWidthOld;
511 }
512
513 if (nHeight == -1)
514 {
515 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
516 nHeight = nTotHeight;
517 else
518 nHeight = nHeightOld;
519 }
520
521 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
522
523 if (pParent)
524 {
525 int nOS2Height = GetOS2ParentHeight(pParent);
526
527 nYy = nOS2Height - (nYy + nHeight);
528 nYOffset = nYy + nHeight;
529 }
530 else
531 {
532 RECTL vRect;
533
534 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
535 nYy = vRect.yTop - (nYy + nHeight);
536 }
537 ::WinSetWindowPos( GetHwnd()
538 ,HWND_TOP
539 ,(LONG)nXx
540 ,(LONG)nYy
541 ,(LONG)nWidth
542 ,(LONG)nHeight
543 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
544 );
545
546 //
547 // Now position all the buttons: the current button will be put at
548 // wxPoint(x_offset, y_offset) and the new row/column will start at
549 // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
550 // maxHeight) except for the buttons in the last column which should extend
551 // to the right border of radiobox and thus can be wider than this.
552 //
553 // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
554 // left to right order and m_majorDim is the number of columns while
555 // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
556 // m_majorDim is the number of rows.
557 //
558 nXOffset += nCx1;
559 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
560
561 nStartX = nXOffset;
562 nStartY = nYOffset;
563
564 for (int i = 0; i < m_nNoItems; i++)
565 {
566 //
567 // The last button in the row may be wider than the other ones as the
568 // radiobox may be wider than the sum of the button widths (as it
569 // happens, for example, when the radiobox label is very long)
570 //
571 bool bIsLastInTheRow;
572
573 if (m_windowStyle & wxRA_SPECIFY_COLS)
574 {
575 //
576 // Item is the last in its row if it is a multiple of the number of
577 // columns or if it is just the last item
578 //
579 int n = i + 1;
580
581 bIsLastInTheRow = ((n % m_nMajorDim) == 0) || (n == m_nNoItems);
582 }
583 else // winRA_SPECIFY_ROWS
584 {
585 //
586 // Item is the last in the row if it is in the last columns
587 //
588 bIsLastInTheRow = i >= (m_nNoItems/m_nMajorDim) * m_nMajorDim;
589 }
590
591 //
592 // Is this the start of new row/column?
593 //
594 if (i && (i % m_nMajorDim == 0))
595 {
596 if (m_windowStyle & wxRA_SPECIFY_ROWS)
597 {
598
599 //
600 // Start of new column
601 //
602 nYOffset = nStartY;
603 nXOffset += nMaxWidth + nCx1;
604 }
605 else // start of new row
606 {
607 nXOffset = nStartX;
608 nYOffset -= nMaxHeight;
609 if (m_pnRadioWidth[0] > 0L)
610 nYOffset -= nCy1/2;
611 }
612 }
613
614 int nWidthBtn;
615
616 if (bIsLastInTheRow)
617 {
618 //
619 // Make the button go to the end of radio box
620 //
621 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
622 if (nWidthBtn < nMaxWidth)
623 nWidthBtn = nMaxWidth;
624 }
625 else
626 {
627 //
628 // Normal button, always of the same size
629 //
630 nWidthBtn = nMaxWidth;
631 }
632
633 //
634 // Make all buttons of the same, maximal size - like this they
635 // cover the radiobox entirely and the radiobox tooltips are always
636 // shown (otherwise they are not when the mouse pointer is in the
637 // radiobox part not beinting to any radiobutton)
638 //
639 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
640 ,HWND_TOP
641 ,(LONG)nXOffset
642 ,(LONG)nYOffset
643 ,(LONG)nWidthBtn
644 ,(LONG)nMaxHeight
645 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
646 );
647 //
648 // Where do we put the next button?
649 //
650 if (m_windowStyle & wxRA_SPECIFY_ROWS)
651 {
652 //
653 // Below this one
654 //
655 nYOffset -= nMaxHeight;
656 if (m_pnRadioWidth[0] > 0)
657 nYOffset -= nCy1/2;
658 }
659 else
660 {
661 //
662 // To the right of this one
663 //
664 nXOffset += nWidthBtn + nCx1;
665 }
666 }
667 } // end of wxRadioBox::DoSetSize
668
669 bool wxRadioBox::Enable(int nItem, bool bEnable)
670 {
671 wxCHECK_MSG( IsValid(nItem), false,
672 wxT("invalid item in wxRadioBox::Enable()") );
673
674 ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
675 return true;
676 } // end of wxRadioBox::Enable
677
678 bool wxRadioBox::Enable(
679 bool bEnable
680 )
681 {
682 if ( !wxControl::Enable(bEnable) )
683 return false;
684 for (int i = 0; i < m_nNoItems; i++)
685 ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
686 return true;
687 } // end of wxRadioBox::Enable
688
689 int wxRadioBox::GetColumnCount() const
690 {
691 return GetNumHor();
692 } // end of wxRadioBox::GetColumnCount
693
694 int wxRadioBox::GetCount() const
695 {
696 return m_nNoItems;
697 } // end of wxRadioBox::GetCount
698
699 wxString wxRadioBox::GetLabel(int nItem) const
700 {
701 wxCHECK_MSG( IsValid(nItem), wxEmptyString, wxT("invalid radiobox index") );
702
703 return wxGetWindowText(m_ahRadioButtons[nItem]);
704 } // end of wxRadioBox::GetLabel
705
706 wxSize wxRadioBox::GetMaxButtonSize() const
707 {
708 int nWidthMax = 0;
709 int nHeightMax = 0;
710
711 for (int i = 0 ; i < m_nNoItems; i++)
712 {
713 int nWidth;
714 int nHeight;
715
716 if (m_pnRadioWidth[i] < 0L)
717 {
718 GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
719 ,&nWidth
720 ,&nHeight
721 );
722
723 //
724 // Adjust the size to take into account the radio box itself
725 // FIXME this is totally bogus!
726 //
727 nWidth += RADIO_SIZE;
728 nHeight *= 3;
729 nHeight /= 2;
730 }
731 else
732 {
733 nWidth = m_pnRadioWidth[i];
734 nHeight = m_pnRadioHeight[i];
735 }
736 if (nWidthMax < nWidth )
737 nWidthMax = nWidth;
738 if (nHeightMax < nHeight )
739 nHeightMax = nHeight;
740 }
741 wxSize maxsize( nWidthMax, nHeightMax);
742 return maxsize;
743 } // end of wxRadioBox::GetMaxButtonSize
744
745 int wxRadioBox::GetNumHor() const
746 {
747 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
748 {
749 return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
750 }
751 else
752 {
753 return m_nMajorDim;
754 }
755 } // end of wxRadioBox::GetNumHor
756
757 int wxRadioBox::GetNumVer() const
758 {
759 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
760 {
761 return m_nMajorDim;
762 }
763 else
764 {
765 return (m_nNoItems + m_nMajorDim - 1)/m_nMajorDim;
766 }
767 } // end of wxRadioBox::GetNumVer
768
769 void wxRadioBox::GetPosition( int* pnX,
770 int* WXUNUSED(pnY) ) const
771 {
772 wxWindowOS2* pParent = GetParent();
773 RECT vRect = { -1, -1, -1, -1 };
774 POINTL vPoint;
775 int i;
776
777 for (i = 0; i < m_nNoItems; i++)
778 wxFindMaxSize( m_ahRadioButtons[i]
779 ,&vRect
780 );
781 if (m_hWnd)
782 wxFindMaxSize( m_hWnd
783 ,&vRect
784 );
785
786 //
787 // Since we now have the absolute screen coords, if there's a parent we
788 // must subtract its top left corner
789 //
790 vPoint.x = vRect.xLeft;
791 vPoint.y = vRect.yTop;
792 if (pParent)
793 {
794 SWP vSwp;
795
796 ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
797 vPoint.x = vSwp.x;
798 vPoint.y = vSwp.y;
799 }
800
801 //
802 // We may be faking the client origin. So a window that's really at (0, 30)
803 // may appear (to wxWin apps) to be at (0, 0).
804 //
805 if (GetParent())
806 {
807 wxPoint vPt(GetParent()->GetClientAreaOrigin());
808
809 vPoint.x = vPt.x;
810 vPoint.y = vPt.y;
811 }
812 *pnX = vPoint.x;
813 *pnX = vPoint.y;
814 } // end of wxRadioBox::GetPosition
815
816 int wxRadioBox::GetRowCount() const
817 {
818 return GetNumVer();
819 } // end of wxRadioBox::GetRowCount
820
821 // Get single selection, for single choice list items
822 int wxRadioBox::GetSelection() const
823 {
824 return m_nSelectedButton;
825 } // end of wxRadioBox::GetSelection
826
827 void wxRadioBox::GetSize(
828 int* pnWidth
829 , int* pnHeight
830 ) const
831 {
832 RECT vRect;
833 int i;
834
835 vRect.xLeft = -1;
836 vRect.xRight = -1;
837 vRect.yTop = -1;
838 vRect.yBottom = -1;
839
840 if (m_hWnd)
841 wxFindMaxSize( m_hWnd
842 ,&vRect
843 );
844
845 for (i = 0; i < m_nNoItems; i++)
846 wxFindMaxSize( m_ahRadioButtons[i]
847 ,&vRect
848 );
849
850 if (pnWidth)
851 *pnWidth = vRect.xRight - vRect.xLeft;
852 if (pnHeight)
853 *pnHeight = vRect.yTop - vRect.yBottom;
854 } // end of wxRadioBox::GetSize
855
856 // Find string for position
857 wxString wxRadioBox::GetString(
858 int nNum
859 ) const
860 {
861 return wxGetWindowText(m_ahRadioButtons[nNum]);
862 } // end of wxRadioBox::GetString
863
864 // For single selection items only
865 wxString wxRadioBox::GetStringSelection() const
866 {
867 wxString sResult;
868 int nSel = GetSelection();
869
870 if (nSel > -1)
871 sResult = GetString(nSel);
872 return sResult;
873 } // end of wxRadioBox::GetStringSelection
874
875 wxSize wxRadioBox::GetTotalButtonSize( const wxSize& rSizeBtn ) const
876 {
877 int nCx1;
878 int nCy1;
879 int nExtraHeight;
880 int nHeight;
881 int nWidth;
882 int nWidthLabel;
883 wxFont vFont = GetFont();
884
885 wxGetCharSize( m_hWnd, &nCx1, &nCy1, &vFont );
886 nExtraHeight = nCy1;
887
888 nHeight = GetNumVer() * rSizeBtn.y + (2 * nCy1);
889 nWidth = GetNumHor() * (rSizeBtn.x + nCx1) + nCx1;
890
891 //
892 // And also wide enough for its label
893 //
894 GetTextExtent( GetTitle()
895 ,&nWidthLabel
896 ,NULL
897 );
898 nWidthLabel += RADIO_SIZE;
899 if (nWidthLabel > nWidth)
900 nWidth = nWidthLabel;
901
902 wxSize total( nWidth, nHeight );
903 return total;
904 } // end of wxRadioBox::GetTotalButtonSize
905
906 WXHBRUSH wxRadioBox::OnCtlColor( WXHDC hwinDC,
907 WXHWND WXUNUSED(hWnd),
908 WXUINT WXUNUSED(uCtlColor),
909 WXUINT WXUNUSED(uMessage),
910 WXWPARAM WXUNUSED(wParam),
911 WXLPARAM WXUNUSED(lParam) )
912 {
913 HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
914
915 if (GetParent()->GetTransparentBackground())
916 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
917 else
918 ::GpiSetBackMix(hPS, BM_OVERPAINT);
919
920 wxColour vColBack = GetBackgroundColour();
921
922 ::GpiSetBackColor(hPS, vColBack.GetPixel());
923 ::GpiSetColor(hPS, vColBack.GetPixel());
924
925 wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID );
926 return ((WXHBRUSH)pBrush->GetResourceHandle());
927 } // end of wxRadioBox::OnCtlColor
928
929 bool wxRadioBox::OS2Command( WXUINT uCmd,
930 WXWORD wId)
931 {
932 int nSelectedButton = -1;
933
934 if (uCmd == BN_CLICKED)
935 {
936 if (wId == GetId())
937 return true;
938
939
940 for (int i = 0; i < m_nNoItems; i++)
941 {
942 if (wId == wxGetWindowId(m_ahRadioButtons[i]))
943 {
944 nSelectedButton = i;
945 break;
946 }
947 }
948 if (nSelectedButton == -1)
949 {
950 //
951 // Just ignore it
952 //
953 return false;
954 }
955 if (nSelectedButton != m_nSelectedButton)
956 {
957 m_nSelectedButton = nSelectedButton;
958 SendNotificationEvent();
959 }
960 return true;
961 }
962 else
963 return false;
964 } // end of wxRadioBox::OS2Command
965
966 void wxRadioBox::SendNotificationEvent()
967 {
968 wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
969 ,m_windowId
970 );
971
972 vEvent.SetInt( m_nSelectedButton );
973 vEvent.SetString( GetString(m_nSelectedButton) );
974 vEvent.SetEventObject(this);
975 ProcessCommand(vEvent);
976 } // end of wxRadioBox::SendNotificationEvent
977
978 void wxRadioBox::SetFocus()
979 {
980 if (m_nNoItems > 0)
981 {
982 if (m_nSelectedButton == -1)
983 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
984 else
985 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
986 }
987 } // end of wxRadioBox::SetFocus
988
989 bool wxRadioBox::SetFont(
990 const wxFont& rFont
991 )
992 {
993 if (!wxControl::SetFont(rFont))
994 {
995 //
996 // Nothing to do
997 //
998 return false;
999 }
1000 //
1001 // Also set the font of our radio buttons
1002 //
1003 for (int n = 0; n < (int)m_nNoItems; n++)
1004 {
1005 HWND hWndBtn = (HWND)m_ahRadioButtons[n];
1006
1007 wxOS2SetFont( hWndBtn
1008 ,rFont
1009 );
1010 ::WinInvalidateRect(hWndBtn, NULL, FALSE);
1011 }
1012 return true;
1013 } // end of wxRadioBox::SetFont
1014
1015 void wxRadioBox::SetSelection(
1016 int nNum
1017 )
1018 {
1019 wxCHECK_RET( IsValid(nNum), wxT("invalid radiobox index") );
1020
1021 if ( IsValid(m_nSelectedButton) )
1022 ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
1023
1024 ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
1025 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
1026 m_nSelectedButton = nNum;
1027 } // end of wxRadioBox::SetSelection
1028
1029 void wxRadioBox::SetString(
1030 int nItem
1031 , const wxString& rsLabel
1032 )
1033 {
1034 wxCHECK_RET( IsValid(nItem), wxT("invalid radiobox index") );
1035
1036 m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
1037 ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], (PSZ)rsLabel.c_str());
1038 } // end of wxRadioBox::SetString
1039
1040 bool wxRadioBox::SetStringSelection(const wxString& rsStr)
1041 {
1042 int nSel = FindString(rsStr);
1043
1044 if (nSel > -1)
1045 {
1046 SetSelection(nSel);
1047 return true;
1048 }
1049 else
1050 return false;
1051 } // end of wxRadioBox::SetStringSelection
1052
1053 bool wxRadioBox::Show(
1054 bool bShow
1055 )
1056 {
1057 if (!wxControl::Show(bShow))
1058 return false;
1059
1060 for (int i = 0; i < m_nNoItems; i++)
1061 {
1062 ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
1063 }
1064 return true;
1065 } // end of wxRadioBox::Show
1066
1067 // Show a specific button
1068 bool wxRadioBox::Show(
1069 int nItem
1070 , bool bShow
1071 )
1072 {
1073 wxCHECK_MSG( IsValid(nItem), false,
1074 wxT("invalid item in wxRadioBox::Show()") );
1075
1076 ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
1077
1078 return true;
1079 } // end of wxRadioBox::Show
1080
1081 void wxRadioBox::SubclassRadioButton(
1082 WXHWND hWndBtn
1083 )
1084 {
1085 fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
1086 } // end of wxRadioBox::SubclassRadioButton
1087
1088 MRESULT wxRadioBox::WindowProc(
1089 WXUINT uMsg
1090 , WXWPARAM wParam
1091 , WXLPARAM lParam
1092 )
1093 {
1094 return (wxControl::OS2WindowProc( uMsg
1095 ,wParam
1096 ,lParam
1097 ));
1098 } // end of wxRadioBox::WindowProc
1099
1100 // ---------------------------------------------------------------------------
1101 // window proc for radio buttons
1102 // ---------------------------------------------------------------------------
1103
1104 MRESULT wxRadioBtnWndProc(
1105 HWND hWnd
1106 , UINT uMessage
1107 , MPARAM wParam
1108 , MPARAM lParam
1109 )
1110 {
1111 switch (uMessage)
1112 {
1113 case WM_CHAR:
1114 {
1115 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
1116
1117 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
1118 {
1119 if (uKeyFlags & KC_VIRTUALKEY)
1120 {
1121 wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
1122 ,QWL_USER
1123 );
1124 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
1125 bool bProcessed = true;
1126 wxDirection eDir;
1127
1128 switch(uVk)
1129 {
1130 case VK_LEFT:
1131 eDir = wxDOWN;
1132 break;
1133
1134 case VK_RIGHT:
1135 eDir = wxDOWN;
1136 break;
1137
1138 case VK_DOWN:
1139 eDir = wxDOWN;
1140 break;
1141
1142 case VK_UP:
1143 eDir = wxUP;
1144 break;
1145
1146 default:
1147 bProcessed = false;
1148
1149 //
1150 // Just to suppress the compiler warning
1151 //
1152 eDir = wxALL;
1153 }
1154
1155 if (bProcessed)
1156 {
1157 int nSelOld = pRadiobox->GetSelection();
1158 int nSelNew = pRadiobox->GetNextItem( nSelOld
1159 ,eDir
1160 ,pRadiobox->GetWindowStyleFlag()
1161 );
1162
1163 if (nSelNew != nSelOld)
1164 {
1165 pRadiobox->SetSelection(nSelNew);
1166
1167 //
1168 // Emulate the button click
1169 //
1170 pRadiobox->SendNotificationEvent();
1171 return 0;
1172 }
1173 }
1174 }
1175 }
1176 }
1177 break;
1178 }
1179
1180 return fnWndProcRadioBtn( hWnd
1181 ,(ULONG)uMessage
1182 ,(MPARAM)wParam
1183 ,(MPARAM)lParam
1184 );
1185 } // end of wxRadioBtnWndProc
1186
1187 MRESULT EXPENTRY wxRadioBoxWndProc(
1188 HWND hWnd
1189 , UINT uMessage
1190 , MPARAM wParam
1191 , MPARAM lParam
1192 )
1193 {
1194 return (fnWndProcRadioBox( hWnd
1195 ,(ULONG)uMessage
1196 ,(MPARAM)wParam
1197 ,(MPARAM)lParam
1198 )
1199 );
1200 } // end of wxRadioBoxWndProc