Release 940804
[wine/gsoc-2012-control.git] / controls / button.c
blob67de0ab3ee611b370a290d996253d39a84254336
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"
13 #include "syscolor.h"
15 LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam);
17 static BOOL pressed;
19 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
20 SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
21 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
22 #define DIM(array) ((sizeof array)/(sizeof array[0]))
24 static LONG PB_Paint(HWND hWnd);
25 static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
26 static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
27 static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
28 static LONG PB_KillFocus(HWND hwnd);
29 static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc);
30 static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc);
31 static LONG CB_Paint(HWND hWnd);
32 static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
33 static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
34 static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
35 static LONG CB_KillFocus(HWND hWnd);
36 static LONG CB_SetCheck(HWND hWnd, WORD wParam);
37 static LONG CB_GetCheck(HWND hWnd);
38 static LONG RB_Paint(HWND hWnd);
39 static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
40 static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
41 static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam);
42 static LONG RB_KillFocus(HWND hWnd);
43 static LONG RB_SetCheck(HWND hWnd, WORD wParam);
44 static LONG RB_GetCheck(HWND hWnd);
45 static LONG GB_Paint(HWND hWnd);
46 static LONG UB_Paint(HWND hWnd);
47 static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
48 static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
49 static LONG UB_KillFocus(HWND hWnd);
50 static LONG OB_Paint(HWND hWnd);
51 static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam);
52 static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam);
53 static LONG OB_KillFocus(HWND hWnd);
55 typedef struct
57 LONG (*paintfn)();
58 LONG (*lButtonDownfn)();
59 LONG (*lButtonUpfn)();
60 LONG (*lButtonDblClkfn)();
61 LONG (*killFocusfn)();
62 LONG (*setCheckfn)();
63 LONG (*getCheckfn)();
64 } BTNFN;
66 #define MAX_BTN_TYPE 12
68 static BTNFN btnfn[MAX_BTN_TYPE] =
71 (LONG(*)())PB_Paint, /* BS_PUSHBUTTON */
72 (LONG(*)())PB_LButtonDown,
73 (LONG(*)())PB_LButtonUp,
74 (LONG(*)())PB_LButtonDblClk,
75 (LONG(*)())PB_KillFocus,
76 (LONG(*)())NULL,
77 (LONG(*)())NULL
80 (LONG(*)())PB_Paint, /* BS_DEFPUSHBUTTON */
81 (LONG(*)())PB_LButtonDown,
82 (LONG(*)())PB_LButtonUp,
83 (LONG(*)())PB_LButtonDblClk,
84 (LONG(*)())PB_KillFocus,
85 (LONG(*)())NULL,
86 (LONG(*)())NULL
89 (LONG(*)())CB_Paint, /* BS_CHECKBOX */
90 (LONG(*)())CB_LButtonDown,
91 (LONG(*)())CB_LButtonUp,
92 (LONG(*)())CB_LButtonDblClk,
93 (LONG(*)())CB_KillFocus,
94 (LONG(*)())CB_SetCheck,
95 (LONG(*)())CB_GetCheck
98 (LONG(*)())CB_Paint, /* BS_AUTOCHECKBOX */
99 (LONG(*)())CB_LButtonDown,
100 (LONG(*)())CB_LButtonUp,
101 (LONG(*)())CB_LButtonDblClk,
102 (LONG(*)())CB_KillFocus,
103 (LONG(*)())CB_SetCheck,
104 (LONG(*)())CB_GetCheck
107 (LONG(*)())RB_Paint, /* BS_RADIOBUTTON */
108 (LONG(*)())RB_LButtonDown,
109 (LONG(*)())RB_LButtonUp,
110 (LONG(*)())RB_LButtonDblClk,
111 (LONG(*)())RB_KillFocus,
112 (LONG(*)())RB_SetCheck,
113 (LONG(*)())RB_GetCheck
116 (LONG(*)())CB_Paint, /* BS_3STATE */
117 (LONG(*)())CB_LButtonDown,
118 (LONG(*)())CB_LButtonUp,
119 (LONG(*)())CB_LButtonDblClk,
120 (LONG(*)())CB_KillFocus,
121 (LONG(*)())CB_SetCheck,
122 (LONG(*)())CB_GetCheck
125 (LONG(*)())CB_Paint, /* BS_AUTO3STATE */
126 (LONG(*)())CB_LButtonDown,
127 (LONG(*)())CB_LButtonUp,
128 (LONG(*)())CB_LButtonDblClk,
129 (LONG(*)())CB_KillFocus,
130 (LONG(*)())CB_SetCheck,
131 (LONG(*)())CB_GetCheck
134 (LONG(*)())GB_Paint, /* BS_GROUPBOX */
135 (LONG(*)())NULL,
136 (LONG(*)())NULL,
137 (LONG(*)())NULL,
138 (LONG(*)())NULL,
139 (LONG(*)())NULL,
140 (LONG(*)())NULL
143 (LONG(*)())UB_Paint, /* BS_USERBUTTON */
144 (LONG(*)())UB_LButtonDown,
145 (LONG(*)())UB_LButtonUp,
146 (LONG(*)())NULL,
147 (LONG(*)())UB_KillFocus,
148 (LONG(*)())NULL,
149 (LONG(*)())NULL
152 (LONG(*)())RB_Paint, /* BS_AUTORADIOBUTTON */
153 (LONG(*)())RB_LButtonDown,
154 (LONG(*)())RB_LButtonUp,
155 (LONG(*)())RB_LButtonDblClk,
156 (LONG(*)())RB_KillFocus,
157 (LONG(*)())RB_SetCheck,
158 (LONG(*)())RB_GetCheck
161 (LONG(*)())NULL, /* Not defined */
162 (LONG(*)())NULL,
163 (LONG(*)())NULL,
164 (LONG(*)())NULL,
165 (LONG(*)())NULL,
166 (LONG(*)())NULL,
167 (LONG(*)())NULL
170 (LONG(*)())OB_Paint, /* BS_OWNERDRAW */
171 (LONG(*)())OB_LButtonDown,
172 (LONG(*)())OB_LButtonUp,
173 (LONG(*)())NULL,
174 (LONG(*)())OB_KillFocus,
175 (LONG(*)())NULL,
176 (LONG(*)())NULL
181 LONG ButtonWndProc(HWND hWnd, WORD uMsg, WORD wParam, LONG lParam)
183 LONG lResult = 0;
184 HDC hDC;
185 RECT rc;
187 WND *wndPtr = WIN_FindWndPtr(hWnd);
188 LONG style = wndPtr->dwStyle & 0x0000000F;
190 switch (uMsg) {
191 /* case WM_GETDLGCODE:
192 lResult = DLGC_BUTTON;
193 break;
195 case WM_ENABLE:
196 InvalidateRect(hWnd, NULL, FALSE);
197 break;
199 case WM_CREATE:
200 if (style < 0L || style >= (LONG)DIM(btnfn))
201 lResult = -1L;
202 else
204 (WORD)(*(wndPtr->wExtra)) = 0;
205 pressed = FALSE;
206 lResult = 0L;
208 break;
210 case WM_PAINT:
211 if (btnfn[style].paintfn)
212 (btnfn[style].paintfn)(hWnd);
213 break;
215 case WM_LBUTTONDOWN:
216 if (btnfn[style].lButtonDownfn)
217 (btnfn[style].lButtonDownfn)(hWnd, wParam, lParam);
218 break;
220 case WM_LBUTTONUP:
221 if (btnfn[style].lButtonUpfn)
222 (btnfn[style].lButtonUpfn)(hWnd, wParam, lParam);
223 break;
225 case WM_LBUTTONDBLCLK:
226 if (btnfn[style].lButtonDblClkfn)
227 (btnfn[style].lButtonDblClkfn)(hWnd, wParam, lParam);
228 break;
230 case WM_SETFOCUS:
231 break;
233 case WM_KILLFOCUS:
234 if (btnfn[style].killFocusfn)
235 (btnfn[style].killFocusfn)(hWnd);
236 break;
238 case WM_SYSCOLORCHANGE:
239 InvalidateRect(hWnd, NULL, TRUE);
240 break;
242 case BM_SETCHECK:
243 if (btnfn[style].setCheckfn)
244 (btnfn[style].setCheckfn)(hWnd, wParam);
245 break;
247 case BM_GETCHECK:
248 if (btnfn[style].getCheckfn)
249 return (btnfn[style].getCheckfn)(hWnd);
250 break;
252 default:
253 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
254 break;
257 GlobalUnlock(hWnd);
258 return lResult;
262 /**********************************************************************
263 * Push Button Functions
266 static LONG PB_Paint(HWND hWnd)
268 PAINTSTRUCT ps;
269 RECT rc;
270 HDC hDC;
272 hDC = BeginPaint(hWnd, &ps);
273 GetClientRect(hWnd, &rc);
274 if (pressed)
275 DrawPressedPushButton(hDC, hWnd, rc);
276 else
277 DrawRaisedPushButton(hDC, hWnd, rc);
278 EndPaint(hWnd, &ps);
281 static LONG PB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
283 SetFocus(hWnd);
284 SetCapture(hWnd);
285 pressed = TRUE;
286 InvalidateRect(hWnd, NULL, FALSE);
287 UpdateWindow(hWnd);
290 static LONG PB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
292 RECT rc;
294 pressed = FALSE;
295 ReleaseCapture();
296 GetClientRect(hWnd, &rc);
297 if (PtInRect(&rc, MAKEPOINT(lParam)))
298 NOTIFY_PARENT(hWnd, BN_CLICKED);
299 InvalidateRect(hWnd, NULL, FALSE);
300 UpdateWindow(hWnd);
303 static LONG PB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
305 RECT rc;
307 GetClientRect(hWnd, &rc);
308 if (PtInRect(&rc, MAKEPOINT(lParam)))
309 NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
312 static LONG PB_KillFocus(HWND hWnd)
314 pressed = FALSE;
315 InvalidateRect(hWnd, NULL, FALSE);
316 UpdateWindow(hWnd);
319 static void DrawRaisedPushButton(HDC hDC, HWND hButton, RECT rc)
321 HPEN hOldPen;
322 HBRUSH hOldBrush;
323 HRGN rgn1, rgn2, rgn;
324 int len;
325 static char text[50+1];
326 POINT points[6];
327 DWORD dwTextSize;
328 int delta;
329 TEXTMETRIC tm;
331 hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
332 hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
333 SetBkMode(hDC, TRANSPARENT);
335 rgn = CreateRectRgn(0, 0, 0, 0);
336 rgn1 = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
338 SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
339 MAKELPARAM(hButton, CTLCOLOR_BTN));
340 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
342 /* draw button label, if any: */
343 len = GetWindowText(hButton, text, sizeof text);
344 if (len >= 1) {
345 rc.left--; rc.bottom--;
346 DrawText(hDC, text, len, &rc,
347 DT_SINGLELINE | DT_CENTER| DT_VCENTER);
350 /* draw button highlight */
351 points[0].x = rc.left+2;
352 points[0].y = rc.bottom;
353 points[1].x = rc.left+4;
354 points[1].y = rc.bottom-2;
355 points[2].x = rc.left+4;
356 points[2].y = rc.top+3;
357 points[3].x = rc.right-3;
358 points[3].y = rc.top+3;
359 points[4].x = rc.right-1;
360 points[4].y = rc.top+1;
361 points[5].x = rc.left+2;
362 points[5].y = rc.top+1;
363 rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
364 CombineRgn(rgn, rgn1, rgn2, RGN_AND);
365 FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnHighlight);
367 /* draw button shadow: */
368 points[0].x = rc.left+2;
369 points[0].y = rc.bottom;
370 points[1].x = rc.left+4;
371 points[1].y = rc.bottom-2;
372 points[2].x = rc.right-3;
373 points[2].y = rc.bottom-2;
374 points[3].x = rc.right-3;
375 points[3].y = rc.top+3;
376 points[4].x = rc.right-1;
377 points[4].y = rc.top;
378 points[5].x = rc.right-1;
379 points[5].y = rc.bottom;
380 rgn2 = CreatePolygonRgn(points, DIM(points), ALTERNATE);
381 CombineRgn(rgn, rgn1, rgn2, RGN_AND);
382 FillRgn(hDC, rgn2, sysColorObjects.hbrushBtnShadow);
384 /* do we have the focus? */
385 if (len >= 1 && GetFocus() == hButton) {
386 dwTextSize = GetTextExtent(hDC, text, len);
387 delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
388 rc.left += delta; rc.right -= delta;
389 GetTextMetrics(hDC, &tm);
390 delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
391 rc.top += delta; rc.bottom -= delta;
392 DrawFocusRect(hDC, &rc);
395 SelectObject(hDC, (HANDLE)hOldPen);
396 SelectObject(hDC, (HANDLE)hOldBrush);
397 DeleteObject((HANDLE)rgn1);
398 DeleteObject((HANDLE)rgn2);
399 DeleteObject((HANDLE)rgn);
403 static void DrawPressedPushButton(HDC hDC, HWND hButton, RECT rc)
405 HPEN hOldPen;
406 HBRUSH hOldBrush;
407 int len;
408 static char text[50+1];
409 DWORD dwTextSize;
410 int delta;
411 TEXTMETRIC tm;
413 hOldBrush = (HBRUSH)SelectObject(hDC, sysColorObjects.hbrushBtnFace);
414 hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowFrame);
415 SetBkMode(hDC, TRANSPARENT);
417 /* give parent a chance to alter parameters: */
418 SendMessage(GetParent(hButton), WM_CTLCOLOR, (WORD)hDC,
419 MAKELPARAM(hButton, CTLCOLOR_BTN));
420 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
422 /* draw button shadow: */
423 SelectObject(hDC, sysColorObjects.hbrushBtnShadow );
424 PatBlt(hDC, rc.left+1, rc.top+1, 1, rc.bottom-rc.top-2, PATCOPY );
425 PatBlt(hDC, rc.left+1, rc.top+1, rc.right-rc.left-2, 1, PATCOPY );
427 /* draw button label, if any: */
428 len = GetWindowText(hButton, text, sizeof text);
429 if (len >= 1) {
430 rc.top++; rc.left++;
431 DrawText(hDC, text, len, &rc,
432 DT_SINGLELINE | DT_CENTER| DT_VCENTER);
435 /* do we have the focus? */
436 if (len >= 1 && GetFocus() == hButton) {
437 dwTextSize = GetTextExtent(hDC, text, len);
438 delta = ((rc.right - rc.left) - LOWORD(dwTextSize) - 1) >> 1;
439 rc.left += delta; rc.right -= delta;
440 GetTextMetrics(hDC, &tm);
441 delta = ((rc.bottom - rc.top) - tm.tmHeight - 1) >> 1;
442 rc.top += delta; rc.bottom -= delta;
443 DrawFocusRect(hDC, &rc);
446 SelectObject(hDC, (HANDLE)hOldPen);
447 SelectObject(hDC, (HANDLE)hOldBrush);
451 /**********************************************************************
452 * Check Box Functions
455 static LONG CB_Paint(HWND hWnd)
457 PAINTSTRUCT ps;
458 RECT rc, rc3;
459 HDC hDC;
460 HPEN hOldPen;
461 HBRUSH hBrush, hGrayBrush;
462 int textlen, delta;
463 char *text;
464 HANDLE hText;
465 TEXTMETRIC tm;
466 SIZE size;
467 WND *wndPtr = WIN_FindWndPtr(hWnd);
469 hDC = BeginPaint(hWnd, &ps);
470 GetClientRect(hWnd, &rc);
472 hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
473 hGrayBrush = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
475 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
476 MAKELPARAM(hWnd, CTLCOLOR_BTN));
477 FillRect(hDC, &rc, hBrush);
479 textlen = GetWindowTextLength(hWnd);
480 hText = USER_HEAP_ALLOC(0, textlen+1);
481 text = USER_HEAP_ADDR(hText);
482 GetWindowText(hWnd, text, textlen+1);
483 GetTextMetrics(hDC, &tm);
485 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
486 Rectangle(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
487 if (pressed)
488 Rectangle(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
489 tm.tmHeight + delta - 1);
491 switch ((WORD)(*(wndPtr->wExtra)))
493 case 1:
494 MoveTo(hDC, 0, rc.top + delta);
495 LineTo(hDC, tm.tmHeight - 1, tm.tmHeight + delta - 1);
496 MoveTo(hDC, 0, tm.tmHeight + delta - 1);
497 LineTo(hDC, tm.tmHeight - 1, rc.top + delta);
498 break;
500 case 2:
501 rc3.left = 1;
502 rc3.top = rc.top + delta + 1;
503 rc3.right = tm.tmHeight - 1;
504 rc3.bottom = tm.tmHeight + delta - 1;
505 FillRect(hDC, &rc3, hGrayBrush);
506 break;
509 rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
510 DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
512 /* do we have the focus? */
513 if (GetFocus() == hWnd)
515 GetTextExtentPoint(hDC, text, textlen, &size);
516 rc.top += delta - 1;
517 rc.bottom -= delta + 1;
518 rc.left--;
519 rc.right = rc.left + size.cx + 2;
520 DrawFocusRect(hDC, &rc);
523 SelectObject(hDC, hOldPen);
524 USER_HEAP_FREE(hText);
525 GlobalUnlock(hWnd);
526 EndPaint(hWnd, &ps);
529 static LONG CB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
531 RECT rc;
532 HDC hDC;
533 TEXTMETRIC tm;
534 int delta;
536 hDC = GetDC(hWnd);
537 GetTextMetrics(hDC, &tm);
538 ReleaseDC(hWnd, hDC);
539 GetClientRect(hWnd, &rc);
540 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
541 rc.top += delta;
542 rc.bottom = tm.tmHeight + delta;
543 if (PtInRect(&rc, MAKEPOINT(lParam)))
545 SetFocus(hWnd);
546 SetCapture(hWnd);
547 pressed = TRUE;
548 InvalidateRect(hWnd, NULL, FALSE);
549 UpdateWindow(hWnd);
553 static LONG CB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
555 RECT rc;
556 HDC hDC;
557 TEXTMETRIC tm;
558 int delta;
559 WND *wndPtr = WIN_FindWndPtr(hWnd);
560 LONG style;
562 pressed = FALSE;
563 ReleaseCapture();
564 hDC = GetDC(hWnd);
565 GetTextMetrics(hDC, &tm);
566 ReleaseDC(hWnd, hDC);
567 GetClientRect(hWnd, &rc);
568 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
569 rc.top += delta;
570 rc.bottom = tm.tmHeight + delta;
572 if (PtInRect(&rc, MAKEPOINT(lParam)))
574 style = wndPtr->dwStyle & 0x0000000F;
575 if (style == BS_AUTOCHECKBOX)
577 switch ((WORD)(*(wndPtr->wExtra)))
579 case 0:
580 (WORD)(*(wndPtr->wExtra)) = 1;
581 break;
583 case 1:
584 (WORD)(*(wndPtr->wExtra)) = 0;
585 break;
588 else if (style == BS_AUTO3STATE)
590 switch ((WORD)(*(wndPtr->wExtra)))
592 case 0:
593 (WORD)(*(wndPtr->wExtra)) = 1;
594 break;
596 case 1:
597 (WORD)(*(wndPtr->wExtra)) = 2;
598 break;
600 case 2:
601 (WORD)(*(wndPtr->wExtra)) = 0;
602 break;
605 NOTIFY_PARENT(hWnd, BN_CLICKED);
607 GlobalUnlock(hWnd);
608 InvalidateRect(hWnd, NULL, FALSE);
609 UpdateWindow(hWnd);
612 static LONG CB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
614 RECT rc;
615 HDC hDC;
616 TEXTMETRIC tm;
617 int delta;
619 hDC = GetDC(hWnd);
620 GetTextMetrics(hDC, &tm);
621 ReleaseDC(hWnd, hDC);
622 GetClientRect(hWnd, &rc);
623 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
624 rc.top += delta;
625 rc.bottom = tm.tmHeight + delta;
626 if (PtInRect(&rc, MAKEPOINT(lParam)))
627 NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
630 static LONG CB_KillFocus(HWND hWnd)
632 pressed = FALSE;
633 InvalidateRect(hWnd, NULL, FALSE);
634 UpdateWindow(hWnd);
637 static LONG CB_SetCheck(HWND hWnd, WORD wParam)
639 WND *wndPtr = WIN_FindWndPtr(hWnd);
641 if ((WORD)(*(wndPtr->wExtra)) != wParam)
643 (WORD)(*(wndPtr->wExtra)) = wParam;
644 InvalidateRect(hWnd, NULL, FALSE);
645 UpdateWindow(hWnd);
647 GlobalUnlock(hWnd);
650 static LONG CB_GetCheck(HWND hWnd)
652 WORD wResult;
653 WND *wndPtr = WIN_FindWndPtr(hWnd);
655 wResult = (WORD)(*(wndPtr->wExtra));
656 GlobalUnlock(hWnd);
657 return (LONG)wResult;
661 /**********************************************************************
662 * Radio Button Functions
665 static LONG RB_Paint(HWND hWnd)
667 PAINTSTRUCT ps;
668 RECT rc;
669 HDC hDC;
670 HPEN hOldPen;
671 HBRUSH hBrush, hOldBrush;
672 int textlen, delta;
673 char *text;
674 HANDLE hText;
675 TEXTMETRIC tm;
676 SIZE size;
677 WND *wndPtr = WIN_FindWndPtr(hWnd);
679 hDC = BeginPaint(hWnd, &ps);
680 GetClientRect(hWnd, &rc);
682 hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
684 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
685 MAKELPARAM(hWnd, CTLCOLOR_BTN));
686 FillRect(hDC, &rc, hBrush);
688 textlen = GetWindowTextLength(hWnd);
689 hText = USER_HEAP_ALLOC(0, textlen+1);
690 text = USER_HEAP_ADDR(hText);
691 GetWindowText(hWnd, text, textlen+1);
692 GetTextMetrics(hDC, &tm);
694 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
695 Ellipse(hDC, 0, rc.top + delta, tm.tmHeight, tm.tmHeight + delta);
696 if (pressed)
697 Ellipse(hDC, 1, rc.top + delta + 1, tm.tmHeight - 1,
698 tm.tmHeight + delta - 1);
700 if ((WORD)(*(wndPtr->wExtra)) == 1)
702 hBrush = CreateSolidBrush( GetNearestColor(hDC, GetSysColor(COLOR_WINDOWTEXT)));
703 hOldBrush = (HBRUSH)SelectObject(hDC, (HANDLE)hBrush);
704 Ellipse(hDC, 3, rc.top + delta + 3, tm.tmHeight - 3,
705 tm.tmHeight + delta -3);
706 SelectObject(hDC, (HANDLE)hOldBrush);
707 DeleteObject((HANDLE)hBrush);
710 rc.left = tm.tmHeight + tm.tmAveCharWidth / 2;
711 DrawText(hDC, text, textlen, &rc, DT_SINGLELINE | DT_VCENTER);
713 /* do we have the focus? */
714 if (GetFocus() == hWnd)
716 GetTextExtentPoint(hDC, text, textlen, &size);
717 rc.top += delta - 1;
718 rc.bottom -= delta + 1;
719 rc.left--;
720 rc.right = rc.left + size.cx + 2;
721 DrawFocusRect(hDC, &rc);
724 SelectObject(hDC, hOldPen );
725 USER_HEAP_FREE(hText);
726 GlobalUnlock(hWnd);
727 EndPaint(hWnd, &ps);
730 static LONG RB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
732 RECT rc;
733 HDC hDC;
734 TEXTMETRIC tm;
735 int delta;
737 hDC = GetDC(hWnd);
738 GetTextMetrics(hDC, &tm);
739 ReleaseDC(hWnd, hDC);
740 GetClientRect(hWnd, &rc);
741 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
742 rc.top += delta;
743 rc.bottom = tm.tmHeight + delta;
744 if (PtInRect(&rc, MAKEPOINT(lParam)))
746 SetFocus(hWnd);
747 SetCapture(hWnd);
748 pressed = TRUE;
749 InvalidateRect(hWnd, NULL, FALSE);
750 UpdateWindow(hWnd);
754 static LONG RB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
756 RECT rc;
757 HDC hDC;
758 TEXTMETRIC tm;
759 int delta;
760 WND *wndPtr = WIN_FindWndPtr(hWnd);
761 LONG style;
763 pressed = FALSE;
764 ReleaseCapture();
765 hDC = GetDC(hWnd);
766 GetTextMetrics(hDC, &tm);
767 ReleaseDC(hWnd, hDC);
768 GetClientRect(hWnd, &rc);
769 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
770 rc.top += delta;
771 rc.bottom = tm.tmHeight + delta;
773 if (PtInRect(&rc, MAKEPOINT(lParam)))
775 style = wndPtr->dwStyle & 0x0000000F;
776 if (style == BS_AUTORADIOBUTTON)
777 (WORD)(*(wndPtr->wExtra)) = 1;
778 NOTIFY_PARENT(hWnd, BN_CLICKED);
780 GlobalUnlock(hWnd);
781 InvalidateRect(hWnd, NULL, FALSE);
782 UpdateWindow(hWnd);
785 static LONG RB_LButtonDblClk(HWND hWnd, WORD wParam, LONG lParam)
787 RECT rc;
788 HDC hDC;
789 TEXTMETRIC tm;
790 int delta;
792 hDC = GetDC(hWnd);
793 GetTextMetrics(hDC, &tm);
794 ReleaseDC(hWnd, hDC);
795 GetClientRect(hWnd, &rc);
796 delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
797 rc.top += delta;
798 rc.bottom = tm.tmHeight + delta;
799 if (PtInRect(&rc, MAKEPOINT(lParam)))
800 NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
803 static LONG RB_KillFocus(HWND hWnd)
805 pressed = FALSE;
806 InvalidateRect(hWnd, NULL, FALSE);
807 UpdateWindow(hWnd);
810 static LONG RB_SetCheck(HWND hWnd, WORD wParam)
812 WND *wndPtr = WIN_FindWndPtr(hWnd);
814 if ((WORD)(*(wndPtr->wExtra)) != wParam)
816 (WORD)(*(wndPtr->wExtra)) = wParam;
817 InvalidateRect(hWnd, NULL, FALSE);
818 UpdateWindow(hWnd);
820 GlobalUnlock(hWnd);
823 static LONG RB_GetCheck(HWND hWnd)
825 WORD wResult;
826 WND *wndPtr = WIN_FindWndPtr(hWnd);
828 wResult = (WORD)(*(wndPtr->wExtra));
829 GlobalUnlock(hWnd);
830 return (LONG)wResult;
834 /**********************************************************************
835 * Group Box Functions
838 static LONG GB_Paint(HWND hWnd)
840 PAINTSTRUCT ps;
841 RECT rc;
842 HDC hDC;
843 HPEN hOldPen;
844 HBRUSH hBrush;
845 int textlen;
846 char *text;
847 HANDLE hText;
848 SIZE size;
850 hDC = BeginPaint(hWnd, &ps);
851 GetClientRect(hWnd, &rc);
853 hOldPen = (HPEN)SelectObject(hDC, sysColorObjects.hpenWindowText);
855 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
856 MAKELPARAM(hWnd, CTLCOLOR_BTN));
857 FillRect(hDC, &rc, hBrush);
859 textlen = GetWindowTextLength(hWnd);
860 hText = USER_HEAP_ALLOC(0, textlen+1);
861 text = USER_HEAP_ADDR(hText);
862 GetWindowText(hWnd, text, textlen+1);
863 GetTextExtentPoint(hDC, text, textlen, &size);
865 rc.top = 5;
866 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
867 rc.left = 10;
868 rc.top = 0;
869 rc.right = rc.left + size.cx + 1;
870 rc.bottom = size.cy;
871 DrawText(hDC, text, textlen, &rc, DT_SINGLELINE);
873 SelectObject(hDC, hOldPen );
874 USER_HEAP_FREE(hText);
875 EndPaint(hWnd, &ps);
879 /**********************************************************************
880 * User Button Functions
883 static LONG UB_Paint(HWND hWnd)
885 PAINTSTRUCT ps;
886 HDC hDC;
887 RECT rc;
888 HBRUSH hBrush;
890 hDC = BeginPaint(hWnd, &ps);
891 GetClientRect(hWnd, &rc);
893 hBrush = SendMessage(GetParent(hWnd), WM_CTLCOLOR, (WORD)hDC,
894 MAKELPARAM(hWnd, CTLCOLOR_BTN));
895 FillRect(hDC, &rc, hBrush);
897 NOTIFY_PARENT(hWnd, BN_PAINT);
899 /* do we have the focus? */
900 if (GetFocus() == hWnd)
901 DrawFocusRect(hDC, &rc);
903 EndPaint(hWnd, &ps);
906 static LONG UB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
908 RECT rc;
910 SetFocus(hWnd);
911 SetCapture(hWnd);
912 GetClientRect(hWnd, &rc);
913 if (PtInRect(&rc, MAKEPOINT(lParam)))
914 NOTIFY_PARENT(hWnd, BN_HILITE);
915 InvalidateRect(hWnd, NULL, FALSE);
916 UpdateWindow(hWnd);
919 static LONG UB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
921 RECT rc;
923 ReleaseCapture();
924 GetClientRect(hWnd, &rc);
925 if (PtInRect(&rc, MAKEPOINT(lParam)))
927 NOTIFY_PARENT(hWnd, BN_CLICKED);
928 NOTIFY_PARENT(hWnd, BN_UNHILITE);
930 InvalidateRect(hWnd, NULL, FALSE);
931 UpdateWindow(hWnd);
934 static LONG UB_KillFocus(HWND hWnd)
936 InvalidateRect(hWnd, NULL, FALSE);
937 UpdateWindow(hWnd);
941 /**********************************************************************
942 * Ownerdrawn Button Functions
945 static LONG OB_Paint(HWND hWnd)
947 PAINTSTRUCT ps;
948 HDC hDC;
949 RECT rc;
950 HANDLE hDis;
951 LPDRAWITEMSTRUCT lpdis;
952 WND *wndPtr = WIN_FindWndPtr(hWnd);
953 hDC = BeginPaint(hWnd, &ps);
954 GetClientRect(hWnd, &rc);
955 hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
956 lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
957 lpdis->hDC = hDC;
958 lpdis->itemID = 0;
959 CopyRect(&lpdis->rcItem, &rc);
960 lpdis->CtlID = wndPtr->wIDmenu;
961 lpdis->CtlType = ODT_BUTTON;
962 lpdis->itemAction = ODA_DRAWENTIRE;
963 /* printf("ownerdrawn button WM_DRAWITEM CtrlID=%X\n", lpdis->CtlID);*/
964 SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
965 USER_HEAP_FREE(hDis);
966 EndPaint(hWnd, &ps);
969 static LONG OB_LButtonDown(HWND hWnd, WORD wParam, LONG lParam)
971 HDC hDC;
972 RECT rc;
973 HANDLE hDis;
974 LPDRAWITEMSTRUCT lpdis;
975 WND *wndPtr = WIN_FindWndPtr(hWnd);
976 SetFocus(hWnd);
977 SetCapture(hWnd);
978 hDC = GetDC(hWnd);
979 GetClientRect(hWnd, &rc);
980 if (PtInRect(&rc, MAKEPOINT(lParam)))
981 NOTIFY_PARENT(hWnd, BN_CLICKED);
982 GetClientRect(hWnd, &rc);
983 hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
984 lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
985 lpdis->hDC = hDC;
986 lpdis->itemID = 0;
987 CopyRect(&lpdis->rcItem, &rc);
988 lpdis->CtlID = wndPtr->wIDmenu;
989 lpdis->CtlType = ODT_BUTTON;
990 lpdis->itemAction = ODA_SELECT;
991 SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
992 USER_HEAP_FREE(hDis);
993 ReleaseDC(hWnd, hDC);
996 static LONG OB_LButtonUp(HWND hWnd, WORD wParam, LONG lParam)
998 HDC hDC;
999 RECT rc;
1000 HANDLE hDis;
1001 LPDRAWITEMSTRUCT lpdis;
1002 WND *wndPtr = WIN_FindWndPtr(hWnd);
1003 ReleaseCapture();
1004 hDC = GetDC(hWnd);
1005 GetClientRect(hWnd, &rc);
1006 if (PtInRect(&rc, MAKEPOINT(lParam)))
1007 NOTIFY_PARENT(hWnd, BN_CLICKED);
1008 GetClientRect(hWnd, &rc);
1009 hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
1010 lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
1011 lpdis->hDC = hDC;
1012 lpdis->itemID = 0;
1013 CopyRect(&lpdis->rcItem, &rc);
1014 lpdis->CtlID = wndPtr->wIDmenu;
1015 lpdis->CtlType = ODT_BUTTON;
1016 lpdis->itemAction = ODA_SELECT;
1017 SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis);
1018 USER_HEAP_FREE(hDis);
1019 ReleaseDC(hWnd, hDC);
1022 static LONG OB_KillFocus(HWND hWnd)
1024 InvalidateRect(hWnd, NULL, FALSE);
1025 UpdateWindow(hWnd);