]> git.saurik.com Git - wxWidgets.git/blame - src/os2/radiobox.cpp
fixed problems with sometimes processing the events twice introduced in rev 1.170...
[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
197 // radiobox part not beYInt32ing to any radiobutton)
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
21e0a4d5 293 SetMajorDim(majorDim == 0 ? n : majorDim, lStyle);
3c299c3a
DW
294 m_nNoRowsOrCols = nMajorDim;
295
296 //
297 // Common initialization
298 //
b9b1d6c8
DW
299 if (!CreateControl( pParent
300 ,vId
301 ,rPos
302 ,rSize
303 ,lStyle
b9b1d6c8 304 ,rVal
b9b1d6c8
DW
305 ,rsName
306 ))
1a87edf2 307 return false;
0fba44b4 308 if (!OS2CreateControl( wxT("STATIC")
f289196b 309 ,SS_GROUPBOX
3c299c3a
DW
310 ,rPos
311 ,rSize
312 ,rsTitle
313 ))
1a87edf2 314 return false;
cdf1e714 315
f289196b 316 wxAssociateWinWithHandle(m_hWnd, this);
cdf1e714 317
3c299c3a 318 //
cdf1e714 319 // Some radio boxes test consecutive id.
3c299c3a 320 //
b389a12d 321 m_nNoItems = nNum;
cdf1e714 322 (void)NewControlId();
3c299c3a
DW
323 m_ahRadioButtons = new WXHWND[nNum];
324 m_pnRadioWidth = new int[nNum];
325 m_pnRadioHeight = new int[nNum];
326
3c299c3a 327 for (int i = 0; i < nNum; i++)
cdf1e714 328 {
3c299c3a
DW
329 m_pnRadioWidth[i] = m_pnRadioHeight[i] = -1;
330
331 long lStyleBtn = BS_AUTORADIOBUTTON | WS_TABSTOP | WS_VISIBLE;
332 int nNewId = NewControlId();
333
334 if (i == 0 && lStyle == 0)
335 lStyleBtn |= WS_GROUP;
336
337 HWND hWndBtn = (WXHWND)::WinCreateWindow ( GetHwndOf(pParent)
338 ,WC_BUTTON
c5f975dd 339 ,::wxPMTextToLabel(asChoices[i])
3c299c3a
DW
340 ,lStyleBtn
341 ,0, 0, 0, 0
342 ,GetWinHwnd(pParent)
343 ,HWND_TOP
344 ,(HMENU)nNewId
345 ,NULL
346 ,NULL
347 );
5d44b24e 348 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
349 ::WinSetPresParam( hWndBtn
350 ,PP_FOREGROUNDCOLOR
351 ,sizeof(LONG)
352 ,(PVOID)&lColor
353 );
5d44b24e
DW
354 lColor = (LONG)m_backgroundColour.GetPixel();
355
356 ::WinSetPresParam( hWndBtn
357 ,PP_BACKGROUNDCOLOR
358 ,sizeof(LONG)
359 ,(PVOID)&lColor
360 );
3c299c3a 361 if (!hWndBtn)
cdf1e714 362 {
1a87edf2 363 return false;
cdf1e714 364 }
3c299c3a
DW
365 m_ahRadioButtons[i] = (WXHWND)hWndBtn;
366 SubclassRadioButton((WXHWND)hWndBtn);
f289196b 367 wxAssociateWinWithHandle(hWndBtn, this);
3c299c3a 368 wxOS2SetFont( hWndBtn
f289196b 369 ,*wxSMALL_FONT
3c299c3a
DW
370 );
371 ::WinSetWindowULong(hWndBtn, QWL_USER, (ULONG)this);
372 m_aSubControls.Add(nNewId);
cdf1e714 373 }
0e320a79 374
3c299c3a 375 //
cdf1e714 376 // Create a dummy radio control to end the group.
3c299c3a 377 //
743e24aa
WS
378 (void)::WinCreateWindow ( GetHwndOf(pParent),
379 WC_BUTTON,
380 "",
381 WS_GROUP | BS_AUTORADIOBUTTON,
382 0, 0, 0, 0,
383 GetWinHwnd(pParent),
384 HWND_TOP,
385 (HMENU)NewControlId(),
386 NULL,
387 NULL
3c299c3a 388 );
f289196b
DW
389 SetFont(*wxSMALL_FONT);
390 fnWndProcRadioBox = (WXFARPROC)::WinSubclassWindow( GetHwnd()
391 ,(PFNWP)wxRadioBoxWndProc
392 );
393 ::WinSetWindowULong(GetHwnd(), QWL_USER, (ULONG)this);
5d44b24e 394 lColor = (LONG)vColour.GetPixel();
3c299c3a
DW
395 ::WinSetPresParam( m_hWnd
396 ,PP_FOREGROUNDCOLOR
397 ,sizeof(LONG)
398 ,(PVOID)&lColor
399 );
f289196b
DW
400 ::WinSetPresParam( m_hWnd
401 ,PP_BORDERDARKCOLOR
402 ,sizeof(LONG)
403 ,(PVOID)&lColor
404 );
5d44b24e
DW
405 lColor = (LONG)m_backgroundColour.GetPixel();
406
407 ::WinSetPresParam( m_hWnd
408 ,PP_BACKGROUNDCOLOR
409 ,sizeof(LONG)
410 ,(PVOID)&lColor
411 );
f289196b
DW
412 ::WinSetPresParam( m_hWnd
413 ,PP_BORDERLIGHTCOLOR
414 ,sizeof(LONG)
415 ,(PVOID)&lColor
416 );
b389a12d
DW
417 SetXComp(0);
418 SetYComp(0);
cdf1e714 419 SetSelection(0);
3c299c3a
DW
420 SetSize( rPos.x
421 ,rPos.y
422 ,rSize.x
423 ,rSize.y
424 );
1a87edf2 425 return true;
3c299c3a 426} // end of wxRadioBox::Create
0e320a79 427
3c299c3a 428wxSize wxRadioBox::DoGetBestSize() const
0e320a79 429{
3c299c3a
DW
430 return (GetTotalButtonSize(GetMaxButtonSize()));
431} // end of WinGuiBase_CRadioBox::DoGetBestSize
432
433void wxRadioBox::DoSetSize(
434 int nX
435, int nY
436, int nWidth
437, int nHeight
438, int nSizeFlags
439)
440{
441 int nCurrentX;
442 int nCurrentY;
443 int nWidthOld;
444 int nHeightOld;
445 int nXx = nX;
446 int nYy = nY;
447#if RADIOBTN_PARENT_IS_RADIOBOX
448 int nXOffset = 0;
449 int nYOffset = 0;
450#else
451 int nXOffset = nXx;
452 int nYOffset = nYy;
453#endif
454 int nCx1;
455 int nCy1;
456 wxSize vMaxSize = GetMaxButtonSize();
457 int nMaxWidth;
458 int nMaxHeight;
459 wxSize vTotSize;
460 int nTotWidth;
461 int nTotHeight;
462 int nStartX;
463 int nStartY;
7804d121 464 wxFont vFont = GetFont();
3c299c3a
DW
465
466 m_nSizeFlags = nSizeFlags;
467 GetPosition( &nCurrentX
468 ,&nCurrentY
469 );
470 GetSize( &nWidthOld
471 ,&nHeightOld
472 );
473
fa50c0e3 474 if (nX == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
3c299c3a 475 nXx = nCurrentX;
fa50c0e3 476 if (nY == wxDefaultCoord && !(nSizeFlags & wxSIZE_ALLOW_MINUS_ONE))
3c299c3a 477 nYy = nCurrentY;
b389a12d
DW
478 if (nYy < 0)
479 nYy = 0;
480 if (nXx < 0)
481 nXx = 0;
3c299c3a
DW
482
483 wxGetCharSize( m_hWnd
484 ,&nCx1
485 ,&nCy1
7804d121 486 ,&vFont
3c299c3a
DW
487 );
488
489 //
490 // Attempt to have a look coherent with other platforms: We compute the
491 // biggest toggle dim, then we align all items according this value.
492 //
493 vMaxSize = GetMaxButtonSize();
494 nMaxWidth = vMaxSize.x;
495 nMaxHeight = vMaxSize.y;
496
497 vTotSize = GetTotalButtonSize(vMaxSize);
498 nTotWidth = vTotSize.x;
499 nTotHeight = vTotSize.y;
500
501 //
502 // Only change our width/height if asked for
503 //
504 if (nWidth == -1)
505 {
506 if (nSizeFlags & wxSIZE_AUTO_WIDTH )
507 nWidth = nTotWidth;
508 else
509 nWidth = nWidthOld;
510 }
cdf1e714 511
3c299c3a 512 if (nHeight == -1)
cdf1e714 513 {
3c299c3a
DW
514 if (nSizeFlags & wxSIZE_AUTO_HEIGHT)
515 nHeight = nTotHeight;
516 else
517 nHeight = nHeightOld;
cdf1e714
DW
518 }
519
3c299c3a 520 wxWindowOS2* pParent = (wxWindowOS2*)GetParent();
cdf1e714 521
3c299c3a
DW
522 if (pParent)
523 {
d8a3f66c
DW
524 int nOS2Height = GetOS2ParentHeight(pParent);
525
526 nYy = nOS2Height - (nYy + nHeight);
3c299c3a
DW
527 nYOffset = nYy + nHeight;
528 }
529 else
530 {
531 RECTL vRect;
0e320a79 532
3c299c3a
DW
533 ::WinQueryWindowRect(HWND_DESKTOP, &vRect);
534 nYy = vRect.yTop - (nYy + nHeight);
535 }
536 ::WinSetWindowPos( GetHwnd()
537 ,HWND_TOP
538 ,(LONG)nXx
539 ,(LONG)nYy
540 ,(LONG)nWidth
541 ,(LONG)nHeight
542 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
543 );
544
545 //
546 // Now position all the buttons: the current button will be put at
547 // wxPoint(x_offset, y_offset) and the new row/column will start at
548 // startX/startY. The size of all buttons will be the same wxSize(maxWidth,
549 // maxHeight) except for the buttons in the last column which should extend
550 // to the right border of radiobox and thus can be wider than this.
551 //
552 // Also, remember that wxRA_SPECIFY_COLS means that we arrange buttons in
553 // left to right order and m_majorDim is the number of columns while
554 // wxRA_SPECIFY_ROWS means that the buttons are arranged top to bottom and
555 // m_majorDim is the number of rows.
556 //
557 nXOffset += nCx1;
558 nYOffset -= (nMaxHeight + ((3*nCy1)/2));
559
560 nStartX = nXOffset;
561 nStartY = nYOffset;
562
563 for (int i = 0; i < m_nNoItems; i++)
564 {
565 //
566 // The last button in the row may be wider than the other ones as the
567 // radiobox may be wider than the sum of the button widths (as it
568 // happens, for example, when the radiobox label is very long)
569 //
570 bool bIsLastInTheRow;
571
572 if (m_windowStyle & wxRA_SPECIFY_COLS)
573 {
574 //
575 // Item is the last in its row if it is a multiple of the number of
576 // columns or if it is just the last item
577 //
578 int n = i + 1;
0367c1c0 579
21e0a4d5 580 bIsLastInTheRow = ((n % GetMajorDim()) == 0) || (n == m_nNoItems);
3c299c3a
DW
581 }
582 else // winRA_SPECIFY_ROWS
583 {
584 //
585 // Item is the last in the row if it is in the last columns
586 //
21e0a4d5 587 bIsLastInTheRow = i >= (m_nNoItems/GetMajorDim()) * GetMajorDim();
3c299c3a 588 }
0367c1c0 589
3c299c3a
DW
590 //
591 // Is this the start of new row/column?
592 //
21e0a4d5 593 if (i && (i % GetMajorDim() == 0))
3c299c3a
DW
594 {
595 if (m_windowStyle & wxRA_SPECIFY_ROWS)
596 {
597
598 //
599 // Start of new column
600 //
601 nYOffset = nStartY;
602 nXOffset += nMaxWidth + nCx1;
603 }
604 else // start of new row
605 {
606 nXOffset = nStartX;
607 nYOffset -= nMaxHeight;
608 if (m_pnRadioWidth[0] > 0L)
609 nYOffset -= nCy1/2;
610 }
611 }
612
613 int nWidthBtn;
614
615 if (bIsLastInTheRow)
616 {
617 //
618 // Make the button go to the end of radio box
619 //
620 nWidthBtn = nStartX + nWidth - nXOffset - (2 * nCx1);
621 if (nWidthBtn < nMaxWidth)
622 nWidthBtn = nMaxWidth;
623 }
624 else
625 {
626 //
627 // Normal button, always of the same size
628 //
629 nWidthBtn = nMaxWidth;
630 }
cdf1e714 631
3c299c3a
DW
632 //
633 // Make all buttons of the same, maximal size - like this they
634 // cover the radiobox entirely and the radiobox tooltips are always
635 // shown (otherwise they are not when the mouse pointer is in the
636 // radiobox part not beinting to any radiobutton)
637 //
638 ::WinSetWindowPos( (HWND)m_ahRadioButtons[i]
639 ,HWND_TOP
640 ,(LONG)nXOffset
641 ,(LONG)nYOffset
642 ,(LONG)nWidthBtn
643 ,(LONG)nMaxHeight
644 ,SWP_ZORDER | SWP_SIZE | SWP_MOVE | SWP_SHOW
645 );
646 //
647 // Where do we put the next button?
648 //
649 if (m_windowStyle & wxRA_SPECIFY_ROWS)
650 {
651 //
652 // Below this one
653 //
654 nYOffset -= nMaxHeight;
655 if (m_pnRadioWidth[0] > 0)
656 nYOffset -= nCy1/2;
657 }
658 else
659 {
660 //
661 // To the right of this one
662 //
663 nXOffset += nWidthBtn + nCx1;
664 }
665 }
666} // end of wxRadioBox::DoSetSize
0e320a79 667
1a87edf2 668bool wxRadioBox::Enable(int nItem, bool bEnable)
0e320a79 669{
fa50c0e3 670 wxCHECK_MSG( IsValid(nItem), false,
3c299c3a 671 wxT("invalid item in wxRadioBox::Enable()") );
cdf1e714 672
3c299c3a 673 ::WinEnableWindow((HWND) m_ahRadioButtons[nItem], bEnable);
1a87edf2 674 return true;
3c299c3a 675} // end of wxRadioBox::Enable
0e320a79 676
3c299c3a
DW
677bool wxRadioBox::Enable(
678 bool bEnable
679)
0e320a79 680{
3c299c3a 681 if ( !wxControl::Enable(bEnable) )
1a87edf2 682 return false;
3c299c3a
DW
683 for (int i = 0; i < m_nNoItems; i++)
684 ::WinEnableWindow((HWND)m_ahRadioButtons[i], bEnable);
1a87edf2 685 return true;
3c299c3a 686} // end of wxRadioBox::Enable
0e320a79 687
3c299c3a 688int wxRadioBox::GetCount() const
0e320a79 689{
3c299c3a
DW
690 return m_nNoItems;
691} // end of wxRadioBox::GetCount
0e320a79 692
11e62fe6 693wxString wxRadioBox::GetLabel(int nItem) const
0e320a79 694{
fa50c0e3 695 wxCHECK_MSG( IsValid(nItem), wxEmptyString, wxT("invalid radiobox index") );
cdf1e714 696
3c299c3a
DW
697 return wxGetWindowText(m_ahRadioButtons[nItem]);
698} // end of wxRadioBox::GetLabel
cdf1e714 699
3c299c3a
DW
700wxSize wxRadioBox::GetMaxButtonSize() const
701{
702 int nWidthMax = 0;
703 int nHeightMax = 0;
cdf1e714 704
3c299c3a 705 for (int i = 0 ; i < m_nNoItems; i++)
cdf1e714 706 {
3c299c3a
DW
707 int nWidth;
708 int nHeight;
709
710 if (m_pnRadioWidth[i] < 0L)
cdf1e714 711 {
3c299c3a
DW
712 GetTextExtent( wxGetWindowText(m_ahRadioButtons[i])
713 ,&nWidth
714 ,&nHeight
715 );
716
717 //
718 // Adjust the size to take into account the radio box itself
719 // FIXME this is totally bogus!
720 //
721 nWidth += RADIO_SIZE;
722 nHeight *= 3;
723 nHeight /= 2;
cdf1e714
DW
724 }
725 else
726 {
3c299c3a
DW
727 nWidth = m_pnRadioWidth[i];
728 nHeight = m_pnRadioHeight[i];
cdf1e714 729 }
3c299c3a
DW
730 if (nWidthMax < nWidth )
731 nWidthMax = nWidth;
732 if (nHeightMax < nHeight )
733 nHeightMax = nHeight;
734 }
6670f564
WS
735 wxSize maxsize( nWidthMax, nHeightMax);
736 return maxsize;
3c299c3a 737} // end of wxRadioBox::GetMaxButtonSize
cdf1e714 738
6670f564
WS
739void wxRadioBox::GetPosition( int* pnX,
740 int* WXUNUSED(pnY) ) const
3c299c3a
DW
741{
742 wxWindowOS2* pParent = GetParent();
d0ee33f5 743 RECT vRect = { -1, -1, -1, -1 };
3c299c3a
DW
744 POINTL vPoint;
745 int i;
746
747 for (i = 0; i < m_nNoItems; i++)
748 wxFindMaxSize( m_ahRadioButtons[i]
749 ,&vRect
750 );
cdf1e714 751 if (m_hWnd)
3c299c3a
DW
752 wxFindMaxSize( m_hWnd
753 ,&vRect
754 );
755
756 //
757 // Since we now have the absolute screen coords, if there's a parent we
758 // must subtract its top left corner
759 //
760 vPoint.x = vRect.xLeft;
761 vPoint.y = vRect.yTop;
762 if (pParent)
cdf1e714 763 {
3c299c3a 764 SWP vSwp;
cdf1e714 765
3c299c3a
DW
766 ::WinQueryWindowPos((HWND)pParent->GetHWND(), &vSwp);
767 vPoint.x = vSwp.x;
768 vPoint.y = vSwp.y;
769 }
cdf1e714 770
3c299c3a
DW
771 //
772 // We may be faking the client origin. So a window that's really at (0, 30)
773 // may appear (to wxWin apps) to be at (0, 0).
774 //
775 if (GetParent())
776 {
777 wxPoint vPt(GetParent()->GetClientAreaOrigin());
cdf1e714 778
3c299c3a
DW
779 vPoint.x = vPt.x;
780 vPoint.y = vPt.y;
781 }
782 *pnX = vPoint.x;
783 *pnX = vPoint.y;
784} // end of wxRadioBox::GetPosition
cdf1e714 785
3c299c3a
DW
786// Get single selection, for single choice list items
787int wxRadioBox::GetSelection() const
788{
789 return m_nSelectedButton;
790} // end of wxRadioBox::GetSelection
cdf1e714 791
743e24aa 792void wxRadioBox::GetSize( int* pnWidth, int* pnHeight ) const
3c299c3a
DW
793{
794 RECT vRect;
795 int i;
cdf1e714 796
3c299c3a
DW
797 vRect.xLeft = -1;
798 vRect.xRight = -1;
799 vRect.yTop = -1;
800 vRect.yBottom = -1;
801
802 if (m_hWnd)
803 wxFindMaxSize( m_hWnd
804 ,&vRect
805 );
806
807 for (i = 0; i < m_nNoItems; i++)
808 wxFindMaxSize( m_ahRadioButtons[i]
809 ,&vRect
810 );
811
a00ffdf1
SN
812 if (pnWidth)
813 *pnWidth = vRect.xRight - vRect.xLeft;
814 if (pnHeight)
815 *pnHeight = vRect.yTop - vRect.yBottom;
3c299c3a 816} // end of wxRadioBox::GetSize
cdf1e714 817
3c299c3a
DW
818// Find string for position
819wxString wxRadioBox::GetString(
820 int nNum
821) const
822{
823 return wxGetWindowText(m_ahRadioButtons[nNum]);
824} // end of wxRadioBox::GetString
825
826// For single selection items only
827wxString wxRadioBox::GetStringSelection() const
828{
829 wxString sResult;
830 int nSel = GetSelection();
831
832 if (nSel > -1)
833 sResult = GetString(nSel);
834 return sResult;
835} // end of wxRadioBox::GetStringSelection
836
6670f564 837wxSize wxRadioBox::GetTotalButtonSize( const wxSize& rSizeBtn ) const
3c299c3a 838{
6670f564
WS
839 int nCx1;
840 int nCy1;
6670f564
WS
841 int nHeight;
842 int nWidth;
c5f975dd 843 int nWidthLabel = 0;
3c299c3a 844
c5f975dd
SN
845 nCx1 = GetCharWidth();
846 nCy1 = GetCharHeight();
21e0a4d5
VZ
847 nHeight = GetRowCount() * rSizeBtn.y + (2 * nCy1);
848 nWidth = GetColumnCount() * (rSizeBtn.x + nCx1) + nCx1;
3c299c3a
DW
849
850 //
851 // And also wide enough for its label
852 //
c5f975dd
SN
853 wxString sStr = wxGetWindowText(GetHwnd());
854 if (!sStr.IsEmpty())
855 {
856 GetTextExtent( sStr
857 ,&nWidthLabel
858 ,NULL
859 );
860 nWidthLabel += 2*nCx1;
861 }
3c299c3a
DW
862 if (nWidthLabel > nWidth)
863 nWidth = nWidthLabel;
864
6670f564
WS
865 wxSize total( nWidth, nHeight );
866 return total;
3c299c3a
DW
867} // end of wxRadioBox::GetTotalButtonSize
868
6670f564
WS
869WXHBRUSH wxRadioBox::OnCtlColor( WXHDC hwinDC,
870 WXHWND WXUNUSED(hWnd),
871 WXUINT WXUNUSED(uCtlColor),
872 WXUINT WXUNUSED(uMessage),
873 WXWPARAM WXUNUSED(wParam),
874 WXLPARAM WXUNUSED(lParam) )
3c299c3a 875{
6670f564 876 HPS hPS = (HPS)hwinDC; // pass in a PS handle in OS/2
3c299c3a
DW
877
878 if (GetParent()->GetTransparentBackground())
879 ::GpiSetBackMix(hPS, BM_LEAVEALONE);
880 else
881 ::GpiSetBackMix(hPS, BM_OVERPAINT);
882
6670f564 883 wxColour vColBack = GetBackgroundColour();
cdf1e714 884
3c299c3a
DW
885 ::GpiSetBackColor(hPS, vColBack.GetPixel());
886 ::GpiSetColor(hPS, vColBack.GetPixel());
887
6670f564 888 wxBrush* pBrush = wxTheBrushList->FindOrCreateBrush( vColBack, wxSOLID );
3c299c3a
DW
889 return ((WXHBRUSH)pBrush->GetResourceHandle());
890} // end of wxRadioBox::OnCtlColor
891
6670f564
WS
892bool wxRadioBox::OS2Command( WXUINT uCmd,
893 WXWORD wId)
3c299c3a 894{
6670f564 895 int nSelectedButton = -1;
3c299c3a
DW
896
897 if (uCmd == BN_CLICKED)
cdf1e714 898 {
3c299c3a 899 if (wId == GetId())
1a87edf2 900 return true;
3c299c3a
DW
901
902
903 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 904 {
3c299c3a 905 if (wId == wxGetWindowId(m_ahRadioButtons[i]))
cdf1e714 906 {
3c299c3a
DW
907 nSelectedButton = i;
908 break;
cdf1e714
DW
909 }
910 }
3c299c3a 911 if (nSelectedButton == -1)
cdf1e714 912 {
3c299c3a 913 //
f289196b
DW
914 // Just ignore it
915 //
1a87edf2 916 return false;
cdf1e714 917 }
3c299c3a 918 if (nSelectedButton != m_nSelectedButton)
cdf1e714 919 {
3c299c3a
DW
920 m_nSelectedButton = nSelectedButton;
921 SendNotificationEvent();
cdf1e714 922 }
1a87edf2 923 return true;
cdf1e714 924 }
3c299c3a 925 else
1a87edf2 926 return false;
3c299c3a 927} // end of wxRadioBox::OS2Command
0e320a79 928
3c299c3a 929void wxRadioBox::SendNotificationEvent()
0e320a79 930{
3c299c3a
DW
931 wxCommandEvent vEvent( wxEVT_COMMAND_RADIOBOX_SELECTED
932 ,m_windowId
933 );
cdf1e714 934
3c299c3a
DW
935 vEvent.SetInt( m_nSelectedButton );
936 vEvent.SetString( GetString(m_nSelectedButton) );
937 vEvent.SetEventObject(this);
938 ProcessCommand(vEvent);
939} // end of wxRadioBox::SendNotificationEvent
0e320a79
DW
940
941void wxRadioBox::SetFocus()
942{
3c299c3a 943 if (m_nNoItems > 0)
cdf1e714 944 {
3c299c3a
DW
945 if (m_nSelectedButton == -1)
946 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[0]);
cdf1e714 947 else
3c299c3a 948 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[m_nSelectedButton]);
cdf1e714 949 }
3c299c3a 950} // end of wxRadioBox::SetFocus
0e320a79 951
3c299c3a
DW
952bool wxRadioBox::SetFont(
953 const wxFont& rFont
954)
0e320a79 955{
3c299c3a
DW
956 if (!wxControl::SetFont(rFont))
957 {
958 //
959 // Nothing to do
960 //
1a87edf2 961 return false;
3c299c3a
DW
962 }
963 //
964 // Also set the font of our radio buttons
965 //
3c299c3a 966 for (int n = 0; n < (int)m_nNoItems; n++)
cdf1e714 967 {
3c299c3a 968 HWND hWndBtn = (HWND)m_ahRadioButtons[n];
cdf1e714 969
3c299c3a
DW
970 wxOS2SetFont( hWndBtn
971 ,rFont
972 );
973 ::WinInvalidateRect(hWndBtn, NULL, FALSE);
974 }
1a87edf2 975 return true;
3c299c3a 976} // end of wxRadioBox::SetFont
0e320a79 977
3c299c3a
DW
978void wxRadioBox::SetSelection(
979 int nNum
980)
0e320a79 981{
fa50c0e3 982 wxCHECK_RET( IsValid(nNum), wxT("invalid radiobox index") );
cdf1e714 983
fa50c0e3 984 if ( IsValid(m_nSelectedButton) )
3c299c3a 985 ::WinSendMsg((HWND)m_ahRadioButtons[m_nSelectedButton], BM_SETCHECK, (MPARAM)0, (MPARAM)0);
0e320a79 986
3c299c3a
DW
987 ::WinSendMsg((HWND)m_ahRadioButtons[nNum], BM_SETCHECK, (MPARAM)1, (MPARAM)0);
988 ::WinSetFocus(HWND_DESKTOP, (HWND)m_ahRadioButtons[nNum]);
989 m_nSelectedButton = nNum;
990} // end of wxRadioBox::SetSelection
0e320a79 991
3c299c3a
DW
992void wxRadioBox::SetString(
993 int nItem
994, const wxString& rsLabel
995)
0e320a79 996{
fa50c0e3 997 wxCHECK_RET( IsValid(nItem), wxT("invalid radiobox index") );
cdf1e714 998
3c299c3a 999 m_pnRadioWidth[nItem] = m_pnRadioHeight[nItem] = -1;
0fba44b4 1000 ::WinSetWindowText((HWND)m_ahRadioButtons[nItem], (PSZ)rsLabel.c_str());
3c299c3a 1001} // end of wxRadioBox::SetString
cdf1e714 1002
11e62fe6 1003bool wxRadioBox::SetStringSelection(const wxString& rsStr)
cdf1e714 1004{
11e62fe6 1005 int nSel = FindString(rsStr);
0e320a79 1006
3c299c3a 1007 if (nSel > -1)
0e320a79 1008 {
3c299c3a 1009 SetSelection(nSel);
1a87edf2 1010 return true;
0e320a79
DW
1011 }
1012 else
1a87edf2 1013 return false;
3c299c3a 1014} // end of wxRadioBox::SetStringSelection
0e320a79 1015
3c299c3a
DW
1016bool wxRadioBox::Show(
1017 bool bShow
1018)
cdf1e714 1019{
3c299c3a 1020 if (!wxControl::Show(bShow))
1a87edf2 1021 return false;
3c299c3a
DW
1022
1023 for (int i = 0; i < m_nNoItems; i++)
cdf1e714 1024 {
3c299c3a 1025 ::WinShowWindow((HWND)m_ahRadioButtons[i], (BOOL)bShow);
cdf1e714 1026 }
1a87edf2 1027 return true;
3c299c3a 1028} // end of wxRadioBox::Show
cdf1e714 1029
3c299c3a 1030// Show a specific button
fa50c0e3 1031bool wxRadioBox::Show(
3c299c3a
DW
1032 int nItem
1033, bool bShow
1034)
0e320a79 1035{
fa50c0e3 1036 wxCHECK_MSG( IsValid(nItem), false,
3c299c3a 1037 wxT("invalid item in wxRadioBox::Show()") );
0e320a79 1038
3c299c3a 1039 ::WinShowWindow((HWND)m_ahRadioButtons[nItem], bShow);
fa50c0e3
WS
1040
1041 return true;
3c299c3a 1042} // end of wxRadioBox::Show
cdf1e714 1043
3c299c3a
DW
1044void wxRadioBox::SubclassRadioButton(
1045 WXHWND hWndBtn
1046)
1047{
3c299c3a
DW
1048 fnWndProcRadioBtn = (WXFARPROC)::WinSubclassWindow(hWndBtn, (PFNWP)wxRadioBtnWndProc);
1049} // end of wxRadioBox::SubclassRadioButton
cdf1e714 1050
3c299c3a
DW
1051MRESULT wxRadioBox::WindowProc(
1052 WXUINT uMsg
1053, WXWPARAM wParam
1054, WXLPARAM lParam
1055)
cdf1e714 1056{
3c299c3a
DW
1057 return (wxControl::OS2WindowProc( uMsg
1058 ,wParam
1059 ,lParam
1060 ));
1061} // end of wxRadioBox::WindowProc
cdf1e714
DW
1062
1063// ---------------------------------------------------------------------------
1064// window proc for radio buttons
1065// ---------------------------------------------------------------------------
1066
3c299c3a
DW
1067MRESULT wxRadioBtnWndProc(
1068 HWND hWnd
1069, UINT uMessage
1070, MPARAM wParam
1071, MPARAM lParam
1072)
cdf1e714 1073{
3c299c3a 1074 switch (uMessage)
cdf1e714 1075 {
3c299c3a
DW
1076 case WM_CHAR:
1077 {
1078 USHORT uKeyFlags = SHORT1FROMMP((MPARAM)wParam);
cdf1e714 1079
3c299c3a 1080 if (!(uKeyFlags & KC_KEYUP)) // Key Down event
cdf1e714 1081 {
3c299c3a
DW
1082 if (uKeyFlags & KC_VIRTUALKEY)
1083 {
1084 wxRadioBox* pRadiobox = (wxRadioBox *)::WinQueryWindowULong( hWnd
1085 ,QWL_USER
1086 );
1087 USHORT uVk = SHORT2FROMMP((MPARAM)lParam);
1a87edf2 1088 bool bProcessed = true;
3c299c3a
DW
1089 wxDirection eDir;
1090
1091 switch(uVk)
1092 {
1093 case VK_LEFT:
1094 eDir = wxDOWN;
1095 break;
1096
1097 case VK_RIGHT:
1098 eDir = wxDOWN;
1099 break;
1100
1101 case VK_DOWN:
1102 eDir = wxDOWN;
1103 break;
1104
1105 case VK_UP:
1106 eDir = wxUP;
1107 break;
1108
1109 default:
1a87edf2 1110 bProcessed = false;
3c299c3a
DW
1111
1112 //
1113 // Just to suppress the compiler warning
1114 //
1115 eDir = wxALL;
1116 }
1117
1118 if (bProcessed)
1119 {
1120 int nSelOld = pRadiobox->GetSelection();
1121 int nSelNew = pRadiobox->GetNextItem( nSelOld
1122 ,eDir
1123 ,pRadiobox->GetWindowStyleFlag()
1124 );
1125
1126 if (nSelNew != nSelOld)
1127 {
1128 pRadiobox->SetSelection(nSelNew);
1129
1130 //
1131 // Emulate the button click
1132 //
1133 pRadiobox->SendNotificationEvent();
1134 return 0;
1135 }
1136 }
1137 }
cdf1e714 1138 }
cdf1e714 1139 }
3c299c3a 1140 break;
cdf1e714
DW
1141 }
1142
3c299c3a
DW
1143 return fnWndProcRadioBtn( hWnd
1144 ,(ULONG)uMessage
1145 ,(MPARAM)wParam
1146 ,(MPARAM)lParam
1147 );
1148} // end of wxRadioBtnWndProc
0e320a79 1149
743e24aa
WS
1150MRESULT EXPENTRY wxRadioBoxWndProc( HWND hWnd,
1151 UINT uMessage,
1152 MPARAM wParam,
1153 MPARAM lParam )
f289196b 1154{
743e24aa
WS
1155 return (fnWndProcRadioBox( hWnd,
1156 (ULONG)uMessage,
1157 (MPARAM)wParam,
1158 (MPARAM)lParam )
f289196b
DW
1159 );
1160} // end of wxRadioBoxWndProc