Release 940405
[wine/gsoc-2012-control.git] / controls / button.c
blobf58057b261e454f16e4d988b7941fa7a613c24d0
1 /* File: button.c -- Button type widgets
3 * Copyright (C) 1993 Johannes Ruscheinski
4 * Copyright (C) 1993 David Metcalfe
5 */
7 static char Copyright1[] = "Copyright Johannes Ruscheinski, 1993";
8 static char Copyright2[] = "Copyright David Metcalfe, 1993";
10 #include <windows.h>
11 #include "win.h"
12 #include "user.h"
14 LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
16 static COLORREF color_windowtext, color_windowframe, color_btnface,
17 color_btnshadow, color_btntext, color_btnhighlight;
19 static BOOL pressed;
21 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
22 SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
23 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
24 #define DIM(array) ((sizeof array)/(sizeof array[0]))
26 static LONG PB_Paint(HWND hWnd);
27 static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
28 static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
29 static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
30 static LONG PB_KillFocus(HWND hwnd);
31 static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc);
32 static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc);
33 static LONG CB_Paint(HWND hWnd);
34 static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
35 static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
36 static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
37 static LONG CB_KillFocus(HWND hWnd);
38 static LONG CB_SetCheck(HWND hWnd, WORD wParam);
39 static LONG CB_GetCheck(HWND hWnd);
40 static LONG RB_Paint(HWND hWnd);
41 static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
42 static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
43 static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
44 static LONG RB_KillFocus(HWND hWnd);
45 static LONG RB_SetCheck(HWND hWnd, WORD wParam);
46 static LONG RB_GetCheck(HWND hWnd);
47 static LONG GB_Paint(HWND hWnd);
48 static LONG UB_Paint(HWND hWnd);
49 static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
50 static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
51 static LONG UB_KillFocus(HWND hWnd);
52 static LONG OB_Paint(HWND hWnd);
53 static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
54 static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
55 static LONG OB_KillFocus(HWND hWnd);
57 typedef struct
59 LONG (*paintfn)();
60 LONG (*lButtonDownfn)();
61 LONG (*lButtonUpfn)();
62 LONG (*lButtonDblClkfn)();
63 LONG (*killFocusfn)();
64 LONG (*setCheckfn)();
65 LONG (*getCheckfn)();
66 } BTNFN;
68 #define MAX_BTN_TYPE 12
70 static BTNFN btnfn[MAX_BTN_TYPE] =
73 (LONG(*)())PB_Paint, /* BS_PUSHBUTTON */
74 (LONG(*)())PB_LButtonDown,
75 (LONG(*)())PB_LButtonUp,
76 (LONG(*)())PB_LButtonDblClk,
77 (LONG(*)())PB_KillFocus,
78 (LONG(*)())NULL,
79 (LONG(*)())NULL
82 (LONG(*)())PB_Paint, /* BS_DEFPUSHBUTTON */
83 (LONG(*)())PB_LButtonDown,
84 (LONG(*)())PB_LButtonUp,
85 (LONG(*)())PB_LButtonDblClk,
86 (LONG(*)())PB_KillFocus,
87 (LONG(*)())NULL,
88 (LONG(*)())NULL
91 (LONG(*)())CB_Paint, /* BS_CHECKBOX */
92 (LONG(*)())CB_LButtonDown,
93 (LONG(*)())CB_LButtonUp,
94 (LONG(*)())CB_LButtonDblClk,
95 (LONG(*)())CB_KillFocus,
96 (LONG(*)())CB_SetCheck,
97 (LONG(*)())CB_GetCheck
100 (LONG(*)())CB_Paint, /* BS_AUTOCHECKBOX */
101 (LONG(*)())CB_LButtonDown,
102 (LONG(*)())CB_LButtonUp,
103 (LONG(*)())CB_LButtonDblClk,
104 (LONG(*)())CB_KillFocus,
105 (LONG(*)())CB_SetCheck,
106 (LONG(*)())CB_GetCheck
109 (LONG(*)())RB_Paint, /* BS_RADIOBUTTON */
110 (LONG(*)())RB_LButtonDown,
111 (LONG(*)())RB_LButtonUp,
112 (LONG(*)())RB_LButtonDblClk,
113 (LONG(*)())RB_KillFocus,
114 (LONG(*)())RB_SetCheck,
115 (LONG(*)())RB_GetCheck
118 (LONG(*)())CB_Paint, /* BS_3STATE */
119 (LONG(*)())CB_LButtonDown,
120 (LONG(*)())CB_LButtonUp,
121 (LONG(*)())CB_LButtonDblClk,
122 (LONG(*)())CB_KillFocus,
123 (LONG(*)())CB_SetCheck,
124 (LONG(*)())CB_GetCheck
127 (LONG(*)())CB_Paint, /* BS_AUTO3STATE */
128 (LONG(*)())CB_LButtonDown,
129 (LONG(*)())CB_LButtonUp,
130 (LONG(*)())CB_LButtonDblClk,
131 (LONG(*)())CB_KillFocus,
132 (LONG(*)())CB_SetCheck,
133 (LONG(*)())CB_GetCheck
136 (LONG(*)())GB_Paint, /* BS_GROUPBOX */
137 (LONG(*)())NULL,
138 (LONG(*)())NULL,
139 (LONG(*)())NULL,
140 (LONG(*)())NULL,
141 (LONG(*)())NULL,
142 (LONG(*)())NULL
145 (LONG(*)())UB_Paint, /* BS_USERBUTTON */
146 (LONG(*)())UB_LButtonDown,
147 (LONG(*)())UB_LButtonUp,
148 (LONG(*)())NULL,
149 (LONG(*)())UB_KillFocus,
150 (LONG(*)())NULL,
151 (LONG(*)())NULL
154 (LONG(*)())RB_Paint, /* BS_AUTORADIOBUTTON */
155 (LONG(*)())RB_LButtonDown,
156 (LONG(*)())RB_LButtonUp,
157 (LONG(*)())RB_LButtonDblClk,
158 (LONG(*)())RB_KillFocus,
159 (LONG(*)())RB_SetCheck,
160 (LONG(*)())RB_GetCheck
163 (LONG(*)())NULL, /* Not defined */
164 (LONG(*)())NULL,
165 (LONG(*)())NULL,
166 (LONG(*)())NULL,
167 (LONG(*)())NULL,
168 (LONG(*)())NULL,
169 (LONG(*)())NULL
172 (LONG(*)())OB_Paint, /* BS_OWNERDRAW */
173 (LONG(*)())OB_LButtonDown,
174 (LONG(*)())OB_LButtonUp,
175 (LONG(*)())NULL,
176 (LONG(*)())OB_KillFocus,
177 (LONG(*)())NULL,
178 (LONG(*)())NULL
183 LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
185 LONG lResult = 0;
186 HDC hDC;
187 RECT rc;
189 WND *wndPtr = WIN_FindWndPtr(hWnd);
190 LONG style = wndPtr->dwStyle & 0x0000000F;
192 switch (uMsg) {
193 /* case WM_GETDLGCODE:
194 lResult = DLGC_BUTTON;
195 break;
197 case WM_ENABLE:
198 InvalidateRect(hWnd, NULL, FALSE);
199 break;
201 case WM_CREATE:
202 if (style < 0L || style >= (LONG)DIM(btnfn))
203 lResult = -1L;
204 else
206 /* initialise colours used for button rendering: */
207 color_windowtext = GetSysColor(COLOR_WINDOWTEXT);
208 color_windowframe = GetSysColor(COLOR_WINDOWFRAME);
209 color_btnface = GetSysColor(COLOR_BTNFACE);
210 color_btnshadow = GetSysColor(COLOR_BTNSHADOW);
211 color_btntext = GetSysColor(COLOR_BTNTEXT);
212 color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
214 (WORD)(*(wndPtr->wExtra)) = 0;
215 pressed = FALSE;
216 lResult = 0L;
218 break;
220 case WM_PAINT:
221 if (btnfn[style].paintfn)
222 (btnfn[style].paintfn)(hWnd);
223 break;
225 case WM_LBUTTONDOWN:
226 if (btnfn[style].lButtonDownfn)
227 (btnfn[style].lButtonDownfn)(hWnd, wParam, lParam);
228 break;
230 case WM_LBUTTONUP:
231 if (btnfn[style].lButtonUpfn)
232 (btnfn[style].lButtonUpfn)(hWnd, wParam, lParam);
233 break;
235 case WM_LBUTTONDBLCLK:
236 if (btnfn[style].lButtonDblClkfn)
237 (btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam);
238 break;
240 case WM_SETFOCUS:
241 break;
243 case WM_KILLFOCUS:
244 if (btnfn[style].killFocusfn)
245 (btnfn[style].killFocusfn)(hWnd);
246 break;
248 case WM_SYSCOLORCHANGE:
249 color_windowtext = GetSysColor(COLOR_WINDOWTEXT);
250 color_windowframe = GetSysColor(COLOR_WINDOWFRAME);
251 color_btnface = GetSysColor(COLOR_BTNFACE);
252 color_btnshadow = GetSysColor(COLOR_BTNSHADOW);
253 color_btntext = GetSysColor(COLOR_BTNTEXT);
254 color_btnhighlight = GetSysColor(COLOR_BTNHIGHLIGHT);
255 InvalidateRect(hWnd, NULL, TRUE);
256 break;
258 case BM_SETCHECK:
259 if (btnfn[style].setCheckfn)
260 (btnfn[style].setCheckfn)(hWnd, wParam);
261 break;
263 case BM_GETCHECK:
264 if (btnfn[style].getCheckfn)
265 return (btnfn[style].getCheckfn)(hWnd);
266 break;
268 default:
269 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
270 break;
273 GlobalUnlock(hWnd);
274 return lResult;
278 /**********************************************************************
279 * Push Button Functions
282 static LONG PB_Paint(HWND hWnd)
284 PAINTSTRUCT ps;
285 RECT rc;
286 HDC hDC;
288 hDC = BeginPaint(hWnd, &ps);
289 GetClientRect(hWnd, &rc);
290 if (pressed)
291 DrawPressedPushButton(hDC, hWnd, rc);
292 else
293 DrawRaisedPushButton(hDC, hWnd, rc);
294 EndPaint(hWnd, &ps);
297 static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
299 /* SetFocus(hWnd); */
300 SetCapture(hWnd);
301 pressed = TRUE;
302 InvalidateRect(hWnd, NULL, FALSE);
303 UpdateWindow(hWnd);
306 static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
308 RECT rc;
310 pressed = FALSE;
311 ReleaseCapture();
312 GetClientRect(hWnd, &rc);
313 if (PtInRect(&rc, MAKEPOINT(lParam)))
314 NOTIFY_PARENT(hWnd, BN_CLICKED);
315 InvalidateRect(hWnd, NULL, FALSE);
316 UpdateWindow(hWnd);
319 static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
321 RECT rc;
323 GetClientRect(hWnd, &rc);
324 if (PtInRect(&rc, MAKEPOINT(lParam)))
325 NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
328 static LONG PB_KillFocus(HWND hWnd)
330 pressed = FALSE;
331 InvalidateRect(hWnd, NULL, FALSE);
332 UpdateWindow(hWnd);
335 static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
337 HPEN hOldPen, hFramePen;
338 HBRUSH hOldBrush, hShadowBrush, hHighlightBrush, hBackgrndBrush;
339 HRGN rgn1, rgn2, rgn;
340 int len;
341 static char text[50+1];
342 POINT points[6];
343 DWORD dwTextSize;
344 int delta;
345 TEXTMETRIC tm;
346 int i;
348 hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
349 hBackgrndBrush = CreateSolidBrush(color_btnface);
351 hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
352 hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
353 SetBkMode(hDC, TRANSPARENT);
355 rgn = CreateRectRgn(0, 0, 0, 0);
356 rgn1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
358 SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
359 MAKELPARAM(hButton, CTLCOLOR_BTN));
360 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
362 /* draw button label, if any: */
363 len = GetWindowText(hButton, text, sizeof text);
364 if (len >= 1) {
365 rc.left--; rc.bottom--;
366 DrawText(hDC, text, len, &rc,
367 DT_SINGLELINE | DT_CENTER| DT_VCENTER);
370 /* draw button highlight */
371 points[0].x = rc.left+2;
372 points[0].y = rc.bottom;
373 points[1].x = rc.left+4;
374 points[1].y = rc.bottom-2;
375 points[2].x = rc.left+4;
376 points[2].y = rc.top+3;
377 points[3].x = rc.right-3;
378 points[3].y = rc.top+3;
379 points[4].x = rc.right-1;
380 points[4].y = rc.top+1;
381 points[5].x = rc.left+2;
382 points[5].y = rc.top+1;
383 hHighlightBrush = CreateSolidBrush(color_btnhighlight);
384 rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
385 CombineRgn(rgn, rgn1, rgn2, RGN_AND);
386 FillRgn(hDC, rgn2, hHighlightBrush);
388 /* draw button shadow: */
389 points[0].x = rc.left+2;
390 points[0].y = rc.bottom;
391 points[1].x = rc.left+4;
392 points[1].y = rc.bottom-2;
393 points[2].x = rc.right-3;
394 points[2].y = rc.bottom-2;
395 points[3].x = rc.right-3;
396 points[3].y = rc.top+3;
397 points[4].x = rc.right-1;
398 points[4].y = rc.top;
399 points[5].x = rc.right-1;
400 points[5].y = rc.bottom;
401 hShadowBrush = CreateSolidBrush(color_btnshadow);
402 rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
403 CombineRgn(rgn, rgn1, rgn2, RGN_AND);
404 FillRgn(hDC, rgn2, hShadowBrush);
406 /* do we have the focus? */
407 if (len >= 1 && GetFocus() == hButton) {
408 dwTextSize = GetTextExtent(hDC, text, len);
409 delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
410 rc.left += delta; rc.right -= delta;
411 GetTextMetrics(hDC, &tm);
412 delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
413 rc.top += delta; rc.bottom -= delta;
414 DrawFocusRect(hDC, &rc);
417 SelectObject(hDC, (HANDLE)hOldPen);
418 SelectObject(hDC, (HANDLE)hOldBrush);
419 DeleteObject((HANDLE)hFramePen);
420 DeleteObject((HANDLE)hShadowBrush);
421 DeleteObject((HANDLE)hBackgrndBrush);
422 DeleteObject((HANDLE)rgn1);
423 DeleteObject((HANDLE)rgn2);
424 DeleteObject((HANDLE)rgn);
428 static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
430 HPEN hOldPen, hShadowPen, hFramePen;
431 HBRUSH hOldBrush, hBackgrndBrush;
432 HRGN rgn1, rgn2, rgn;
433 int len;
434 static char text[50+1];
435 DWORD dwTextSize;
436 int delta;
437 TEXTMETRIC tm;
439 hFramePen = CreatePen(PS_SOLID, 1, color_windowframe);
440 hBackgrndBrush = CreateSolidBrush(color_btnface);
442 hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBackgrndBrush);
443 hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hFramePen);
444 SetBkMode(hDC, TRANSPARENT);
446 /* give parent a chance to alter parameters: */
447 SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
448 MAKELPARAM(hButton, CTLCOLOR_BTN));
449 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
451 /* draw button shadow: */
452 hShadowPen = CreatePen(PS_SOLID, 1, color_btnshadow);
453 SelectObject(hDC, (HANDLE)hShadowPen);
454 MoveTo(hDC, rc.left+1, rc.bottom-1);
455 LineTo(hDC, rc.left+1, rc.top+1);
456 LineTo(hDC, rc.right-1, rc.top+1);
458 /* draw button label, if any: */
459 len = GetWindowText(hButton, text, sizeof text);
460 if (len >= 1) {
461 rc.top++; rc.left++;
462 DrawText(hDC, text, len, &rc,
463 DT_SINGLELINE | DT_CENTER| DT_VCENTER);
466 /* do we have the focus? */
467 if (len >= 1 && GetFocus() == hButton) {
468 dwTextSize = GetTextExtent(hDC, text, len);
469 delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
470 rc.left += delta; rc.right -= delta;
471 GetTextMetrics(hDC, &tm);
472 delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
473 rc.top += delta; rc.bottom -= delta;
474 DrawFocusRect(hDC, &rc);
477 SelectObject(hDC, (HANDLE)hOldPen);
478 SelectObject(hDC, (HANDLE)hOldBrush);
479 DeleteObject((HANDLE)hBackgrndBrush);
480 DeleteObject(SelectObject(hDC, (HANDLE)hFramePen));
481 DeleteObject(SelectObject(hDC, (HANDLE)hShadowPen));
485 /**********************************************************************
486 * Check Box Functions
489 static LONG CB_Paint(HWND hWnd)
491 PAINTSTRUCT ps;
492 RECT rc, rc3;
493 HDC hDC;
494 HPEN hPen, hOldPen;
495 HBRUSH hBrush, hGrayBrush;
496 int textlen, delta;
497 char *text;
498 HANDLE hText;
499 TEXTMETRIC tm;
500 SIZE size;
501 WND *wndPtr = WIN_FindWndPtr(hWnd);
503 hDC = BeginPaint(hWnd, &ps);
504 GetClientRect(hWnd, &rc);
506 hPen = CreatePen(PS_SOLID, 1, color_windowtext);
507 hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
508 hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
510 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
511 MAKELPARAM(hWnd, CTLCOLOR_BTN));
512 FillRect(hDC, &rc, hBrush);
514 textlen = GetWindowTextLength(hWnd);
515 hText = USER_HEAP_ALLOC(0, textlen+1);
516 text = USER_HEAP_ADDR(hText);
517 GetWindowText(hWnd, text, textlen+1);
518 GetTextMetrics(hDC, &tm);
520 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
521 Rectangle(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
522 if (pressed)
523 Rectangle(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
524 tm.tmHeight + delta - 1);
526 switch ((WORD)(*(wndPtr->wExtra)))
528 case 1:
529 MoveTo(hDC, 0, rc.top + delta);
530 LineTo(hDC, tm.tmHeight - 1, tm.tmHeight + delta - 1);
531 MoveTo(hDC, 0, tm.tmHeight + delta - 1);
532 LineTo(hDC, tm.tmHeight - 1, rc.top + delta);
533 break;
535 case 2:
536 rc3.left = 1;
537 rc3.top = rc.top + delta + 1;
538 rc3.right = tm.tmHeight - 1;
539 rc3.bottom = tm.tmHeight + delta - 1;
540 FillRect(hDC, &rc3, hGrayBrush);
541 break;
544 rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
545 DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
547 /* do we have the focus? */
548 if (GetFocus() == hWnd)
550 GetTextExtentPoint(hDC, text, textlen, &size);
551 rc.top += delta - 1;
552 rc.bottom -= delta + 1;
553 rc.left--;
554 rc.right = rc.left + size.cx + 2;
555 DrawFocusRect(hDC, &rc);
558 USER_HEAP_FREE(hText);
559 GlobalUnlock(hWnd);
560 EndPaint(hWnd, &ps);
563 static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
565 RECT rc;
566 HDC hDC;
567 TEXTMETRIC tm;
568 int delta;
570 hDC = GetDC(hWnd);
571 GetTextMetrics(hDC, &tm);
572 ReleaseDC(hWnd, hDC);
573 GetClientRect(hWnd, &rc);
574 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
575 rc.top += delta;
576 rc.bottom = tm.tmHeight + delta;
577 rc.right = tm.tmHeight;
578 if (PtInRect(&rc, MAKEPOINT(lParam)))
580 /* SetFocus(hWnd); */
581 SetCapture(hWnd);
582 pressed = TRUE;
583 InvalidateRect(hWnd, NULL, FALSE);
584 UpdateWindow(hWnd);
588 static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
590 RECT rc;
591 HDC hDC;
592 TEXTMETRIC tm;
593 int delta;
594 WND *wndPtr = WIN_FindWndPtr(hWnd);
595 LONG style;
597 pressed = FALSE;
598 ReleaseCapture();
599 hDC = GetDC(hWnd);
600 GetTextMetrics(hDC, &tm);
601 ReleaseDC(hWnd, hDC);
602 GetClientRect(hWnd, &rc);
603 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
604 rc.top += delta;
605 rc.bottom = tm.tmHeight + delta;
606 rc.right = tm.tmHeight;
608 if (PtInRect(&rc, MAKEPOINT(lParam)))
610 style = wndPtr->dwStyle & 0x0000000F;
611 if (style == BS_AUTOCHECKBOX)
613 switch ((WORD)(*(wndPtr->wExtra)))
615 case 0:
616 (WORD)(*(wndPtr->wExtra)) = 1;
617 break;
619 case 1:
620 (WORD)(*(wndPtr->wExtra)) = 0;
621 break;
624 else if (style == BS_AUTO3STATE)
626 switch ((WORD)(*(wndPtr->wExtra)))
628 case 0:
629 (WORD)(*(wndPtr->wExtra)) = 1;
630 break;
632 case 1:
633 (WORD)(*(wndPtr->wExtra)) = 2;
634 break;
636 case 2:
637 (WORD)(*(wndPtr->wExtra)) = 0;
638 break;
641 NOTIFY_PARENT(hWnd, BN_CLICKED);
643 GlobalUnlock(hWnd);
644 InvalidateRect(hWnd, NULL, FALSE);
645 UpdateWindow(hWnd);
648 static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
650 RECT rc;
651 HDC hDC;
652 TEXTMETRIC tm;
653 int delta;
655 hDC = GetDC(hWnd);
656 GetTextMetrics(hDC, &tm);
657 ReleaseDC(hWnd, hDC);
658 GetClientRect(hWnd, &rc);
659 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
660 rc.top += delta;
661 rc.bottom = tm.tmHeight + delta;
662 rc.right = tm.tmHeight;
663 if (PtInRect(&rc, MAKEPOINT(lParam)))
664 NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
667 static LONG CB_KillFocus(HWND hWnd)
669 pressed = FALSE;
670 InvalidateRect(hWnd, NULL, FALSE);
671 UpdateWindow(hWnd);
674 static LONG CB_SetCheck(HWND hWnd, WORD wParam)
676 WND *wndPtr = WIN_FindWndPtr(hWnd);
678 if ((WORD)(*(wndPtr->wExtra)) != wParam)
680 (WORD)(*(wndPtr->wExtra)) = wParam;
681 InvalidateRect(hWnd, NULL, FALSE);
682 UpdateWindow(hWnd);
684 GlobalUnlock(hWnd);
687 static LONG CB_GetCheck(HWND hWnd)
689 WORD wResult;
690 WND *wndPtr = WIN_FindWndPtr(hWnd);
692 wResult = (WORD)(*(wndPtr->wExtra));
693 GlobalUnlock(hWnd);
694 return (LONG)wResult;
698 /**********************************************************************
699 * Radio Button Functions
702 static LONG RB_Paint(HWND hWnd)
704 PAINTSTRUCT ps;
705 RECT rc;
706 HDC hDC;
707 HPEN hPen, hOldPen;
708 HBRUSH hBrush, hOldBrush;
709 int textlen, delta;
710 char *text;
711 HANDLE hText;
712 TEXTMETRIC tm;
713 SIZE size;
714 WND *wndPtr = WIN_FindWndPtr(hWnd);
716 hDC = BeginPaint(hWnd, &ps);
717 GetClientRect(hWnd, &rc);
719 hPen = CreatePen(PS_SOLID, 1, color_windowtext);
720 hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
722 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
723 MAKELPARAM(hWnd, CTLCOLOR_BTN));
724 FillRect(hDC, &rc, hBrush);
726 textlen = GetWindowTextLength(hWnd);
727 hText = USER_HEAP_ALLOC(0, textlen+1);
728 text = USER_HEAP_ADDR(hText);
729 GetWindowText(hWnd, text, textlen+1);
730 GetTextMetrics(hDC, &tm);
732 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
733 Ellipse(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
734 if (pressed)
735 Ellipse(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
736 tm.tmHeight + delta - 1);
738 if ((WORD)(*(wndPtr->wExtra)) == 1)
740 hBrush = CreateSolidBrush(color_windowtext);
741 hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBrush);
742 Ellipse(hDC, 3, rc.top + delta + 3, tm.tmHeight - 3,
743 tm.tmHeight + delta -3);
744 SelectObject(hDC, (HANDLE)hOldBrush);
745 DeleteObject((HANDLE)hBrush);
748 rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
749 DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
751 /* do we have the focus? */
752 if (GetFocus() == hWnd)
754 GetTextExtentPoint(hDC, text, textlen, &size);
755 rc.top += delta - 1;
756 rc.bottom -= delta + 1;
757 rc.left--;
758 rc.right = rc.left + size.cx + 2;
759 DrawFocusRect(hDC, &rc);
762 USER_HEAP_FREE(hText);
763 GlobalUnlock(hWnd);
764 EndPaint(hWnd, &ps);
767 static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
769 RECT rc;
770 HDC hDC;
771 TEXTMETRIC tm;
772 int delta;
774 hDC = GetDC(hWnd);
775 GetTextMetrics(hDC, &tm);
776 ReleaseDC(hWnd, hDC);
777 GetClientRect(hWnd, &rc);
778 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
779 rc.top += delta;
780 rc.bottom = tm.tmHeight + delta;
781 rc.right = tm.tmHeight;
782 if (PtInRect(&rc, MAKEPOINT(lParam)))
784 /* SetFocus(hWnd); */
785 SetCapture(hWnd);
786 pressed = TRUE;
787 InvalidateRect(hWnd, NULL, FALSE);
788 UpdateWindow(hWnd);
792 static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
794 RECT rc;
795 HDC hDC;
796 TEXTMETRIC tm;
797 int delta;
798 WND *wndPtr = WIN_FindWndPtr(hWnd);
799 LONG style;
801 pressed = FALSE;
802 ReleaseCapture();
803 hDC = GetDC(hWnd);
804 GetTextMetrics(hDC, &tm);
805 ReleaseDC(hWnd, hDC);
806 GetClientRect(hWnd, &rc);
807 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
808 rc.top += delta;
809 rc.bottom = tm.tmHeight + delta;
810 rc.right = tm.tmHeight;
812 if (PtInRect(&rc, MAKEPOINT(lParam)))
814 style = wndPtr->dwStyle & 0x0000000F;
815 if (style == BS_AUTORADIOBUTTON)
816 (WORD)(*(wndPtr->wExtra)) = 1;
817 NOTIFY_PARENT(hWnd, BN_CLICKED);
819 GlobalUnlock(hWnd);
820 InvalidateRect(hWnd, NULL, FALSE);
821 UpdateWindow(hWnd);
824 static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
826 RECT rc;
827 HDC hDC;
828 TEXTMETRIC tm;
829 int delta;
831 hDC = GetDC(hWnd);
832 GetTextMetrics(hDC, &tm);
833 ReleaseDC(hWnd, hDC);
834 GetClientRect(hWnd, &rc);
835 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
836 rc.top += delta;
837 rc.bottom = tm.tmHeight + delta;
838 rc.right = tm.tmHeight;
839 if (PtInRect(&rc, MAKEPOINT(lParam)))
840 NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
843 static LONG RB_KillFocus(HWND hWnd)
845 pressed = FALSE;
846 InvalidateRect(hWnd, NULL, FALSE);
847 UpdateWindow(hWnd);
850 static LONG RB_SetCheck(HWND hWnd, WORD wParam)
852 WND *wndPtr = WIN_FindWndPtr(hWnd);
854 if ((WORD)(*(wndPtr->wExtra)) != wParam)
856 (WORD)(*(wndPtr->wExtra)) = wParam;
857 InvalidateRect(hWnd, NULL, FALSE);
858 UpdateWindow(hWnd);
860 GlobalUnlock(hWnd);
863 static LONG RB_GetCheck(HWND hWnd)
865 WORD wResult;
866 WND *wndPtr = WIN_FindWndPtr(hWnd);
868 wResult = (WORD)(*(wndPtr->wExtra));
869 GlobalUnlock(hWnd);
870 return (LONG)wResult;
874 /**********************************************************************
875 * Group Box Functions
878 static LONG GB_Paint(HWND hWnd)
880 PAINTSTRUCT ps;
881 RECT rc;
882 HDC hDC;
883 HPEN hPen, hOldPen;
884 HBRUSH hBrush;
885 int textlen;
886 char *text;
887 HANDLE hText;
888 SIZE size;
890 hDC = BeginPaint(hWnd, &ps);
891 GetClientRect(hWnd, &rc);
893 hPen = CreatePen(PS_SOLID, 1, color_windowtext);
894 hOldPen = (HPEN)SelectObject(hDC, (HANDLE)hPen);
896 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
897 MAKELPARAM(hWnd, CTLCOLOR_BTN));
898 FillRect(hDC, &rc, hBrush);
900 textlen = GetWindowTextLength(hWnd);
901 hText = USER_HEAP_ALLOC(0, textlen+1);
902 text = USER_HEAP_ADDR(hText);
903 GetWindowText(hWnd, text, textlen+1);
904 GetTextExtentPoint(hDC, text, textlen, &size);
906 rc.top = 5;
907 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
908 rc.left = 10;
909 rc.top = 0;
910 rc.right = rc.left + size.cx + 1;
911 rc.bottom = size.cy;
912 DrawText(hDC, text, textlen, &rc, DT_SINGLELINE);
914 USER_HEAP_FREE(hText);
915 EndPaint(hWnd, &ps);
919 /**********************************************************************
920 * User Button Functions
923 static LONG UB_Paint(HWND hWnd)
925 PAINTSTRUCT ps;
926 HDC hDC;
927 RECT rc;
928 HBRUSH hBrush;
930 hDC = BeginPaint(hWnd, &ps);
931 GetClientRect(hWnd, &rc);
933 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
934 MAKELPARAM(hWnd, CTLCOLOR_BTN));
935 FillRect(hDC, &rc, hBrush);
937 NOTIFY_PARENT(hWnd, BN_PAINT);
939 /* do we have the focus? */
940 if (GetFocus() == hWnd)
941 DrawFocusRect(hDC, &rc);
943 EndPaint(hWnd, &ps);
946 static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
948 RECT rc;
950 /* SetFocus(hWnd); */
951 SetCapture(hWnd);
952 GetClientRect(hWnd, &rc);
953 if (PtInRect(&rc, MAKEPOINT(lParam)))
954 NOTIFY_PARENT(hWnd, BN_HILITE);
955 InvalidateRect(hWnd, NULL, FALSE);
956 UpdateWindow(hWnd);
959 static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
961 RECT rc;
963 ReleaseCapture();
964 GetClientRect(hWnd, &rc);
965 if (PtInRect(&rc, MAKEPOINT(lParam)))
967 NOTIFY_PARENT(hWnd, BN_CLICKED);
968 NOTIFY_PARENT(hWnd, BN_UNHILITE);
970 InvalidateRect(hWnd, NULL, FALSE);
971 UpdateWindow(hWnd);
974 static LONG UB_KillFocus(HWND hWnd)
976 InvalidateRect(hWnd, NULL, FALSE);
977 UpdateWindow(hWnd);
981 /**********************************************************************
982 * Ownerdrawn Button Functions
985 static LONG OB_Paint(HWND hWnd)
987 PAINTSTRUCT ps;
988 HDC hDC;
989 RECT rc;
990 HANDLE hDis;
991 LPDRAWITEMSTRUCT lpdis;
992 WND *wndPtr = WIN_FindWndPtr(hWnd);
993 hDC = BeginPaint(hWnd, &ps);
994 GetClientRect(hWnd, &rc);
995 hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
996 lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
997 lpdis->hDC = hDC;
998 lpdis->itemID = 0;
999 CopyRect(&lpdis->rcItem, &rc);
1000 lpdis->CtlID = wndPtr->wIDmenu;
1001 lpdis->CtlType = ODT_BUTTON;
1002 lpdis->itemAction = ODA_DRAWENTIRE;
1003 /* printf("ownerdrawn button WM_DRAWITEM CtrlID=%X\n", lpdis->CtlID);*/
1004 SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
1005 USER_HEAP_FREE(hDis);
1006 EndPaint(hWnd, &ps);
1009 static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
1011 HDC hDC;
1012 RECT rc;
1013 HANDLE hDis;
1014 LPDRAWITEMSTRUCT lpdis;
1015 WND *wndPtr = WIN_FindWndPtr(hWnd);
1016 /* SetFocus(hWnd); */
1017 SetCapture(hWnd);
1018 hDC = GetDC(hWnd);
1019 GetClientRect(hWnd, &rc);
1020 if (PtInRect(&rc, MAKEPOINT(lParam)))
1021 NOTIFY_PARENT(hWnd, BN_CLICKED);
1022 GetClientRect(hWnd, &rc);
1023 hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
1024 lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
1025 lpdis->hDC = hDC;
1026 lpdis->itemID = 0;
1027 CopyRect(&lpdis->rcItem, &rc);
1028 lpdis->CtlID = wndPtr->wIDmenu;
1029 lpdis->CtlType = ODT_BUTTON;
1030 lpdis->itemAction = ODA_SELECT;
1031 SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
1032 USER_HEAP_FREE(hDis);
1033 ReleaseDC(hWnd, hDC);
1036 static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
1038 HDC hDC;
1039 RECT rc;
1040 HANDLE hDis;
1041 LPDRAWITEMSTRUCT lpdis;
1042 WND *wndPtr = WIN_FindWndPtr(hWnd);
1043 ReleaseCapture();
1044 hDC = GetDC(hWnd);
1045 GetClientRect(hWnd, &rc);
1046 if (PtInRect(&rc, MAKEPOINT(lParam)))
1047 NOTIFY_PARENT(hWnd, BN_CLICKED);
1048 GetClientRect(hWnd, &rc);
1049 hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
1050 lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
1051 lpdis->hDC = hDC;
1052 lpdis->itemID = 0;
1053 CopyRect(&lpdis->rcItem, &rc);
1054 lpdis->CtlID = wndPtr->wIDmenu;
1055 lpdis->CtlType = ODT_BUTTON;
1056 lpdis->itemAction = ODA_SELECT;
1057 SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
1058 USER_HEAP_FREE(hDis);
1059 ReleaseDC(hWnd, hDC);
1062 static LONG OB_KillFocus(HWND hWnd)
1064 InvalidateRect(hWnd, NULL, FALSE);
1065 UpdateWindow(hWnd);