]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/mwin/winlib/button.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / mwin / winlib / button.c
1 #include "windows.h"
2 #include "windowsx.h"
3 #include "wintools.h"
4 /*
5  * WINCTL Custom Control Library
6  * Push button Custom Control
7  *      This control implements a custom pushbutton control.
8  *
9  * 4/8/98 g haerr original version from control palette v2.00, Blaise Computing
10  */
11
12 #define GET_PBSTATE(h)                  (GetWindowWord(h, 0))
13 #define GET_PBCAPTURE(h)                (GetWindowWord(h, 2))
14 #define GET_PBWASINSIDE(h)              (GetWindowWord(h, 4))
15 #define GET_PBDELETEFONT(h)             (GetWindowWord(h, 6))
16 #define GET_PBFONT(h)                   (GetWindowWord(h, 8))
17
18 #define SET_PBSTATE(h,x)                (SetWindowWord(h, 0, x))
19 #define SET_PBCAPTURE(h,x)              (SetWindowWord(h, 2, x))
20 #define SET_PBWASINSIDE(h,x)            (SetWindowWord(h, 4, x))
21 #define SET_PBDELETEFONT(h,x)           (SetWindowWord(h, 6, x))
22 #define SET_PBFONT(h,x)                 (SetWindowWord(h, 8, x))
23
24 #define PARENT(hwnd)            ((HWND)GetWindowLong(hwnd,GWL_HWNDPARENT))
25
26 /* Internal state variable bit positions                                */
27 #define PUSH_UP         0x0000
28 #define PUSH_DOWN       0x0001  /* Button is down                       */
29 #define PUSH_FOCUS      0x0002  /* Button is focused                    */
30 #define PUSH_DISABLED   0x0004  /* Button is disabled                   */
31 #define PUSH_DEFAULT    0x0008  /* Button is currently a default        */
32 #define PUSH_CHECKED    0x0010
33
34 /* Push Button states */
35 #define PBS_UP          0x0000                  /* Normal button state. */
36 #define PBS_FOCUSDOWN   0x0001                  /* Button pressed.      */
37 #define PBS_FOCUSUP     0x0002                  /* Focused state.       */
38 #define PBS_DISABLED    0x0004                  /* Disabled state.      */
39 #define PBS_DEFAULT     0x0008                  /* Default state.       */
40 #define PBS_CHECKED     0x0010                  /* checked state.       */
41
42 #define WM_PAINT_SPECIAL        WM_PAINT
43 #define HANDLE_WM_PAINT_SPECIAL(hwnd, wParam, lParam, fn) \
44     ((fn)((hwnd),(HDC)(wParam)), 0L)
45
46 /* BOOL Cls_OnGetState( HWND hwnd); */
47 #define HANDLE_BM_GETSTATE(hwnd, wParam, lParam, fn) ((fn)(hwnd))
48 #define FORWARD_BM_GETSTATE(hwnd) \
49         (LONG)(fn)((hwnd), BM_GETSTATE, (WPARAM)0, (LPARAM)0)
50
51 /* void Cls_OnSetState( HWND hwnd, WORD wState); */
52 #define HANDLE_BM_SETSTATE( hwnd, wParam, lParam, fn) \
53         ((fn)((hwnd), (WORD)wParam), 0)
54 #define FORWARD_BM_SETSTATE( hwnd, wState) \
55         (fn)((hwnd), BM_SETSTATE, (WPARAM)wState, (LPARAM)0)
56
57 /* void Cls_OnSetStyle( HWND hwnd, WORD style, BOOL bRedraw); */
58 #define HANDLE_BM_SETSTYLE( hwnd, wParam, lParam, fn) \
59         ((fn)((hwnd), (WORD)wParam, (BOOL)LOWORD(lParam)), 0)
60 #define FORWARD_BM_SETSTYLE( hwnd, style, bRedraw, fn) \
61         (fn)((hwnd), BM_SETSTYLE, (WPARAM)style, MAKELPARAM(bRedraw, 0))
62
63 /* entry points*/
64 void WINAPI             CheckRadioButton(HWND hDlg, int nIDFirst,int nIDLast,
65                                 int nIDCheckButton);
66
67 /* local procs*/
68 static void WINAPI      cenButton_FnEnd( HWND, WORD);
69 static WORD WINAPI      cenButton_FnStart( HWND);
70 static BOOL WINAPI      cenButton_OnCreate( HWND, LPCREATESTRUCT);
71 /*static void WINAPI    cenButton_OnDestroy( HWND);*/
72 /*static void WINAPI    cenButton_OnEnable( HWND, BOOL);*/
73 static BOOL WINAPI      cenButton_OnEraseBkgnd( HWND, HDC);
74 /*static UINT WINAPI    cenButton_OnGetDlgCode( HWND, LPMSG);*/
75 static LONG WINAPI      cenButton_OnGetState( HWND);
76 /*static void WINAPI    cenButton_OnKey( HWND, UINT, BOOL, int, UINT);*/
77 static void WINAPI      cenButton_OnKillFocus( HWND, HWND);
78 static void WINAPI      cenButton_OnLButtonDown( HWND, BOOL, UINT, UINT, UINT);
79 static void WINAPI      cenButton_OnLButtonUp( HWND, UINT, UINT, UINT);
80 static void WINAPI      cenButton_OnMouseMove( HWND, UINT, UINT, UINT);
81 static void WINAPI      cenButton_OnPaint( HWND, HDC);
82 static void WINAPI      DrawPushButton(HWND hwnd,HDC hDCwParam,UINT wEnumState,
83                                 DWORD dwStyle);
84 static void WINAPI      DrawGroupBox(HWND hwnd,HDC hDCwParam, DWORD dwStyle);
85 static void WINAPI      cenButton_OnSetFocus( HWND, HWND);
86 static void WINAPI      cenButton_OnSetStyle( HWND, WORD, BOOL);
87 static void WINAPI      cenButton_OnSetState( HWND, WORD);
88 static void WINAPI      cenButton_SetState( HWND, WORD, BOOL);
89 static void WINAPI      cenButton_OnSetText( HWND, LPCSTR);
90
91 static void WINAPI
92 cenButton_FnEnd(
93 HWND            hwnd,
94 WORD            wState)
95 {
96         if( wState != GET_PBSTATE( hwnd)) {
97                 if( IsWindowVisible( hwnd))
98                         UpdateWindow( hwnd);
99         }
100 }
101
102 static WORD WINAPI
103 cenButton_FnStart(
104 HWND            hwnd)
105 {
106         return GET_PBSTATE( hwnd);
107 }
108
109 static BOOL WINAPI
110 cenButton_OnCreate(
111 HWND                    hwnd,
112 LPCREATESTRUCT  lpCreate)
113 {
114         /* Set initial states */
115         /*SET_PBDELETEFONT( hwnd, FALSE);*/
116         /*SET_PBFONT( hwnd, NULL);*/
117         SET_PBSTATE( hwnd, PUSH_UP );
118         SET_PBCAPTURE( hwnd, FALSE );
119         SET_PBWASINSIDE( hwnd, FALSE );
120
121         if ((lpCreate->style & 0x0f) == BS_DEFPUSHBUTTON)
122                 cenButton_SetState( hwnd, PUSH_DEFAULT, TRUE );
123
124         if (lpCreate->style & WS_DISABLED)
125                 cenButton_SetState( hwnd, PUSH_DISABLED, TRUE );
126
127         return( TRUE);
128 }
129
130 #if 0
131 static void WINAPI
132 cenButton_OnDestroy(
133 HWND            hwnd)
134 {
135         if( GET_PBDELETEFONT( hwnd)) {
136                 DeleteObject( GET_PBFONT( hwnd));
137                 SET_PBDELETEFONT( hwnd, FALSE);
138         }
139 }
140
141 static void WINAPI
142 cenButton_OnEnable(
143 HWND            hwnd,
144 BOOL            bEnable)
145 {
146         WORD            wState;
147
148         wState = cenButton_FnStart( hwnd);
149         cenButton_SetState( hwnd, PUSH_DISABLED, !bEnable);
150         cenButton_FnEnd( hwnd, wState);
151 }
152 #endif
153
154 static BOOL WINAPI
155 cenButton_OnEraseBkgnd(
156 HWND            hwnd,
157 HDC                     hdc)
158 {
159         /* Background is erased at WM_PAINT time, so return TRUE*/
160         return TRUE;
161 }
162
163 #if 0
164 static UINT WINAPI
165 cenButton_OnGetDlgCode(
166 HWND    hwnd,
167 LPMSG   lpMsg)
168 {
169         /* WM_GETDLGCODE is sent by the dialog manager to find     */
170         /* what type/style of control is responding and/or to      */
171         /* determine what keystrokes the control wants to process  */
172         /* itself.      In this case, the pushbutton identifies itself */
173         /* and also indicates whether it is currently the default  */
174         /* pushbutton.                                                                                     */
175
176         /*return( DLGC_BUTTON | ((GET_PBSTATE( hwnd) & PUSH_DEFAULT) ?
177                                 DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON));*/
178         return( DLGC_BUTTON);
179 }
180 #endif
181
182 static LONG WINAPI
183 cenButton_OnGetState(
184 HWND            hwnd)
185 {
186         /* BM_GETSTATE is sent to enquire about the state of the   */
187         /* control.      It returns TRUE if the button is in the down  */
188         /* state.                                                                                                  */
189
190         return( ( GET_PBSTATE( hwnd) & PUSH_DOWN) == PUSH_DOWN);
191 }
192
193 #if 0
194 static void WINAPI
195 cenButton_OnKey(
196 HWND            hwnd,
197 UINT            vk,
198 BOOL            bDown,
199 int                     cRepeat,
200 UINT            flag)
201 {
202         WORD            wState;
203
204         wState = cenButton_FnStart( hwnd);
205         if (bDown) {
206                 /* WM_KEYDOWN is sent when a non-system key is pressed.    */
207                 /* If a spacebar is detected and the previous key state    */
208                 /* was up, then the control should switch to the down      */
209                 /* state.                                                                                                  */
210
211                 if ( (vk == ' ') && !(HIBYTE(flag) & 0x40) )
212                         cenButton_SetState( hwnd, PUSH_DOWN, TRUE );
213         }
214         else {
215                 /* WM_KEYUP is sent when a non-system key is released.     */
216                 /* If a space bar is detected, change to the up state.  If */
217                 /* the control is the focused control, send the BN_CLICKED */
218                 /* notification message.                                                                   */
219
220                 if ( vk == ' ' )
221                 {       cenButton_SetState( hwnd, PUSH_DOWN, FALSE );
222
223                         if (GET_PBSTATE( hwnd) & PUSH_FOCUS) {
224                                 FORWARD_WM_COMMAND( PARENT( hwnd), GetDlgCtrlID( hwnd),
225                                         hwnd, BN_CLICKED, SendMessage);
226                                 if(!IsWindow(hwnd))
227                                         return;
228                         }
229                 }
230         }
231         cenButton_FnEnd( hwnd, wState);
232 }
233 #endif
234
235 static void WINAPI
236 cenButton_OnKillFocus(
237 HWND            hwnd,
238 HWND            hwndNewFocus)
239 {
240         WORD            wState;
241
242         wState = cenButton_FnStart( hwnd);
243         cenButton_SetState( hwnd, PUSH_FOCUS, FALSE );
244         cenButton_FnEnd( hwnd, wState);
245 }
246
247 static void WINAPI
248 cenButton_OnLButtonDown(
249 HWND            hwnd,
250 BOOL            bDblClick,
251 UINT            x,
252 UINT            y,
253 UINT            keyState)
254 {
255         WORD            wState;
256
257         wState = cenButton_FnStart( hwnd);
258         /* capture the mouse*/
259         SetCapture( hwnd );
260         /* set focus to ourself*/
261         SetFocus( hwnd );
262         SET_PBCAPTURE( hwnd, TRUE );
263         SET_PBWASINSIDE( hwnd, TRUE );
264         /* set down state*/
265         cenButton_SetState( hwnd, PUSH_DOWN, TRUE );
266         cenButton_FnEnd( hwnd, wState);
267 }
268
269 static void WINAPI
270 cenButton_OnLButtonUp(
271 HWND            hwnd,
272 UINT            x,
273 UINT            y,
274 UINT            keys)
275 {
276         WORD            wState;
277         DWORD           dwStyle;
278  
279         dwStyle = GetWindowLong(hwnd, GWL_STYLE);
280         wState = cenButton_FnStart( hwnd);
281
282         /* only draw up state if we captured mouse*/
283         if(GetCapture() == hwnd)
284                 cenButton_SetState( hwnd, PUSH_DOWN, FALSE );
285         /* release mouse capture*/
286         ReleaseCapture();
287
288         /* if cursor is inside control, send clicked notification to parent*/
289         if (GET_PBWASINSIDE( hwnd)) {
290                 switch((int)(dwStyle & 0x0f)) {
291                 case BS_AUTOCHECKBOX:
292                         SendMessage(hwnd,BM_SETCHECK,(wState & PBS_CHECKED)?0:1,0L);
293                         break;
294                 case BS_AUTORADIOBUTTON:
295                         CheckRadioButton(PARENT(hwnd),0,0xffff,hwnd->id);
296                         break;
297                 }
298                 FORWARD_WM_COMMAND( PARENT( hwnd), GetDlgCtrlID( hwnd), hwnd,
299                         BN_CLICKED, SendMessage);
300                 if(!IsWindow(hwnd))
301                         return;
302         }
303
304         SET_PBCAPTURE( hwnd, FALSE );
305         SET_PBWASINSIDE( hwnd, FALSE );
306         cenButton_FnEnd( hwnd, wState);
307 }
308
309 static void WINAPI
310 cenButton_OnMouseMove(
311 HWND            hwnd,
312 UINT            x,
313 UINT            y,
314 UINT            keys)
315 {
316         /* WM_MOUSEMOVE is sent at every discernable mouse                 */
317         /* movement.  It is necessary to detect this because if    */
318         /* the mouse has been captured (because of a button down   */
319         /* message), the location of the cursor needs to be                */
320         /* tracked.      If it moves out of the confines of the            */
321         /* control, the control should change to the focus/up      */
322         /* state (and retain capture.)  If the cursor then moves   */
323         /* back into the control, change back to the down state.   */
324
325         WORD            wState;
326         DWORD           dwStyle;
327
328         wState = cenButton_FnStart( hwnd);
329         dwStyle = GetWindowLong(hwnd, GWL_STYLE);
330         if( GET_PBCAPTURE( hwnd)) {
331                 if( !PtInsideWindow( hwnd, x, y) ) {
332                         if( GET_PBWASINSIDE( hwnd)) {
333                                 cenButton_SetState( hwnd, PUSH_DOWN, FALSE);
334                                 SET_PBWASINSIDE( hwnd, FALSE );
335                         }
336                 } else {
337                         if( !GET_PBWASINSIDE( hwnd) ) {
338                                 cenButton_SetState( hwnd, PUSH_DOWN, TRUE );
339                                 SET_PBWASINSIDE( hwnd, TRUE );
340                         }
341                 }
342         }
343         cenButton_FnEnd( hwnd, wState);
344 }
345
346 static void WINAPI
347 cenButton_OnPaint(
348 HWND            hwnd,
349 HDC             hDCwParam)
350 {
351         UINT            wEnumState;
352         DWORD           dwStyle;
353
354         if( GET_PBSTATE( hwnd) & PUSH_DISABLED)
355                 wEnumState = PBS_DISABLED;
356         else if( GET_PBSTATE( hwnd) & PUSH_DOWN)
357                 wEnumState = PBS_FOCUSDOWN;
358         else if( GET_PBSTATE( hwnd) & PUSH_CHECKED)
359                 wEnumState = PBS_CHECKED;
360         else
361         {
362                 if( GET_PBSTATE( hwnd) & PUSH_FOCUS)
363                         wEnumState = PBS_FOCUSUP;
364                 else
365                         wEnumState = PBS_UP;
366                 if( GET_PBSTATE( hwnd) & PUSH_DEFAULT)
367                         wEnumState |= PBS_DEFAULT;
368         }
369
370         /* common draw code for button and checkbox*/
371         dwStyle = GetWindowLong(hwnd, GWL_STYLE);
372         switch((int)(dwStyle & 0x0f)) {
373         case BS_GROUPBOX:
374                 DrawGroupBox( hwnd, hDCwParam, dwStyle);
375                 break;
376         default:
377                 DrawPushButton( hwnd, hDCwParam, wEnumState, dwStyle);
378         }
379 }
380
381 static void WINAPI
382 DrawPushButton(HWND hwnd,HDC hDCwParam,UINT wEnumState,DWORD dwStyle)
383 {
384         HDC             hdc;
385         HBRUSH          hNewBrush;
386         RECT            rect;
387         RECT            rectClient;
388         RECT            rectSave;
389         RECT            rc;
390         int             iFaceOffset = 0;
391         INT             uiHeight;
392         INT             uiWidth;
393         COLORREF        crOld;
394         COLORREF        crBkOld;
395         int             oldBkMode;
396         HFONT           hNewFont;
397         HFONT           hOldFont;
398         HPEN            hOldPen;
399         COLORREF        hOldColor;
400         PAINTSTRUCT     ps;
401         char            buf[256];
402 #define uiWidthFrame    0
403 #define uiWidthShadow   2
404
405         hdc = BeginPaint(hwnd, &ps);
406         if(!hdc)
407                 goto Return;
408
409         GetWindowText(hwnd, buf, sizeof(buf));
410         GetClientRect( hwnd, &rectClient );
411         uiWidth = rectClient.right - rectClient.left;
412         uiHeight = rectClient.bottom - rectClient.top;
413
414         hNewBrush = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
415         crOld = SetTextColor( hdc, GetSysColor( COLOR_BTNTEXT));
416         crBkOld = SetBkColor( hdc, GetSysColor( COLOR_BTNFACE));
417
418         rc = rectClient;
419         switch((int)(dwStyle & 0x0f)) {
420         case BS_PUSHBUTTON:
421         case BS_DEFPUSHBUTTON:
422                 if( wEnumState & PBS_FOCUSDOWN) {
423                         Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
424                                 GetSysColor(COLOR_WINDOWFRAME), GetSysColor(COLOR_WINDOWFRAME));
425                         InsetR(&rc, 1, 1);
426                         Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
427                                 GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNSHADOW));
428                         InsetR(&rc, 1, 1);
429                         FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE));
430                         iFaceOffset = 1;
431                 } else {
432                         if(wEnumState & PBS_DEFAULT) {
433                                 Draw3dBox(hdc, rc.left, rc.top,
434                                         rc.right-rc.left, rc.bottom-rc.top,
435                                         GetSysColor(COLOR_WINDOWFRAME),
436                                         GetSysColor(COLOR_WINDOWFRAME));
437                                 InsetR(&rc, 1, 1);
438                         }
439                         Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
440                                 GetSysColor(COLOR_BTNHIGHLIGHT),GetSysColor(COLOR_WINDOWFRAME));
441                         InsetR(&rc, 1, 1);
442                         Draw3dBox(hdc, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top,
443                                 GetSysColor(COLOR_3DLIGHT), GetSysColor(COLOR_BTNSHADOW));
444                         InsetR(&rc, 1, 1);
445                         FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE));
446                         iFaceOffset = 0;
447                 }
448                 break;
449
450         case BS_CHECKBOX:
451         case BS_AUTOCHECKBOX:
452                 FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE));
453                 /*rc.left += 2;*/
454                 /*rc.top += 2;*/
455                 rc.right = rc.left + 12;
456                 rc.bottom = rc.top + 12;
457                 /*Draw3dBox(hdc, rc.left, rc.top, 8, 8,
458                         GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_3DLIGHT));*/
459                 Draw3dInset(hdc, rc.left, rc.top, 12, 12);
460                 InsetR(&rc, 2, 2);
461                 FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNHIGHLIGHT));
462                 iFaceOffset = 1;
463                 if(wEnumState & PBS_CHECKED) {
464                         MoveToEx(hdc, rc.left, rc.top,NULL);
465                         LineTo(hdc, rc.right, rc.bottom);
466                         MoveToEx(hdc, rc.left, rc.bottom,NULL);
467                         LineTo(hdc, rc.right, rc.top);
468                 }
469                 break;
470
471         case BS_AUTORADIOBUTTON:
472         case BS_RADIOBUTTON:
473                 FastFillRect(hdc, &rc, GetSysColor(COLOR_BTNFACE));
474                 rc.left = 0;
475                 rc.top += 1;
476                 rc.right = rc.left + 10;
477                 rc.bottom = rc.top + 10;
478
479                 SelectObject(hdc, GetStockObject(NULL_BRUSH));
480                 hOldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1,
481                         GetSysColor(COLOR_BTNSHADOW)));
482                 SelectObject(hdc, GetStockObject(WHITE_BRUSH));
483                 Ellipse(hdc,rc.left,rc.top, rc.right,rc.bottom);
484                 InsetR(&rc, 1, 1);
485
486                 SelectObject(hdc, GetStockObject(WHITE_BRUSH));
487                 DeleteObject(SelectObject(hdc, 
488                         CreatePen(PS_SOLID, 1,GetSysColor(COLOR_WINDOWFRAME))));
489                 Ellipse(hdc,rc.left,rc.top, rc.right,rc.bottom);
490                 DeleteObject(SelectObject(hdc, hOldPen));
491
492                 iFaceOffset = 0;
493                 if(wEnumState & PBS_CHECKED)
494                         Ellipse(hdc, rc.left+2, rc.top+2, rc.right-2,
495                                         rc.bottom-2);
496                 break;
497         }
498
499         /*
500          * draw text
501          */
502         if(buf[ 0]) {
503                 hNewFont = GetStockObject( DEFAULT_GUI_FONT);
504                 hOldFont = SelectObject( hdc, hNewFont);
505
506                 /* calculate text bounding rect*/
507                 rect.left = 0;
508                 rect.top = 0;
509                 DrawText( hdc, buf, -1, &rect, DT_CALCRECT | DT_LEFT |
510                         DT_SINGLELINE | DT_TOP);
511                 rectSave = rect;
512
513                 /*
514                  * calculate text draw location
515                  */
516                 switch((int)(dwStyle & (BS_LEFT|BS_CENTER|BS_RIGHT))) {
517                 case BS_CENTER:
518                 default:
519                         rect.left = (uiWidth - (rect.right - rect.left)) / 2
520                                 + iFaceOffset;
521                         break; 
522                 case BS_LEFT:
523                         rect.left = uiWidthFrame + uiWidthShadow + 2
524                                 + iFaceOffset;
525                         break;
526                 case BS_RIGHT:
527                         rect.left = (rect.right - rect.left) + uiWidthFrame
528                                 + uiWidthShadow + 4 + iFaceOffset;
529                         break;
530                 }
531
532                 switch((int)(dwStyle & 0x0f)) {
533                 case BS_CHECKBOX:
534                 case BS_AUTOCHECKBOX:
535                 case BS_AUTORADIOBUTTON:
536                 case BS_RADIOBUTTON:
537                         rect.left = 12;
538                         break;
539                 }
540
541                 rect.right += rect.left - rectSave.left;
542
543                 switch((int)(dwStyle & (BS_TOP|BS_VCENTER|BS_BOTTOM))) {
544                 case BS_VCENTER:
545                 default:
546                         rect.top = (uiHeight - (rect.bottom - rect.top)) / 2
547                                 + iFaceOffset;
548                         break;
549                 case BS_TOP:
550                         rect.top = 2 + uiWidthFrame + uiWidthShadow
551                                 + iFaceOffset;
552                         break;
553                 case BS_BOTTOM:
554                         rect.top = uiHeight - uiWidthFrame - uiWidthShadow -
555                                 (rect.bottom - rect.top) - 1 + iFaceOffset;
556                         break;
557                 }
558                 switch((int)(dwStyle & 0x0f)) {
559                 case BS_CHECKBOX:
560                 case BS_AUTOCHECKBOX:
561                 case BS_AUTORADIOBUTTON:
562                 case BS_RADIOBUTTON:
563                         rect.top = 0;
564                         break;
565                 }
566                 rect.bottom += rect.top - rectSave.top;
567
568                 oldBkMode = SetBkMode( hdc, TRANSPARENT);
569                 if(wEnumState & PBS_DISABLED)
570                         hOldColor = SetTextColor( hdc,
571                                 GetSysColor( COLOR_GRAYTEXT));
572                 else
573                         hOldColor = SetTextColor( hdc,
574                                 GetSysColor( COLOR_BTNTEXT));
575
576                 DrawText( hdc, buf, -1, &rect,DT_LEFT | DT_SINGLELINE | DT_TOP);
577
578                 SetBkMode( hdc, oldBkMode);
579                 SetTextColor( hdc, hOldColor);
580                 SelectObject( hdc, hOldFont);
581         }
582
583 #if 0
584         if( (!(wEnumState&PBS_CHECKED) && (wEnumState&PBS_FOCUSDOWN)) || 
585                                                 (wEnumState & PBS_FOCUSUP)) {
586                 rect = rectClient;
587                 uiWidth = uiWidthFrame + uiWidthShadow + 2;
588                 rect.left += uiWidth;
589                 rect.top += uiWidth;
590                 rect.right -= uiWidth;
591                 rect.bottom -= uiWidth;
592                 if((dwStyle & (BS_FLAT|BS_NOFOCUSRECT)) == 0)
593                         DrawFocusRect( hdc, &rect);
594         }
595 #endif
596
597         SetTextColor( hdc, crOld);
598         SetBkColor( hdc, crBkOld);
599
600 Return:
601         EndPaint(hwnd, &ps);
602 }
603
604 static void WINAPI
605 cenButton_OnSetFocus(
606 HWND            hwnd,
607 HWND            hwndOldFocus)
608 {
609         /* WM_SETFOCUS is sent when the user clicks on the control */
610         /* or when the dialog manager determines that a keystroke  */
611         /* should cause the control to be focused.      This affects   */
612         /* the appearance of the control so the state is saved for */
613         /* future drawing.                                                                                 */
614
615         WORD            wState;
616
617         wState = cenButton_FnStart( hwnd);
618         /*if(!IsWindowEnabled(hwnd))
619                 cenButton_SetState( hwnd, PUSH_FOCUS, TRUE );*/
620         cenButton_FnEnd( hwnd, wState);
621 }
622
623 static void WINAPI
624 cenButton_OnSetStyle(
625 HWND            hwnd,
626 WORD            style,
627 BOOL            bRedraw)
628 {
629         WORD            wState;
630
631         wState = cenButton_FnStart( hwnd);
632         cenButton_SetState( hwnd, PUSH_DEFAULT,
633                 (style & 0x0f) == BS_DEFPUSHBUTTON);
634         cenButton_FnEnd( hwnd, wState);
635 }
636
637 static void WINAPI
638 cenButton_OnSetState(
639 HWND            hwnd,
640 WORD            wState)
641 {
642         WORD            wStateOld;
643
644         wStateOld = cenButton_FnStart( hwnd);
645         cenButton_SetState( hwnd, PUSH_DOWN, (wState ? TRUE : FALSE ) );
646         cenButton_FnEnd( hwnd, wStateOld);
647 }
648
649 static void WINAPI
650 cenButton_SetState(
651 HWND    hwnd,
652 WORD    wState,
653 BOOL    bEnable )
654 {
655         /* Turn on/off state bits according to the bEnable flag.  If the   */
656         /* new state is different, invalidate the client window so that    */
657         /* the proper bitmap is displayed.                                                                 */
658
659         WORD    wNewState;
660         WORD    wOldState;
661         RECT    rectClient;
662
663         wOldState = GET_PBSTATE( hwnd);
664         wNewState = (bEnable ? (wOldState | wState) : (wOldState & ~wState));
665
666         if (wOldState != wNewState)
667         {       SET_PBSTATE( hwnd, wNewState );
668                 GetClientRect(hwnd, &rectClient);
669                 InvalidateRect(hwnd, &rectClient, FALSE);
670         }
671 }
672
673 #if 0
674 static void WINAPI
675 cenButton_OnSetFont(
676 HWND            hwnd,
677 HFONT           hFont,
678 BOOL            bRedraw)
679 {
680         BOOL            bDeleteFont = FALSE;
681         HFONT           hFontNew = 0;
682         LOGFONT         logFont;
683
684         /* create a thin font*/
685         if( GetObject( hFont, sizeof( logFont), &logFont) != 0) {
686                 if( logFont.lfWeight != FW_NORMAL) {
687                         logFont.lfWeight = FW_NORMAL;
688                         if( ( hFontNew = CreateFontIndirect( &logFont)) != 0) {
689                                 hFont = hFontNew;
690                                 bDeleteFont = TRUE;
691                         }
692                 }
693         }
694
695         if( GET_PBDELETEFONT( hwnd))
696                 DeleteObject( GET_PBFONT( hwnd));
697
698         SET_PBDELETEFONT( hwnd, bDeleteFont);
699         SET_PBFONT( hwnd, hFont);
700
701         FORWARD_WM_SETFONT( hwnd, hFont, bRedraw, DefWindowProc);
702 }
703 #endif
704
705 static void WINAPI
706 cenButton_OnSetText(
707 HWND            hwnd,
708 LPCSTR          lpszText)
709 {
710         /* WM_SETTEXT is sent to change the text of the button     */
711         /* control.      In this case we allow the default window proc */
712         /* to handle the message first.  But this only affects the */
713         /* internal Windows data structure of the control, it does */
714         /* not display the change.      To do this we invalidate and   */
715         /* update the client area of the control which displays    */
716         /* the new text.                                                                                   */
717
718         FORWARD_WM_SETTEXT( hwnd, lpszText, DefWindowProc);
719         InvalidateRect( hwnd, NULL, FALSE);
720         UpdateWindow( hwnd);
721 }
722
723 LRESULT CALLBACK
724 cenButtonWndFn(
725 HWND    hwnd,
726 UINT    message,
727 WPARAM  wParam,
728 LPARAM  lParam)
729 {
730         /* This is the window proc for the pushbutton control.  Most of    */
731         /* the drawing is accomplished in the DrawPushButton() function. */
732         /* The code below is mainly concerned with the keyboard and mouse  */
733         /* events that the control detects.                                                                */
734
735         switch( message) {
736         HANDLE_MSG( hwnd, WM_CREATE, cenButton_OnCreate);
737         /*HANDLE_MSG( hwnd, WM_ENABLE, cenButton_OnEnable);*/
738         HANDLE_MSG( hwnd, WM_SETFOCUS, cenButton_OnSetFocus);
739         HANDLE_MSG( hwnd, WM_KILLFOCUS, cenButton_OnKillFocus);
740         HANDLE_MSG( hwnd, WM_LBUTTONDOWN, cenButton_OnLButtonDown);
741         HANDLE_MSG( hwnd, WM_LBUTTONDBLCLK, cenButton_OnLButtonDown);
742         HANDLE_MSG( hwnd, WM_LBUTTONUP, cenButton_OnLButtonUp);
743         HANDLE_MSG( hwnd, WM_MOUSEMOVE, cenButton_OnMouseMove);
744         /*HANDLE_MSG( hwnd, WM_KEYDOWN, cenButton_OnKey);*/
745         /*HANDLE_MSG( hwnd, WM_KEYUP, cenButton_OnKey);*/
746         HANDLE_MSG( hwnd, WM_ERASEBKGND, cenButton_OnEraseBkgnd);
747         HANDLE_MSG( hwnd, WM_PAINT_SPECIAL, cenButton_OnPaint);
748         /*HANDLE_MSG( hwnd, WM_GETDLGCODE, cenButton_OnGetDlgCode);*/
749         HANDLE_MSG( hwnd, BM_SETSTYLE, cenButton_OnSetStyle);
750         HANDLE_MSG( hwnd, BM_GETSTATE, cenButton_OnGetState);
751         HANDLE_MSG( hwnd, BM_SETSTATE, cenButton_OnSetState);
752         /*HANDLE_MSG( hwnd, WM_DESTROY, cenButton_OnDestroy);*/
753         /*HANDLE_MSG( hwnd, WM_SETFONT, cenButton_OnSetFont);*/
754         HANDLE_MSG( hwnd, WM_SETTEXT, cenButton_OnSetText);
755
756         case BM_GETCHECK:
757 #if 0
758                 return cenButton_OnGetState(hwnd);
759 #else 
760                 return( ( GET_PBSTATE(hwnd) & PUSH_CHECKED) == PUSH_CHECKED);
761 #endif
762
763         case BM_SETCHECK:
764 #if 0
765                 cenButton_OnSetState(hwnd, (WORD)wParam);
766 #else
767 {
768                 WORD            wStateOld;
769
770                 wStateOld = cenButton_FnStart( hwnd);
771                 cenButton_SetState( hwnd, PUSH_CHECKED,
772                         ((WORD)wParam ? TRUE : FALSE) );
773                 cenButton_FnEnd( hwnd, wStateOld);
774 }
775 #endif
776                 return 0;
777         }
778
779         return DefWindowProc( hwnd, message, wParam, lParam);
780 }
781
782 /* backwards compatibility*/
783 int WINAPI
784 MwButtonRegister(HINSTANCE hInstance)
785 {
786         return MwRegisterButtonControl(hInstance);
787 }
788
789 int WINAPI
790 MwRegisterButtonControl(HINSTANCE hInstance)
791 {
792         WNDCLASS        wc;
793
794         wc.style        = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS;
795         wc.lpfnWndProc  = (WNDPROC)cenButtonWndFn;
796         wc.cbClsExtra   = 0;
797         wc.cbWndExtra   = 10;
798         wc.hInstance    = hInstance;
799         wc.hIcon        = NULL;
800         wc.hCursor      = 0; /*LoadCursor(NULL, IDC_ARROW);*/
801         wc.hbrBackground= GetStockObject(LTGRAY_BRUSH);
802         wc.lpszMenuName = NULL;
803         wc.lpszClassName= "BUTTON";
804
805         return RegisterClass(&wc);
806 }
807
808 static void WINAPI
809 DrawGroupBox(HWND hwnd,HDC hDCwParam,DWORD dwStyle)
810 {
811         HDC             hdc;
812         HFONT           hFont;
813         RECT            rcClient;
814         RECT            rcText;
815         RECT            rc;
816         PAINTSTRUCT     ps;
817         char            buf[256];
818         HPEN            hPenTop, hPenBottom, holdPen;
819         COLORREF        crTop,crBottom;
820
821
822         hdc = BeginPaint(hwnd, &ps);
823         if(!hdc)
824                 goto Return;
825
826         GetWindowText(hwnd, buf, sizeof(buf));
827         GetClientRect( hwnd, &rcClient );
828
829         hFont = GetStockObject( DEFAULT_GUI_FONT);
830         if (hFont)
831                 hFont = SelectObject(hdc,hFont);
832
833         rc.left = 0;
834         rc.top = 0;
835         DrawText( hdc, buf, -1, &rc, DT_CALCRECT);
836
837         if(buf[ 0]) {
838                 SetTextColor(hdc,GetSysColor(COLOR_WINDOWTEXT));
839                 SetBkMode(hdc,TRANSPARENT);
840                 SetRect(&rcText,8,2,rc.right+8,rc.bottom+2);
841                 DrawText(hdc,buf,-1,&rcText,DT_CENTER);
842         }
843
844         crTop=GetSysColor(COLOR_BTNHIGHLIGHT);
845         crBottom=GetSysColor(COLOR_BTNSHADOW);
846
847         hPenTop = CreatePen( PS_SOLID, 1, crTop);
848         hPenBottom = CreatePen( PS_SOLID, 1, crBottom);
849         holdPen = SelectObject( hdc, hPenTop);
850
851         MoveToEx(hdc,0,rc.bottom/2,NULL);
852
853         if(buf[ 0]) {
854                 LineTo(hdc,5,rc.bottom/2);
855                 MoveToEx(hdc,rc.right+11,rc.bottom/2,NULL);
856                 LineTo(hdc,rcClient.right-1,rc.bottom/2);
857         }
858         else
859                 LineTo(hdc,rcClient.right-1,rc.bottom/2);
860
861         LineTo(hdc,rcClient.right-1,rcClient.bottom-1);
862
863         SelectObject( hdc, hPenBottom);
864         LineTo(hdc,rcClient.left,rcClient.bottom-1);
865         LineTo(hdc,rcClient.left,rc.bottom/2);
866
867         SelectObject( hdc, holdPen);
868         DeleteObject( hPenTop);
869         DeleteObject( hPenBottom);
870
871         if (hFont)
872                 SelectObject(hdc,hFont);
873
874 Return:
875         EndPaint(hwnd, &ps);
876 }
877
878 /* temporarily here, should move to winuser.c*/
879 void WINAPI
880 CheckRadioButton(HWND hDlg, int nIDFirst,int nIDLast,int nIDCheckButton)
881 {
882         HWND    hWndCheck,hWndTemp;
883         DWORD   dwStyle;
884
885         if (!(hWndCheck = GetDlgItem(hDlg,nIDCheckButton)))
886             return;
887
888         for(hWndTemp=hDlg->children; hWndTemp; hWndTemp=hWndTemp->siblings) {
889                 if(hWndCheck == hWndTemp) continue;
890                 dwStyle = GetWindowLong(hWndTemp,GWL_STYLE);
891                 if ((hWndTemp->id >= (WORD)nIDFirst) && 
892                     (hWndTemp->id <= (WORD)nIDLast) &&
893                         ((LOWORD(dwStyle) == BS_RADIOBUTTON) ||
894                          (LOWORD(dwStyle) == BS_AUTORADIOBUTTON)))
895                         SendMessage(hWndTemp,BM_SETCHECK,FALSE,0);
896         }
897         SendMessage(hWndCheck,BM_SETCHECK,TRUE,0);
898 }