1 /* File: button.c -- Button type widgets
3 * Copyright (C) 1993 Johannes Ruscheinski
4 * Copyright (C) 1993 David Metcalfe
5 * Copyright (C) 1994 Alexandre Julliard
11 #include "wine/winuser16.h"
14 static void PaintGrayOnGray( HDC hDC
,HFONT hFont
,RECT
*rc
,
15 char *text
, UINT format
);
17 static void PB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
);
18 static void CB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
);
19 static void GB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
);
20 static void UB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
);
21 static void OB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
);
22 static void BUTTON_CheckAutoRadioButton( WND
*wndPtr
);
24 #define MAX_BTN_TYPE 12
26 static const WORD maxCheckState
[MAX_BTN_TYPE
] =
28 BUTTON_UNCHECKED
, /* BS_PUSHBUTTON */
29 BUTTON_UNCHECKED
, /* BS_DEFPUSHBUTTON */
30 BUTTON_CHECKED
, /* BS_CHECKBOX */
31 BUTTON_CHECKED
, /* BS_AUTOCHECKBOX */
32 BUTTON_CHECKED
, /* BS_RADIOBUTTON */
33 BUTTON_3STATE
, /* BS_3STATE */
34 BUTTON_3STATE
, /* BS_AUTO3STATE */
35 BUTTON_UNCHECKED
, /* BS_GROUPBOX */
36 BUTTON_UNCHECKED
, /* BS_USERBUTTON */
37 BUTTON_CHECKED
, /* BS_AUTORADIOBUTTON */
38 BUTTON_UNCHECKED
, /* Not defined */
39 BUTTON_UNCHECKED
/* BS_OWNERDRAW */
42 typedef void (*pfPaint
)( WND
*wndPtr
, HDC hdc
, WORD action
);
44 static const pfPaint btnPaintFunc
[MAX_BTN_TYPE
] =
46 PB_Paint
, /* BS_PUSHBUTTON */
47 PB_Paint
, /* BS_DEFPUSHBUTTON */
48 CB_Paint
, /* BS_CHECKBOX */
49 CB_Paint
, /* BS_AUTOCHECKBOX */
50 CB_Paint
, /* BS_RADIOBUTTON */
51 CB_Paint
, /* BS_3STATE */
52 CB_Paint
, /* BS_AUTO3STATE */
53 GB_Paint
, /* BS_GROUPBOX */
54 UB_Paint
, /* BS_USERBUTTON */
55 CB_Paint
, /* BS_AUTORADIOBUTTON */
56 NULL
, /* Not defined */
57 OB_Paint
/* BS_OWNERDRAW */
60 #define PAINT_BUTTON(wndPtr,style,action) \
61 if (btnPaintFunc[style]) { \
62 HDC hdc = GetDC( (wndPtr)->hwndSelf ); \
63 (btnPaintFunc[style])(wndPtr,hdc,action); \
64 ReleaseDC( (wndPtr)->hwndSelf, hdc ); }
66 #define BUTTON_SEND_CTLCOLOR(wndPtr,hdc) \
67 SendMessageA( GetParent((wndPtr)->hwndSelf), WM_CTLCOLORBTN, \
68 (hdc), (wndPtr)->hwndSelf )
70 static HBITMAP hbitmapCheckBoxes
= 0;
71 static WORD checkBoxWidth
= 0, checkBoxHeight
= 0;
74 /***********************************************************************
75 * ButtonWndProc_locked
77 * Called with window lock held.
79 static inline LRESULT WINAPI
ButtonWndProc_locked(WND
* wndPtr
, UINT uMsg
,
80 WPARAM wParam
, LPARAM lParam
)
83 HWND hWnd
= wndPtr
->hwndSelf
;
85 BUTTONINFO
*infoPtr
= (BUTTONINFO
*)wndPtr
->wExtra
;
86 LONG style
= wndPtr
->dwStyle
& 0x0f;
89 pt
.x
= LOWORD(lParam
);
90 pt
.y
= HIWORD(lParam
);
97 case BS_PUSHBUTTON
: return DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
;
98 case BS_DEFPUSHBUTTON
: return DLGC_BUTTON
| DLGC_DEFPUSHBUTTON
;
100 case BS_AUTORADIOBUTTON
: return DLGC_BUTTON
| DLGC_RADIOBUTTON
;
101 default: return DLGC_BUTTON
;
105 PAINT_BUTTON( wndPtr
, style
, ODA_DRAWENTIRE
);
109 if (!hbitmapCheckBoxes
)
112 hbitmapCheckBoxes
= LoadBitmapA(0, MAKEINTRESOURCEA(OBM_CHECKBOXES
));
113 GetObjectA( hbitmapCheckBoxes
, sizeof(bmp
), &bmp
);
114 checkBoxWidth
= bmp
.bmWidth
/ 4;
115 checkBoxHeight
= bmp
.bmHeight
/ 3;
117 if (style
< 0L || style
>= MAX_BTN_TYPE
)
118 return -1; /* abort */
119 infoPtr
->state
= BUTTON_UNCHECKED
;
121 infoPtr
->hImage
= NULL
;
128 if (btnPaintFunc
[style
])
131 HDC hdc
= wParam
? (HDC
)wParam
: BeginPaint( hWnd
, &ps
);
132 SetBkMode( hdc
, OPAQUE
);
133 (btnPaintFunc
[style
])( wndPtr
, hdc
, ODA_DRAWENTIRE
);
134 if( !wParam
) EndPaint( hWnd
, &ps
);
139 case WM_LBUTTONDBLCLK
:
140 SendMessageA( hWnd
, BM_SETSTATE
, TRUE
, 0 );
146 /* FIXME: real windows uses extra flags in the status for this */
147 if (GetCapture() != hWnd
) break;
149 if (!(infoPtr
->state
& BUTTON_HIGHLIGHTED
)) break;
150 SendMessageA( hWnd
, BM_SETSTATE
, FALSE
, 0 );
151 GetClientRect( hWnd
, &rect
);
152 if (PtInRect( &rect
, pt
))
156 case BS_AUTOCHECKBOX
:
157 SendMessageA( hWnd
, BM_SETCHECK
,
158 !(infoPtr
->state
& BUTTON_CHECKED
), 0 );
160 case BS_AUTORADIOBUTTON
:
161 SendMessageA( hWnd
, BM_SETCHECK
, TRUE
, 0 );
164 SendMessageA( hWnd
, BM_SETCHECK
,
165 (infoPtr
->state
& BUTTON_3STATE
) ? 0 :
166 ((infoPtr
->state
& 3) + 1), 0 );
169 SendMessageA( GetParent(hWnd
), WM_COMMAND
,
170 MAKEWPARAM( wndPtr
->wIDmenu
, BN_CLICKED
), hWnd
);
175 if (GetCapture() == hWnd
)
177 GetClientRect( hWnd
, &rect
);
178 SendMessageA( hWnd
, BM_SETSTATE
, PtInRect(&rect
, pt
), 0 );
183 if(style
== BS_GROUPBOX
) return HTTRANSPARENT
;
184 return DefWindowProcA( hWnd
, uMsg
, wParam
, lParam
);
187 DEFWND_SetText( wndPtr
, (LPCSTR
)lParam
);
188 if( wndPtr
->dwStyle
& WS_VISIBLE
)
189 PAINT_BUTTON( wndPtr
, style
, ODA_DRAWENTIRE
);
193 infoPtr
->hFont
= (HFONT16
)wParam
;
194 if (lParam
&& (wndPtr
->dwStyle
& WS_VISIBLE
))
195 PAINT_BUTTON( wndPtr
, style
, ODA_DRAWENTIRE
);
199 return infoPtr
->hFont
;
202 infoPtr
->state
|= BUTTON_HASFOCUS
;
203 if (style
== BS_AUTORADIOBUTTON
)
204 SendMessageA( hWnd
, BM_SETCHECK
, 1, 0 );
205 PAINT_BUTTON( wndPtr
, style
, ODA_FOCUS
);
209 infoPtr
->state
&= ~BUTTON_HASFOCUS
;
210 PAINT_BUTTON( wndPtr
, style
, ODA_FOCUS
);
211 InvalidateRect( hWnd
, NULL
, TRUE
);
214 case WM_SYSCOLORCHANGE
:
215 InvalidateRect( hWnd
, NULL
, FALSE
);
220 if ((wParam
& 0x0f) >= MAX_BTN_TYPE
) break;
221 wndPtr
->dwStyle
= (wndPtr
->dwStyle
& 0xfffffff0)
222 | (wParam
& 0x0000000f);
223 style
= wndPtr
->dwStyle
& 0x0000000f;
224 PAINT_BUTTON( wndPtr
, style
, ODA_DRAWENTIRE
);
228 oldHbitmap
= infoPtr
->hImage
;
229 if(wndPtr
->dwStyle
& BS_BITMAP
)
230 infoPtr
->hImage
= (HANDLE
) lParam
;
234 return infoPtr
->hImage
;
238 return infoPtr
->state
& 3;
242 if (wParam
> maxCheckState
[style
]) wParam
= maxCheckState
[style
];
243 if ((infoPtr
->state
& 3) != wParam
)
245 if ((style
== BS_RADIOBUTTON
) || (style
== BS_AUTORADIOBUTTON
))
248 wndPtr
->dwStyle
|= WS_TABSTOP
;
250 wndPtr
->dwStyle
&= ~WS_TABSTOP
;
252 infoPtr
->state
= (infoPtr
->state
& ~3) | wParam
;
253 PAINT_BUTTON( wndPtr
, style
, ODA_SELECT
);
255 if ((style
== BS_AUTORADIOBUTTON
) && (wParam
== BUTTON_CHECKED
))
256 BUTTON_CheckAutoRadioButton( wndPtr
);
261 return infoPtr
->state
;
267 if (infoPtr
->state
& BUTTON_HIGHLIGHTED
) break;
268 infoPtr
->state
|= BUTTON_HIGHLIGHTED
;
272 if (!(infoPtr
->state
& BUTTON_HIGHLIGHTED
)) break;
273 infoPtr
->state
&= ~BUTTON_HIGHLIGHTED
;
275 PAINT_BUTTON( wndPtr
, style
, ODA_SELECT
);
279 return DefWindowProcA(hWnd
, uMsg
, wParam
, lParam
);
284 /***********************************************************************
286 * The button window procedure. This is just a wrapper which locks
287 * the passed HWND and calls the real window procedure (with a WND*
288 * pointer pointing to the locked windowstructure).
290 LRESULT WINAPI
ButtonWndProc( HWND hWnd
, UINT uMsg
,
291 WPARAM wParam
, LPARAM lParam
)
294 WND
*wndPtr
= WIN_FindWndPtr(hWnd
);
296 res
= ButtonWndProc_locked(wndPtr
,uMsg
,wParam
,lParam
);
298 WIN_ReleaseWndPtr(wndPtr
);
302 /**********************************************************************
303 * Push Button Functions
306 static void PB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
)
311 BUTTONINFO
*infoPtr
= (BUTTONINFO
*)wndPtr
->wExtra
;
312 int xBorderOffset
, yBorderOffset
;
313 xBorderOffset
= yBorderOffset
= 0;
315 GetClientRect( wndPtr
->hwndSelf
, &rc
);
317 /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
318 if (infoPtr
->hFont
) SelectObject( hDC
, infoPtr
->hFont
);
319 BUTTON_SEND_CTLCOLOR( wndPtr
, hDC
);
320 hOldPen
= (HPEN
)SelectObject(hDC
, GetSysColorPen(COLOR_WINDOWFRAME
));
321 hOldBrush
=(HBRUSH
)SelectObject(hDC
,GetSysColorBrush(COLOR_BTNFACE
));
322 SetBkMode(hDC
, TRANSPARENT
);
323 Rectangle(hDC
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
324 if (TWEAK_WineLook
== WIN31_LOOK
)
326 SetPixel( hDC
, rc
.left
, rc
.top
, GetSysColor(COLOR_WINDOW
) );
327 SetPixel( hDC
, rc
.left
, rc
.bottom
-1, GetSysColor(COLOR_WINDOW
) );
328 SetPixel( hDC
, rc
.right
-1, rc
.top
, GetSysColor(COLOR_WINDOW
) );
329 SetPixel( hDC
, rc
.right
-1, rc
.bottom
-1, GetSysColor(COLOR_WINDOW
));
331 InflateRect( &rc
, -1, -1 );
333 if ((wndPtr
->dwStyle
& 0x000f) == BS_DEFPUSHBUTTON
)
335 Rectangle(hDC
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
336 InflateRect( &rc
, -1, -1 );
339 if (infoPtr
->state
& BUTTON_HIGHLIGHTED
)
341 /* draw button shadow: */
342 SelectObject(hDC
, GetSysColorBrush(COLOR_BTNSHADOW
));
343 PatBlt(hDC
, rc
.left
, rc
.top
, 1, rc
.bottom
-rc
.top
, PATCOPY
);
344 PatBlt(hDC
, rc
.left
, rc
.top
, rc
.right
-rc
.left
, 1, PATCOPY
);
345 rc
.left
+= 2; /* To position the text down and right */
348 rc
.right
++, rc
.bottom
++;
349 DrawEdge( hDC
, &rc
, EDGE_RAISED
, BF_RECT
);
351 /* To place de bitmap correctly */
352 xBorderOffset
+= GetSystemMetrics(SM_CXEDGE
);
353 yBorderOffset
+= GetSystemMetrics(SM_CYEDGE
);
355 rc
.right
--, rc
.bottom
--;
358 /* draw button label, if any: */
359 if (wndPtr
->text
&& wndPtr
->text
[0])
362 GetObjectA( GetSysColorBrush(COLOR_BTNFACE
), sizeof(lb
), &lb
);
363 if (wndPtr
->dwStyle
& WS_DISABLED
&&
364 GetSysColor(COLOR_GRAYTEXT
)==lb
.lbColor
)
365 /* don't write gray text on gray background */
366 PaintGrayOnGray( hDC
,infoPtr
->hFont
,&rc
,wndPtr
->text
,
367 DT_CENTER
| DT_VCENTER
);
370 SetTextColor( hDC
, (wndPtr
->dwStyle
& WS_DISABLED
) ?
371 GetSysColor(COLOR_GRAYTEXT
) :
372 GetSysColor(COLOR_BTNTEXT
) );
373 DrawTextA( hDC
, wndPtr
->text
, -1, &rc
,
374 DT_SINGLELINE
| DT_CENTER
| DT_VCENTER
);
375 /* do we have the focus? */
376 if (infoPtr
->state
& BUTTON_HASFOCUS
)
378 RECT r
= { 0, 0, 0, 0 };
381 DrawTextA( hDC
, wndPtr
->text
, -1, &r
,
382 DT_SINGLELINE
| DT_CALCRECT
);
383 xdelta
= ((rc
.right
- rc
.left
) - (r
.right
- r
.left
) - 1) / 2;
384 ydelta
= ((rc
.bottom
- rc
.top
) - (r
.bottom
- r
.top
) - 1) / 2;
385 if (xdelta
< 0) xdelta
= 0;
386 if (ydelta
< 0) ydelta
= 0;
387 InflateRect( &rc
, -xdelta
, -ydelta
);
388 DrawFocusRect( hDC
, &rc
);
393 if((wndPtr
->dwStyle
& BS_BITMAP
) && (infoPtr
->hImage
!= NULL
))
397 int yOffset
, xOffset
, imageWidth
, imageHeight
;
399 GetObjectA (infoPtr
->hImage
, sizeof(BITMAP
), &bm
);
401 /* Center the bitmap */
402 xOffset
= (((rc
.right
- rc
.left
) - 2*xBorderOffset
) - bm
.bmWidth
) / 2;
403 yOffset
= (((rc
.bottom
- rc
.top
) - 2*yBorderOffset
) - bm
.bmHeight
) / 2;
405 imageWidth
= bm
.bmWidth
;
406 imageHeight
= bm
.bmHeight
;
408 /* If the image is to big for the button */
411 imageWidth
= rc
.right
- rc
.left
- 2*xBorderOffset
-1;
412 xOffset
= xBorderOffset
;
417 imageHeight
= rc
.bottom
- rc
.top
- 2*yBorderOffset
-1;
418 yOffset
= yBorderOffset
;
421 /* Let minimum 1 space from border */
422 xOffset
++, yOffset
++;
424 hdcMem
= CreateCompatibleDC (hDC
);
425 SelectObject (hdcMem
, (HBITMAP
)infoPtr
->hImage
);
426 BitBlt(hDC
, rc
.left
+ xOffset
,
428 imageWidth
, imageHeight
,
429 hdcMem
, 0, 0, SRCCOPY
);
434 SelectObject( hDC
, hOldPen
);
435 SelectObject( hDC
, hOldBrush
);
439 /**********************************************************************
440 * PB_Paint & CB_Paint sub function [internal]
441 * Paint text using a raster brush to avoid gray text on gray
442 * background. 'format' can be a combination of DT_CENTER and
443 * DT_VCENTER to use this function in both PB_PAINT and
444 * CB_PAINT. - Dirk Thierbach
446 * FIXME: This and TEXT_GrayString should be eventually combined,
447 * so calling one common function from PB_Paint, CB_Paint and
448 * TEXT_GrayString will be enough. Also note that this
449 * function ignores the CACHE_GetPattern funcs.
452 void PaintGrayOnGray(HDC hDC
,HFONT hFont
,RECT
*rc
,char *text
,
455 /* This is the standard gray on gray pattern:
456 static const WORD Pattern[] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55};
458 /* This pattern gives better readability with X Fonts.
459 FIXME: Maybe the user should be allowed to decide which he wants. */
460 static const WORD Pattern
[] = {0x55,0xFF,0xAA,0xFF,0x55,0xFF,0xAA,0xFF};
462 HBITMAP hbm
= CreateBitmap( 8, 8, 1, 1, Pattern
);
463 HDC hdcMem
= CreateCompatibleDC(hDC
);
469 DrawTextA( hDC
, text
, -1, &rect
, DT_SINGLELINE
| DT_CALCRECT
);
470 /* now text width and height are in rect.right and rect.bottom */
472 rect
.left
= rect
.top
= 0; /* drawing pos in hdcMem */
473 if (format
& DT_CENTER
) rect
.left
=(rc
->right
-rect
.right
)/2;
474 if (format
& DT_VCENTER
) rect
.top
=(rc
->bottom
-rect
.bottom
)/2;
475 hbmMem
= CreateCompatibleBitmap( hDC
,rect
.right
,rect
.bottom
);
476 SelectObject( hdcMem
, hbmMem
);
477 PatBlt( hdcMem
,0,0,rect
.right
,rect
.bottom
,WHITENESS
);
478 /* will be overwritten by DrawText, but just in case */
479 if (hFont
) SelectObject( hdcMem
, hFont
);
480 DrawTextA( hdcMem
, text
, -1, &rc2
, DT_SINGLELINE
);
481 /* After draw: foreground = 0 bits, background = 1 bits */
482 hBr
= SelectObject( hdcMem
, CreatePatternBrush(hbm
) );
484 PatBlt( hdcMem
,0,0,rect
.right
,rect
.bottom
,0xAF0229);
485 /* only keep the foreground bits where pattern is 1 */
486 DeleteObject( SelectObject( hdcMem
,hBr
) );
487 BitBlt(hDC
,rect
.left
,rect
.top
,rect
.right
,rect
.bottom
,hdcMem
,0,0,SRCAND
);
488 /* keep the background of the dest */
490 DeleteObject( hbmMem
);
494 /**********************************************************************
495 * Check Box & Radio Button Functions
498 static void CB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
)
500 RECT rbox
, rtext
, client
;
503 BUTTONINFO
*infoPtr
= (BUTTONINFO
*)wndPtr
->wExtra
;
506 GetClientRect(wndPtr
->hwndSelf
, &client
);
507 rbox
= rtext
= client
;
509 if (infoPtr
->hFont
) SelectObject( hDC
, infoPtr
->hFont
);
511 /* Something is still not right, checkboxes (and edit controls)
512 * in wsping32 have white backgrounds instead of dark grey.
513 * BUTTON_SEND_CTLCOLOR() is even worse since it returns 0 in this
514 * particular case and the background is not painted at all.
517 hBrush
= GetControlBrush16( wndPtr
->hwndSelf
, hDC
, CTLCOLOR_BTN
);
519 if (wndPtr
->dwStyle
& BS_LEFTTEXT
)
521 /* magic +4 is what CTL3D expects */
523 rtext
.right
-= checkBoxWidth
+ 4;
524 rbox
.left
= rbox
.right
- checkBoxWidth
;
528 rtext
.left
+= checkBoxWidth
+ 4;
529 rbox
.right
= checkBoxWidth
;
532 /* Draw the check-box bitmap */
534 if (wndPtr
->text
) textlen
= strlen( wndPtr
->text
);
535 if (action
== ODA_DRAWENTIRE
|| action
== ODA_SELECT
)
537 HDC hMemDC
= CreateCompatibleDC( hDC
);
539 delta
= (rbox
.bottom
- rbox
.top
- checkBoxHeight
) >> 1;
541 if (action
== ODA_SELECT
) FillRect( hDC
, &rbox
, hBrush
);
542 else FillRect( hDC
, &client
, hBrush
);
544 if (infoPtr
->state
& BUTTON_HIGHLIGHTED
) x
+= 2 * checkBoxWidth
;
545 if (infoPtr
->state
& (BUTTON_CHECKED
| BUTTON_3STATE
)) x
+= checkBoxWidth
;
546 if (((wndPtr
->dwStyle
& 0x0f) == BS_RADIOBUTTON
) ||
547 ((wndPtr
->dwStyle
& 0x0f) == BS_AUTORADIOBUTTON
)) y
+= checkBoxHeight
;
548 else if (infoPtr
->state
& BUTTON_3STATE
) y
+= 2 * checkBoxHeight
;
550 SelectObject( hMemDC
, hbitmapCheckBoxes
);
551 BitBlt( hDC
, rbox
.left
, rbox
.top
+ delta
, checkBoxWidth
,
552 checkBoxHeight
, hMemDC
, x
, y
, SRCCOPY
);
555 if( textlen
&& action
!= ODA_SELECT
)
557 if (wndPtr
->dwStyle
& WS_DISABLED
&&
558 GetSysColor(COLOR_GRAYTEXT
)==GetBkColor(hDC
)) {
559 /* don't write gray text on gray background */
560 PaintGrayOnGray( hDC
, infoPtr
->hFont
, &rtext
, wndPtr
->text
,
563 if (wndPtr
->dwStyle
& WS_DISABLED
)
564 SetTextColor( hDC
, GetSysColor(COLOR_GRAYTEXT
) );
565 DrawTextA( hDC
, wndPtr
->text
, textlen
, &rtext
,
566 DT_SINGLELINE
| DT_VCENTER
);
567 textlen
= 0; /* skip DrawText() below */
572 if ((action
== ODA_FOCUS
) ||
573 ((action
== ODA_DRAWENTIRE
) && (infoPtr
->state
& BUTTON_HASFOCUS
)))
575 /* again, this is what CTL3D expects */
579 DrawTextA( hDC
, wndPtr
->text
, textlen
, &rbox
,
580 DT_SINGLELINE
| DT_CALCRECT
);
581 textlen
= rbox
.bottom
- rbox
.top
;
582 delta
= ((rtext
.bottom
- rtext
.top
) - textlen
)/2;
583 rbox
.bottom
= (rbox
.top
= rtext
.top
+ delta
- 1) + textlen
+ 2;
584 textlen
= rbox
.right
- rbox
.left
;
585 rbox
.right
= (rbox
.left
+= --rtext
.left
) + textlen
+ 2;
586 IntersectRect(&rbox
, &rbox
, &rtext
);
587 DrawFocusRect( hDC
, &rbox
);
592 /**********************************************************************
593 * BUTTON_CheckAutoRadioButton
595 * wndPtr is checked, uncheck every other auto radio button in group
597 static void BUTTON_CheckAutoRadioButton( WND
*wndPtr
)
599 HWND parent
, sibling
, start
;
600 if (!(wndPtr
->dwStyle
& WS_CHILD
)) return;
601 parent
= wndPtr
->parent
->hwndSelf
;
602 /* assure that starting control is not disabled or invisible */
603 start
= sibling
= GetNextDlgGroupItem( parent
, wndPtr
->hwndSelf
, TRUE
);
608 tmpWnd
= WIN_FindWndPtr(sibling
);
609 if ((wndPtr
->hwndSelf
!= sibling
) &&
610 ((tmpWnd
->dwStyle
& 0x0f) == BS_AUTORADIOBUTTON
))
611 SendMessageA( sibling
, BM_SETCHECK
, BUTTON_UNCHECKED
, 0 );
612 sibling
= GetNextDlgGroupItem( parent
, sibling
, FALSE
);
613 WIN_ReleaseWndPtr(tmpWnd
);
614 } while (sibling
!= start
);
618 /**********************************************************************
619 * Group Box Functions
622 static void GB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
)
625 BUTTONINFO
*infoPtr
= (BUTTONINFO
*)wndPtr
->wExtra
;
627 if (action
!= ODA_DRAWENTIRE
) return;
629 BUTTON_SEND_CTLCOLOR( wndPtr
, hDC
);
631 GetClientRect( wndPtr
->hwndSelf
, &rc
);
632 if (TWEAK_WineLook
== WIN31_LOOK
) {
633 HPEN hPrevPen
= SelectObject( hDC
,
634 GetSysColorPen(COLOR_WINDOWFRAME
));
635 HBRUSH hPrevBrush
= SelectObject( hDC
,
636 GetStockObject(NULL_BRUSH
) );
638 Rectangle( hDC
, rc
.left
, rc
.top
+ 2, rc
.right
- 1, rc
.bottom
- 1 );
639 SelectObject( hDC
, hPrevBrush
);
640 SelectObject( hDC
, hPrevPen
);
646 SelectObject (hDC
, infoPtr
->hFont
);
647 GetTextMetricsA (hDC
, &tm
);
648 rcFrame
.top
+= (tm
.tmHeight
/ 2) - 1;
649 DrawEdge (hDC
, &rcFrame
, EDGE_ETCHED
, BF_RECT
);
654 if (infoPtr
->hFont
) SelectObject( hDC
, infoPtr
->hFont
);
655 if (wndPtr
->dwStyle
& WS_DISABLED
)
656 SetTextColor( hDC
, GetSysColor(COLOR_GRAYTEXT
) );
658 DrawTextA( hDC
, wndPtr
->text
, -1, &rc
, DT_SINGLELINE
| DT_NOCLIP
);
663 /**********************************************************************
664 * User Button Functions
667 static void UB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
)
671 BUTTONINFO
*infoPtr
= (BUTTONINFO
*)wndPtr
->wExtra
;
673 if (action
== ODA_SELECT
) return;
675 GetClientRect( wndPtr
->hwndSelf
, &rc
);
677 if (infoPtr
->hFont
) SelectObject( hDC
, infoPtr
->hFont
);
678 hBrush
= GetControlBrush16( wndPtr
->hwndSelf
, hDC
, CTLCOLOR_BTN
);
680 FillRect( hDC
, &rc
, hBrush
);
681 if ((action
== ODA_FOCUS
) ||
682 ((action
== ODA_DRAWENTIRE
) && (infoPtr
->state
& BUTTON_HASFOCUS
)))
683 DrawFocusRect( hDC
, &rc
);
687 /**********************************************************************
688 * Ownerdrawn Button Functions
691 static void OB_Paint( WND
*wndPtr
, HDC hDC
, WORD action
)
693 BUTTONINFO
*infoPtr
= (BUTTONINFO
*)wndPtr
->wExtra
;
696 dis
.CtlType
= ODT_BUTTON
;
697 dis
.CtlID
= wndPtr
->wIDmenu
;
699 dis
.itemAction
= action
;
700 dis
.itemState
= ((infoPtr
->state
& BUTTON_HASFOCUS
) ? ODS_FOCUS
: 0) |
701 ((infoPtr
->state
& BUTTON_HIGHLIGHTED
) ? ODS_SELECTED
: 0) |
702 ((wndPtr
->dwStyle
& WS_DISABLED
) ? ODS_DISABLED
: 0);
703 dis
.hwndItem
= wndPtr
->hwndSelf
;
706 GetClientRect( wndPtr
->hwndSelf
, &dis
.rcItem
);
707 SendMessageA( GetParent(wndPtr
->hwndSelf
), WM_DRAWITEM
,
708 wndPtr
->wIDmenu
, (LPARAM
)&dis
);