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