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