Doc mods; fixed return non-processing problem; fixed toolbar sizing problems
[wxWidgets.git] / src / msw / radiobox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: radiobox.cpp
3 // Purpose: wxRadioBox
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart and Markus Holzem
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ===========================================================================
13 // declarations
14 // ===========================================================================
15
16 // ---------------------------------------------------------------------------
17 // headers
18 // ---------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "radiobox.h"
22 #endif
23
24 // For compilers that support precompilation, includes "wx.h".
25 #include "wx/wxprec.h"
26
27 #ifdef __BORLANDC__
28 #pragma hdrstop
29 #endif
30
31 #ifndef WX_PRECOMP
32 #include <stdio.h>
33 #include "wx/setup.h"
34 #include "wx/bitmap.h"
35 #include "wx/brush.h"
36 #include "wx/radiobox.h"
37 #endif
38
39 #include "wx/msw/private.h"
40
41 #if !USE_SHARED_LIBRARY
42 IMPLEMENT_DYNAMIC_CLASS(wxRadioBox, wxControl)
43 #endif
44
45 // ---------------------------------------------------------------------------
46 // private functions
47 // ---------------------------------------------------------------------------
48
49 // get the id of the window
50 #ifdef __WIN32__
51 #define GET_WIN_ID(hwnd) ::GetWindowLong((HWND)hwnd, GWL_ID)
52 #else // Win16
53 #define GET_WIN_ID(hwnd) ::GetWindowWord((HWND)hwnd, GWW_ID)
54 #endif // Win32/16
55
56 // wnd proc for radio buttons
57 #ifdef __WIN32__
58 LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hWnd,
59 UINT message,
60 WPARAM wParam,
61 LPARAM lParam);
62 #endif
63
64 // ---------------------------------------------------------------------------
65 // global vars
66 // ---------------------------------------------------------------------------
67
68 // the pointer to standard radio button wnd proc
69 static WNDPROC s_wndprocRadioBtn = (WNDPROC)NULL;
70
71 // ===========================================================================
72 // implementation
73 // ===========================================================================
74
75 // ---------------------------------------------------------------------------
76 // wxRadioBox
77 // ---------------------------------------------------------------------------
78
79 int wxRadioBox::GetNumVer() const
80 {
81 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
82 {
83 return m_majorDim;
84 }
85 else
86 {
87 return (m_noItems + m_majorDim - 1)/m_majorDim;
88 }
89 }
90
91 int wxRadioBox::GetNumHor() const
92 {
93 if ( m_windowStyle & wxRA_SPECIFY_ROWS )
94 {
95 return (m_noItems + m_majorDim - 1)/m_majorDim;
96 }
97 else
98 {
99 return m_majorDim;
100 }
101 }
102
103 bool wxRadioBox::MSWCommand(WXUINT param, WXWORD id)
104 {
105 if ( param == BN_CLICKED )
106 {
107 m_selectedButton = -1;
108
109 for ( int i = 0; i < m_noItems; i++ )
110 {
111 if ( id == GET_WIN_ID(m_radioButtons[i]) )
112 {
113 m_selectedButton = i;
114
115 break;
116 }
117 }
118
119 wxASSERT_MSG( m_selectedButton != -1, "click from alien button?" );
120
121 wxCommandEvent event(wxEVT_COMMAND_RADIOBOX_SELECTED, m_windowId);
122 event.SetInt( m_selectedButton );
123 event.SetEventObject( this );
124 ProcessCommand(event);
125
126 return TRUE;
127 }
128 else
129 return FALSE;
130 }
131
132 #if WXWIN_COMPATIBILITY
133 wxRadioBox::wxRadioBox(wxWindow *parent, wxFunction func, const char *title,
134 int x, int y, int width, int height,
135 int n, char **choices,
136 int majorDim, long style, const char *name)
137 {
138 wxString *choices2 = new wxString[n];
139 for ( int i = 0; i < n; i ++) choices2[i] = choices[i];
140 Create(parent, -1, title, wxPoint(x, y), wxSize(width, height), n, choices2, majorDim, style,
141 wxDefaultValidator, name);
142 Callback(func);
143 delete choices2;
144 }
145
146 #endif
147
148 // Radio box item
149 wxRadioBox::wxRadioBox()
150 {
151 m_selectedButton = -1;
152 m_noItems = 0;
153 m_noRowsOrCols = 0;
154 m_radioButtons = NULL;
155 m_majorDim = 0;
156 m_radioWidth = NULL;
157 m_radioHeight = NULL;
158 }
159
160 bool wxRadioBox::Create(wxWindow *parent, wxWindowID id, const wxString& title,
161 const wxPoint& pos, const wxSize& size,
162 int n, const wxString choices[],
163 int majorDim, long style,
164 const wxValidator& val, const wxString& name)
165 {
166 m_selectedButton = -1;
167 m_noItems = n;
168
169 SetName(name);
170 SetValidator(val);
171
172 parent->AddChild(this);
173 m_backgroundColour = parent->GetBackgroundColour();
174 m_foregroundColour = parent->GetForegroundColour();
175
176 m_windowStyle = (long&)style;
177
178 int x = pos.x;
179 int y = pos.y;
180 int width = size.x;
181 int height = size.y;
182
183 if (id == -1)
184 m_windowId = NewControlId();
185 else
186 m_windowId = id;
187
188 if ( majorDim == 0 )
189 m_majorDim = n;
190 else
191 m_majorDim = majorDim;
192 m_noRowsOrCols = majorDim;
193
194 long msStyle = GROUP_FLAGS;
195
196 bool want3D;
197 WXDWORD exStyle = Determine3DEffects(0, &want3D);
198 // Even with extended styles, need to combine with WS_BORDER
199 // for them to look right.
200 /*
201 if ( want3D || wxStyleHasBorder(m_windowStyle) )
202 msStyle |= WS_BORDER;
203 */
204
205 HWND hwndParent = (HWND)parent->GetHWND();
206
207 m_hWnd = (WXHWND)::CreateWindowEx
208 (
209 (DWORD)exStyle,
210 GROUP_CLASS,
211 title,
212 msStyle,
213 0, 0, 0, 0,
214 hwndParent,
215 (HMENU)m_windowId,
216 wxGetInstance(),
217 NULL
218 );
219
220 #if wxUSE_CTL3D
221 if (want3D)
222 {
223 Ctl3dSubclassCtl((HWND)m_hWnd);
224 m_useCtl3D = TRUE;
225 }
226 #endif // wxUSE_CTL3D
227
228 SetFont(parent->GetFont());
229
230 SubclassWin(m_hWnd);
231
232 // Some radio boxes test consecutive id.
233 (void)NewControlId();
234 m_radioButtons = new WXHWND[n];
235 m_radioWidth = new int[n];
236 m_radioHeight = new int[n];
237 int i;
238 for (i = 0; i < n; i++)
239 {
240 m_radioWidth[i] = m_radioHeight[i] = -1;
241 long groupStyle = 0;
242 if ( i == 0 && style == 0 )
243 groupStyle = WS_GROUP;
244 long newId = NewControlId();
245 long msStyle = groupStyle | RADIO_FLAGS;
246
247 HWND hwndBtn = CreateWindowEx(exStyle, RADIO_CLASS,
248 choices[i], msStyle,
249 0,0,0,0,
250 hwndParent,
251 (HMENU)newId, wxGetInstance(),
252 NULL);
253
254 m_radioButtons[i] = (WXHWND)hwndBtn;
255 SubclassRadioButton((WXHWND)hwndBtn);
256
257 wxFont& font = GetFont();
258 if ( font.Ok() )
259 {
260 SendMessage(hwndBtn, WM_SETFONT,
261 (WPARAM)font.GetResourceHandle(), 0L);
262 }
263
264 m_subControls.Append((wxObject *)newId);
265 }
266
267 // Create a dummy radio control to end the group.
268 (void)CreateWindowEx(0, RADIO_CLASS, "", WS_GROUP | RADIO_FLAGS,
269 0, 0, 0, 0, hwndParent,
270 (HMENU)NewControlId(), wxGetInstance(), NULL);
271
272 SetSelection(0);
273
274 SetSize(x, y, width, height);
275
276 return TRUE;
277 }
278
279 wxRadioBox::~wxRadioBox()
280 {
281 m_isBeingDeleted = TRUE;
282
283 if (m_radioButtons)
284 {
285 int i;
286 for (i = 0; i < m_noItems; i++)
287 DestroyWindow((HWND) m_radioButtons[i]);
288 delete[] m_radioButtons;
289 }
290 if (m_radioWidth)
291 delete[] m_radioWidth;
292 if (m_radioHeight)
293 delete[] m_radioHeight;
294 if (m_hWnd)
295 ::DestroyWindow((HWND) m_hWnd);
296 m_hWnd = 0;
297
298 }
299
300 wxString wxRadioBox::GetLabel(int item) const
301 {
302 GetWindowText((HWND)m_radioButtons[item], wxBuffer, 300);
303 return wxString(wxBuffer);
304 }
305
306 void wxRadioBox::SetLabel(int item, const wxString& label)
307 {
308 m_radioWidth[item] = m_radioHeight[item] = -1;
309 SetWindowText((HWND)m_radioButtons[item], (const char *)label);
310 }
311
312 void wxRadioBox::SetLabel(int item, wxBitmap *bitmap)
313 {
314 /*
315 m_radioWidth[item] = bitmap->GetWidth() + FB_MARGIN;
316 m_radioHeight[item] = bitmap->GetHeight() + FB_MARGIN;
317 */
318 }
319
320 int wxRadioBox::FindString(const wxString& s) const
321 {
322 int i;
323 for (i = 0; i < m_noItems; i++)
324 {
325 GetWindowText((HWND) m_radioButtons[i], wxBuffer, 1000);
326 if (s == wxBuffer)
327 return i;
328 }
329 return -1;
330 }
331
332 void wxRadioBox::SetSelection(int N)
333 {
334 wxCHECK_RET( (N >= 0) && (N < m_noItems), "invalid radiobox index" );
335
336 // Following necessary for Win32s, because Win32s translate BM_SETCHECK
337 if (m_selectedButton >= 0 && m_selectedButton < m_noItems)
338 ::SendMessage((HWND) m_radioButtons[m_selectedButton], BM_SETCHECK, 0, 0L);
339
340 ::SendMessage((HWND)m_radioButtons[N], BM_SETCHECK, 1, 0L);
341 ::SetFocus((HWND)m_radioButtons[N]);
342
343 m_selectedButton = N;
344 }
345
346 // Get single selection, for single choice list items
347 int wxRadioBox::GetSelection() const
348 {
349 return m_selectedButton;
350 }
351
352 // Find string for position
353 wxString wxRadioBox::GetString(int N) const
354 {
355 return wxGetWindowText(m_radioButtons[N]);
356 }
357
358 // Restored old code.
359 void wxRadioBox::DoSetSize(int x, int y, int width, int height, int sizeFlags)
360 {
361 int currentX, currentY;
362 GetPosition(&currentX, &currentY);
363 int xx = x;
364 int yy = y;
365
366 if (x == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
367 xx = currentX;
368 if (y == -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
369 yy = currentY;
370
371 char buf[400];
372
373 int y_offset = yy;
374 int x_offset = xx;
375 int current_width, cyf;
376
377 int cx1,cy1;
378 wxGetCharSize(m_hWnd, &cx1, &cy1, & GetFont());
379 // Attempt to have a look coherent with other platforms:
380 // We compute the biggest toggle dim, then we align all
381 // items according this value.
382 int maxWidth = -1;
383 int maxHeight = -1;
384
385 int i;
386 for (i = 0 ; i < m_noItems; i++)
387 {
388 int eachWidth;
389 int eachHeight;
390 if (m_radioWidth[i]<0)
391 {
392 // It's a labelled toggle
393 GetWindowText((HWND) m_radioButtons[i], buf, 300);
394 GetTextExtent(buf, &current_width, &cyf,NULL,NULL, & GetFont());
395 eachWidth = (int)(current_width + RADIO_SIZE);
396 eachHeight = (int)((3*cyf)/2);
397 }
398 else
399 {
400 eachWidth = m_radioWidth[i];
401 eachHeight = m_radioHeight[i];
402 }
403 if (maxWidth<eachWidth) maxWidth = eachWidth;
404 if (maxHeight<eachHeight) maxHeight = eachHeight;
405 }
406
407 if (m_hWnd)
408 {
409 int totWidth;
410 int totHeight;
411
412 int nbHor = GetNumHor(),
413 nbVer = GetNumVer();
414
415 // this formula works, but I don't know why.
416 // Please, be sure what you do if you modify it!!
417 if (m_radioWidth[0]<0)
418 totHeight = (nbVer * maxHeight) + cy1/2;
419 else
420 totHeight = nbVer * (maxHeight+cy1/2);
421 totWidth = nbHor * (maxWidth+cx1);
422
423 #if (!CTL3D)
424 // Requires a bigger group box in plain Windows
425 MoveWindow((HWND) m_hWnd,x_offset,y_offset,totWidth+cx1,totHeight+(3*cy1)/2,TRUE);
426 #else
427 MoveWindow((HWND) m_hWnd,x_offset,y_offset,totWidth+cx1,totHeight+cy1,TRUE);
428 #endif
429 x_offset += cx1;
430 y_offset += cy1;
431 }
432
433 #if (!CTL3D)
434 y_offset += (int)(cy1/2); // Fudge factor since buttons overlapped label
435 // JACS 2/12/93. CTL3D draws group label quite high.
436 #endif
437 int startX = x_offset;
438 int startY = y_offset;
439
440 for ( i = 0 ; i < m_noItems; i++)
441 {
442 // Bidimensional radio adjustment
443 if (i&&((i%m_majorDim)==0)) // Why is this omitted for i = 0?
444 {
445 if (m_windowStyle & wxRA_VERTICAL)
446 {
447 y_offset = startY;
448 x_offset += maxWidth + cx1;
449 }
450 else
451 {
452 x_offset = startX;
453 y_offset += maxHeight;
454 if (m_radioWidth[0]>0)
455 y_offset += cy1/2;
456 }
457 }
458 int eachWidth;
459 int eachHeight;
460 if (m_radioWidth[i]<0)
461 {
462 // It's a labeled item
463 GetWindowText((HWND) m_radioButtons[i], buf, 300);
464 GetTextExtent(buf, &current_width, &cyf,NULL,NULL, & GetFont());
465
466 // How do we find out radio button bitmap size!!
467 // By adjusting them carefully, manually :-)
468 eachWidth = (int)(current_width + RADIO_SIZE);
469 eachHeight = (int)((3*cyf)/2);
470 }
471 else
472 {
473 eachWidth = m_radioWidth[i];
474 eachHeight = m_radioHeight[i];
475 }
476
477 MoveWindow((HWND) m_radioButtons[i],x_offset,y_offset,eachWidth,eachHeight,TRUE);
478 if (m_windowStyle & wxRA_SPECIFY_ROWS)
479 {
480 y_offset += maxHeight;
481 if (m_radioWidth[0]>0)
482 y_offset += cy1/2;
483 }
484 else
485 x_offset += maxWidth + cx1;
486 }
487 }
488
489
490 void wxRadioBox::GetSize(int *width, int *height) const
491 {
492 RECT rect;
493 rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
494
495 if (m_hWnd)
496 wxFindMaxSize(m_hWnd, &rect);
497
498 int i;
499 for (i = 0; i < m_noItems; i++)
500 wxFindMaxSize(m_radioButtons[i], &rect);
501
502 *width = rect.right - rect.left;
503 *height = rect.bottom - rect.top;
504 }
505
506 void wxRadioBox::GetPosition(int *x, int *y) const
507 {
508 wxWindow *parent = GetParent();
509 RECT rect;
510 rect.left = -1; rect.right = -1; rect.top = -1; rect.bottom = -1;
511
512 int i;
513 for (i = 0; i < m_noItems; i++)
514 wxFindMaxSize(m_radioButtons[i], &rect);
515
516 if (m_hWnd)
517 wxFindMaxSize(m_hWnd, &rect);
518
519 // Since we now have the absolute screen coords,
520 // if there's a parent we must subtract its top left corner
521 POINT point;
522 point.x = rect.left;
523 point.y = rect.top;
524 if (parent)
525 {
526 ::ScreenToClient((HWND) parent->GetHWND(), &point);
527 }
528 // We may be faking the client origin.
529 // So a window that's really at (0, 30) may appear
530 // (to wxWin apps) to be at (0, 0).
531 if (GetParent())
532 {
533 wxPoint pt(GetParent()->GetClientAreaOrigin());
534 point.x -= pt.x;
535 point.y -= pt.y;
536 }
537
538 *x = point.x;
539 *y = point.y;
540 }
541
542 wxString wxRadioBox::GetLabel() const
543 {
544 if (m_hWnd)
545 {
546 GetWindowText((HWND) m_hWnd, wxBuffer, 300);
547 return wxString(wxBuffer);
548 }
549 else return wxString("");
550 }
551
552 void wxRadioBox::SetLabel(const wxString& label)
553 {
554 if (m_hWnd)
555 SetWindowText((HWND) m_hWnd, label);
556 }
557
558 void wxRadioBox::SetFocus()
559 {
560 if (m_noItems > 0)
561 {
562 if (m_selectedButton == -1)
563 ::SetFocus((HWND) m_radioButtons[0]);
564 else
565 ::SetFocus((HWND) m_radioButtons[m_selectedButton]);
566 }
567
568 }
569
570 bool wxRadioBox::Show(bool show)
571 {
572 m_isShown = show;
573 int cshow;
574 if (show)
575 cshow = SW_SHOW;
576 else
577 cshow = SW_HIDE;
578 if (m_hWnd)
579 ShowWindow((HWND) m_hWnd, cshow);
580 int i;
581 for (i = 0; i < m_noItems; i++)
582 ShowWindow((HWND) m_radioButtons[i], cshow);
583 return TRUE;
584 }
585
586 // Enable a specific button
587 void wxRadioBox::Enable(int item, bool enable)
588 {
589 if (item<0)
590 wxWindow::Enable(enable);
591 else if (item < m_noItems)
592 ::EnableWindow((HWND) m_radioButtons[item], enable);
593 }
594
595 // Enable all controls
596 void wxRadioBox::Enable(bool enable)
597 {
598 wxControl::Enable(enable);
599
600 int i;
601 for (i = 0; i < m_noItems; i++)
602 ::EnableWindow((HWND) m_radioButtons[i], enable);
603 }
604
605 // Show a specific button
606 void wxRadioBox::Show(int item, bool show)
607 {
608 if (item<0)
609 wxRadioBox::Show(show);
610 else if (item < m_noItems)
611 {
612 int cshow;
613 if (show)
614 cshow = SW_SHOW;
615 else
616 cshow = SW_HIDE;
617 ShowWindow((HWND) m_radioButtons[item], cshow);
618 }
619 }
620
621 WXHBRUSH wxRadioBox::OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor,
622 WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
623 {
624 #if wxUSE_CTL3D
625 if ( m_useCtl3D )
626 {
627 HBRUSH hbrush = Ctl3dCtlColorEx(message, wParam, lParam);
628 return (WXHBRUSH) hbrush;
629 }
630 #endif
631
632 if (GetParent()->GetTransparentBackground())
633 SetBkMode((HDC) pDC, TRANSPARENT);
634 else
635 SetBkMode((HDC) pDC, OPAQUE);
636
637 ::SetBkColor((HDC) pDC, RGB(GetBackgroundColour().Red(), GetBackgroundColour().Green(), GetBackgroundColour().Blue()));
638 ::SetTextColor((HDC) pDC, RGB(GetForegroundColour().Red(), GetForegroundColour().Green(), GetForegroundColour().Blue()));
639
640 wxBrush *backgroundBrush = wxTheBrushList->FindOrCreateBrush(GetBackgroundColour(), wxSOLID);
641
642 // Note that this will be cleaned up in wxApp::OnIdle, if backgroundBrush
643 // has a zero usage count.
644 // backgroundBrush->RealizeResource();
645 return (WXHBRUSH) backgroundBrush->GetResourceHandle();
646 }
647
648 // For single selection items only
649 wxString wxRadioBox::GetStringSelection() const
650 {
651 wxString result;
652 int sel = GetSelection();
653 if (sel > -1)
654 result = GetString(sel);
655
656 return result;
657 }
658
659 bool wxRadioBox::SetStringSelection(const wxString& s)
660 {
661 int sel = FindString (s);
662 if (sel > -1)
663 {
664 SetSelection (sel);
665 return TRUE;
666 }
667 else
668 return FALSE;
669 }
670
671 bool wxRadioBox::ContainsHWND(WXHWND hWnd) const
672 {
673 int i;
674 for (i = 0; i < Number(); i++)
675 if (GetRadioButtons()[i] == hWnd)
676 return TRUE;
677 return FALSE;
678 }
679
680 void wxRadioBox::Command (wxCommandEvent & event)
681 {
682 SetSelection (event.m_commandInt);
683 ProcessCommand (event);
684 }
685
686 long wxRadioBox::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
687 {
688 if (nMsg == WM_NCHITTEST)
689 {
690 int xPos = LOWORD(lParam); // horizontal position of cursor
691 int yPos = HIWORD(lParam); // vertical position of cursor
692
693 ScreenToClient(&xPos, &yPos);
694
695 // Make sure you can drag by the top of the groupbox, but let
696 // other (enclosed) controls get mouse events also
697 if (yPos < 10)
698 return (long)HTCLIENT;
699 }
700
701 return wxControl::MSWWindowProc(nMsg, wParam, lParam);
702 }
703
704 void wxRadioBox::SubclassRadioButton(WXHWND hWndBtn)
705 {
706 HWND hwndBtn = (HWND)hWndBtn;
707
708 if ( !s_wndprocRadioBtn )
709 s_wndprocRadioBtn = (WNDPROC)::GetWindowLong(hwndBtn, GWL_WNDPROC);
710
711 // No GWL_USERDATA in Win16, so omit this subclassing.
712 #ifdef __WIN32__
713 ::SetWindowLong(hwndBtn, GWL_WNDPROC, (long)wxRadioBtnWndProc);
714 ::SetWindowLong(hwndBtn, GWL_USERDATA, (long)this);
715 #endif
716 }
717
718 // ---------------------------------------------------------------------------
719 // window proc for radio buttons
720 // ---------------------------------------------------------------------------
721
722 #ifdef __WIN32__
723
724 LRESULT APIENTRY _EXPORT wxRadioBtnWndProc(HWND hwnd,
725 UINT msg,
726 WPARAM wParam,
727 LPARAM lParam)
728 {
729 bool processed = TRUE;
730 if ( msg != WM_KEYDOWN )
731 processed = FALSE;
732
733 if ( processed )
734 {
735 wxRadioBox *radiobox = (wxRadioBox *)::GetWindowLong(hwnd, GWL_USERDATA);
736
737 wxCHECK_MSG( radiobox, 0, "radio button without radio box?" );
738
739 int sel = radiobox->GetSelection();
740
741 switch ( wParam )
742 {
743 case VK_UP:
744 sel--;
745 break;
746
747 case VK_LEFT:
748 sel -= radiobox->GetNumVer();
749 break;
750
751 case VK_DOWN:
752 sel++;
753 break;
754
755 case VK_RIGHT:
756 sel += radiobox->GetNumVer();
757 break;
758
759 case VK_TAB:
760 {
761 wxNavigationKeyEvent event;
762 event.SetDirection(!(::GetKeyState(VK_SHIFT) & 0x100));
763 event.SetWindowChange(FALSE);
764 event.SetEventObject(radiobox);
765
766 if ( radiobox->GetEventHandler()->ProcessEvent(event) )
767 return 0;
768 }
769 // fall through
770
771 default:
772 processed = FALSE;
773 }
774
775 if ( processed )
776 {
777 if ( sel >= 0 && sel < radiobox->Number() )
778 radiobox->SetSelection(sel);
779 }
780 }
781
782 if ( !processed )
783 return ::CallWindowProc(s_wndprocRadioBtn, hwnd, msg, wParam, lParam);
784 else
785 return 0;
786 }
787 #endif
788