source: branches/swt/src/user32/button.cpp@ 22094

Last change on this file since 22094 was 22094, checked in by rousseau, 11 years ago

Fixed button text alignment

File size: 35.2 KB
Line 
1/* $Id: button.cpp,v 1.47 2003-04-02 12:58:01 sandervl Exp $ */
2/* File: button.cpp -- Button type widgets
3 *
4 * Copyright (C) 1993 Johannes Ruscheinski
5 * Copyright (C) 1993 David Metcalfe
6 * Copyright (C) 1994 Alexandre Julliard
7 * Copyright (c) 1999 Christoph Bratschi
8 *
9 * Corel version: 20000513
10 * (WINE version: 20000130)
11 *
12 * Status: complete
13 * Version: 5.00
14 */
15
16#include <string.h>
17#include <stdlib.h>
18#include <os2win.h>
19#include "controls.h"
20#include "button.h"
21#include <misc.h>
22#include "initterm.h"
23#include "syscolor.h"
24
25#define DBG_LOCALLOG DBG_button
26#include "dbglocal.h"
27
28#ifdef DEBUG
29char *GetMsgText(int Msg);
30#endif
31
32//Prototypes
33
34static void DrawDisabledText(HDC hdc,char* text,RECT* rtext,UINT format);
35
36static void PB_Paint(HWND hwnd,HDC hDC,WORD action);
37static void CB_Paint(HWND hwnd,HDC hDC,WORD action);
38static void GB_Paint(HWND hwnd,HDC hDC,WORD action);
39static void UB_Paint(HWND hwnd,HDC hDC,WORD action);
40static void OB_Paint(HWND hwnd,HDC hDC,WORD action);
41static void BUTTON_CheckAutoRadioButton(HWND hwnd);
42static void BUTTON_DrawPushButton(HWND hwnd,HDC hDC,WORD action,BOOL pushedState);
43static LRESULT BUTTON_LButtonDown(HWND hwnd,WPARAM wParam,LPARAM lParam);
44
45#define MAX_BTN_TYPE 12
46
47static const WORD maxCheckState[MAX_BTN_TYPE] =
48{
49 BUTTON_UNCHECKED, /* BS_PUSHBUTTON */
50 BUTTON_UNCHECKED, /* BS_DEFPUSHBUTTON */
51 BUTTON_CHECKED, /* BS_CHECKBOX */
52 BUTTON_CHECKED, /* BS_AUTOCHECKBOX */
53 BUTTON_CHECKED, /* BS_RADIOBUTTON */
54 BUTTON_3STATE, /* BS_3STATE */
55 BUTTON_3STATE, /* BS_AUTO3STATE */
56 BUTTON_UNCHECKED, /* BS_GROUPBOX */
57 BUTTON_UNCHECKED, /* BS_USERBUTTON */
58 BUTTON_CHECKED, /* BS_AUTORADIOBUTTON */
59 BUTTON_UNCHECKED, /* Not defined */
60 BUTTON_UNCHECKED /* BS_OWNERDRAW */
61};
62
63typedef void (*pfPaint)(HWND hwnd,HDC hdc,WORD action);
64
65static const pfPaint btnPaintFunc[MAX_BTN_TYPE] =
66{
67 PB_Paint, /* BS_PUSHBUTTON */
68 PB_Paint, /* BS_DEFPUSHBUTTON */
69 CB_Paint, /* BS_CHECKBOX */
70 CB_Paint, /* BS_AUTOCHECKBOX */
71 CB_Paint, /* BS_RADIOBUTTON */
72 CB_Paint, /* BS_3STATE */
73 CB_Paint, /* BS_AUTO3STATE */
74 GB_Paint, /* BS_GROUPBOX */
75 UB_Paint, /* BS_USERBUTTON */
76 CB_Paint, /* BS_AUTORADIOBUTTON */
77 NULL, /* Not defined */
78 OB_Paint /* BS_OWNERDRAW */
79};
80
81
82// 2001-08-29 PH
83// Microsoft ACMSETUP has a OWNERDRAW pushbutton dialog. After finishing
84// the dialog, the pushbuttons are de-initialized immediately.
85// However, OSLibWinDestroyWindow sent WM_SETFOCUS causing the (invisible)
86// buttons to be drawn, resulting in immediate crash.
87// -> IsWindowVisible() check introduced as is in WINE.
88
89#define PAINT_BUTTON(hwnd,style,action) \
90 if (btnPaintFunc[style] && IsWindowVisible(hwnd) ) { \
91 HDC hdc = GetDC(hwnd); \
92 (btnPaintFunc[style])(hwnd,hdc,action); \
93 ReleaseDC(hwnd,hdc); }
94
95#define BUTTON_SEND_CTLCOLOR(hwnd,hdc) \
96 SendMessageA( GetParent(hwnd), WM_CTLCOLORBTN, \
97 (hdc),hwnd)
98
99static HBITMAP hbitmapCheckBoxes = 0;
100static WORD checkBoxWidth = 0, checkBoxHeight = 0;
101
102static LRESULT BUTTON_SendNotify(HWND hwnd,DWORD code)
103{
104 return SendMessageA(GetParent(hwnd),WM_COMMAND,MAKEWPARAM(GetWindowLongA(hwnd,GWL_ID),code),hwnd);
105}
106
107static LRESULT BUTTON_GetDlgCode(HWND hwnd,WPARAM wParam,LPARAM lParam)
108{
109 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
110
111 switch (dwStyle & 0x0f)
112 {
113 case BS_AUTOCHECKBOX:
114 case BS_CHECKBOX:
115 return DLGC_WANTCHARS | DLGC_BUTTON;
116
117 case BS_PUSHBUTTON:
118 return DLGC_UNDEFPUSHBUTTON;
119
120 case BS_DEFPUSHBUTTON:
121 return DLGC_DEFPUSHBUTTON;
122
123 case BS_AUTORADIOBUTTON:
124 case BS_RADIOBUTTON:
125 return DLGC_RADIOBUTTON;
126
127 case BS_GROUPBOX:;
128 return DLGC_STATIC;
129
130 default:
131 return DLGC_BUTTON;
132 }
133}
134
135static LRESULT BUTTON_Enable(HWND hwnd,WPARAM wParam,LPARAM lParam)
136{
137 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
138
139//// if ((dwStyle & BS_NOTIFY) && !wParam) BUTTON_SendNotify(hwnd,BN_DISABLE);
140
141 //PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
142 //SvL: 09/10/99 Force it to redraw properly
143 InvalidateRect( hwnd, NULL, FALSE );
144
145 return 0;
146}
147
148static LRESULT BUTTON_Create(HWND hwnd,WPARAM wParam,LPARAM lParam)
149{
150 BUTTONINFO* infoPtr;
151 DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0f;
152
153 if (!hbitmapCheckBoxes)
154 {
155 BITMAP bmp;
156
157 hbitmapCheckBoxes = LoadBitmapA(hInstanceUser32, MAKEINTRESOURCEA(OBM_CHECKBOXES));
158 GetObjectA( hbitmapCheckBoxes, sizeof(bmp), &bmp );
159 if (GetObjectA(hbitmapCheckBoxes,sizeof(bmp),&bmp))
160 {
161 checkBoxWidth = bmp.bmWidth / 4;
162 checkBoxHeight = bmp.bmHeight / 3;
163 } else checkBoxWidth = checkBoxHeight = 0;
164 }
165 if ((style < 0L) || (style >= MAX_BTN_TYPE)) return -1; /* abort */
166
167 infoPtr = (BUTTONINFO*)malloc(sizeof(BUTTONINFO));
168 infoPtr->state = BUTTON_UNCHECKED;
169 infoPtr->hFont = 0;
170 infoPtr->hImage = 0;
171 SetInfoPtr(hwnd,(DWORD)infoPtr);
172
173 return 0;
174}
175
176static LRESULT BUTTON_Destroy(HWND hwnd,WPARAM wParam,LPARAM lParam)
177{
178 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
179
180 free(infoPtr);
181
182 return 0;
183}
184
185static LRESULT BUTTON_EraseBkgnd(HWND hwnd,WPARAM wParam,LPARAM lParam)
186{
187 DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0f;
188 //SvL: TODO: NT does something extra for ownerdrawn buttons; check this
189 if(style == BS_OWNERDRAW) {
190 return DefWindowProcA(hwnd, WM_ERASEBKGND, wParam, lParam);
191 }
192 return 1;
193}
194
195static LRESULT BUTTON_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam)
196{
197 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
198 DWORD style = dwStyle & 0x0f;
199
200//// if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_PAINT);
201
202 if (btnPaintFunc[style])
203 {
204 PAINTSTRUCT ps;
205
206 HDC hdc = wParam ? (HDC)wParam : BeginPaint(hwnd,&ps);
207 SetBkMode(hdc,OPAQUE);
208 (btnPaintFunc[style])(hwnd,hdc,ODA_DRAWENTIRE);
209 if(!wParam) EndPaint(hwnd,&ps);
210 } else return DefWindowProcA(hwnd,WM_PAINT,wParam,lParam);
211
212 return 0;
213}
214
215static LRESULT BUTTON_LButtonDblClk(HWND hwnd,WPARAM wParam,LPARAM lParam)
216{
217 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
218 DWORD style = dwStyle & 0x0f;
219
220 if(dwStyle & BS_NOTIFY || style == BS_RADIOBUTTON ||
221 style == BS_USERBUTTON || style == BS_OWNERDRAW)
222 BUTTON_SendNotify(hwnd,BN_DOUBLECLICKED);
223 else BUTTON_LButtonDown(hwnd,wParam,lParam);
224
225 return 0;
226}
227
228static LRESULT BUTTON_LButtonDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
229{
230 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
231 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
232 DWORD style = dwStyle & 0x0F;
233
234 if (style == BS_GROUPBOX) return 0;
235 SetCapture(hwnd);
236 SetFocus(hwnd);
237 SendMessageA(hwnd,BM_SETSTATE,TRUE,0);
238 infoPtr->state |= BUTTON_BTNPRESSED;
239
240//// if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_HILITE);
241
242 return 0;
243}
244
245static LRESULT BUTTON_LButtonUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
246{
247 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
248 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
249 DWORD style = dwStyle & 0x0F;
250 RECT rect;
251 POINT pt;
252
253 pt.x = LOWORD(lParam);
254 pt.y = HIWORD(lParam);
255
256 if (!(infoPtr->state & BUTTON_BTNPRESSED)) return 0;
257 infoPtr->state &= BUTTON_NSTATES;
258 if (!(infoPtr->state & BUTTON_HIGHLIGHTED))
259 {
260 ReleaseCapture();
261 return 0;
262 }
263 SendMessageA(hwnd,BM_SETSTATE,FALSE,0);
264 ReleaseCapture();
265 GetClientRect(hwnd,&rect);
266 if (PtInRect(&rect,pt))
267 {
268 switch(dwStyle & 0x0f)
269 {
270 case BS_AUTOCHECKBOX:
271 SendMessageA(hwnd,BM_SETCHECK,!(infoPtr->state & BUTTON_CHECKED),0);
272 break;
273 case BS_AUTORADIOBUTTON:
274 SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
275 break;
276 case BS_AUTO3STATE:
277 SendMessageA(hwnd,BM_SETCHECK,
278 (infoPtr->state & BUTTON_3STATE) ? 0 :
279 ((infoPtr->state & 3)+1),0);
280 break;
281 }
282 BUTTON_SendNotify(hwnd,BN_CLICKED);
283 }
284
285//// if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_UNHILITE);
286
287 return 0;
288}
289
290static LRESULT BUTTON_CaptureChanged(HWND hwnd,WPARAM wParam,LPARAM lParam)
291{
292 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
293 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
294
295 if (infoPtr->state & BUTTON_BTNPRESSED)
296 {
297 infoPtr->state &= BUTTON_NSTATES;
298 if (infoPtr->state & BUTTON_HIGHLIGHTED)
299 SendMessageA( hwnd, BM_SETSTATE, FALSE, 0 );
300 }
301
302//// if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_UNHILITE);
303
304 return 0;
305}
306
307static LRESULT BUTTON_MouseMove(HWND hwnd,WPARAM wParam,LPARAM lParam)
308{
309 if (GetCapture() == hwnd)
310 {
311 RECT rect;
312 POINT pt;
313
314 pt.x = LOWORD(lParam);
315 pt.y = HIWORD(lParam);
316
317 GetClientRect(hwnd,&rect);
318 SendMessageA(hwnd,BM_SETSTATE,PtInRect(&rect,pt),0);
319 }
320
321 return 0;
322}
323
324static LRESULT BUTTON_NCHitTest(HWND hwnd,WPARAM wParam,LPARAM lParam)
325{
326 DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0f;
327
328 if (style == BS_GROUPBOX) return HTTRANSPARENT;
329
330 return DefWindowProcA(hwnd,WM_NCHITTEST,wParam,lParam);
331}
332
333static LRESULT BUTTON_SetText(HWND hwnd,WPARAM wParam,LPARAM lParam)
334{
335 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
336
337 LRESULT result = DefWindowProcA(hwnd,WM_SETTEXT,wParam,lParam);
338#ifdef __WIN32OS2__
339 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
340 if ((dwStyle & 0x0f) == BS_GROUPBOX) {
341 RECT rc;
342 TEXTMETRICA tm;
343 HDC hdc = GetDC(hwnd);
344 int fh1 = 0, fh2 = 0;
345
346 // select old font (if exists)
347 if (infoPtr->hFont) {
348 SelectObject (hdc, infoPtr->hFont);
349 GetTextMetricsA (hdc, &tm);
350 fh1 = tm.tmHeight;
351 }
352 // select new font (if exists)
353 if (wParam) {
354 SelectObject (hdc, wParam);
355 GetTextMetricsA (hdc, &tm);
356 fh2 = tm.tmHeight;
357 }
358 // Erases top border line and (old) text background
359 GetClientRect(hwnd, &rc);
360 rc.bottom = rc.top + max( fh1, fh2) + 1;
361 HBRUSH hbr = GetControlBrush( hwnd, hdc, CTLCOLOR_STATIC );
362 FillRect(hdc, &rc, hbr);
363 ReleaseDC(hwnd,hdc);
364 }
365#endif
366
367 if (dwStyle & WS_VISIBLE) PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
368
369 return result;
370}
371
372static LRESULT BUTTON_SetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
373{
374 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
375 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
376
377#ifdef __WIN32OS2__
378 if ((dwStyle & 0x0f) == BS_GROUPBOX && IsWindowVisible(hwnd)) {
379 RECT rc;
380 TEXTMETRICA tm;
381 HDC hdc = GetDC(hwnd);
382 int fh1 = 0, fh2 = 0;
383
384 // select old font (if exists)
385 if (infoPtr->hFont) {
386 SelectObject (hdc, infoPtr->hFont);
387 GetTextMetricsA (hdc, &tm);
388 fh1 = tm.tmHeight;
389 }
390 // select new font (if exists)
391 if (wParam) {
392 SelectObject (hdc, wParam);
393 GetTextMetricsA (hdc, &tm);
394 fh2 = tm.tmHeight;
395 }
396 // Erases top border line and (old) text background
397 GetClientRect(hwnd, &rc);
398 rc.bottom = rc.top + max( fh1, fh2) + 1;
399 HBRUSH hbr = GetControlBrush( hwnd, hdc, CTLCOLOR_STATIC );
400 FillRect(hdc, &rc, hbr);
401 ReleaseDC(hwnd,hdc);
402 }
403#endif
404
405 infoPtr->hFont = (HFONT)wParam;
406 if (lParam && (dwStyle & WS_VISIBLE)) PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
407
408 return 0;
409}
410
411static LRESULT BUTTON_GetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
412{
413 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
414
415 return infoPtr->hFont;
416}
417
418static LRESULT BUTTON_KeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
419{
420 if (wParam == VK_SPACE)
421 {
422 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
423
424 SendMessageA(hwnd,BM_SETSTATE,TRUE,0);
425 infoPtr->state |= BUTTON_BTNPRESSED;
426 }
427
428 return 0;
429}
430
431static LRESULT BUTTON_KeyUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
432{
433 if (wParam == VK_SPACE)
434 {
435 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
436 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
437
438 if (!(infoPtr->state & BUTTON_BTNPRESSED)) return 0;
439 infoPtr->state &= BUTTON_NSTATES;
440 if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) return 0;
441 SendMessageA(hwnd,BM_SETSTATE,FALSE,0);
442
443 switch(dwStyle & 0x0f)
444 {
445 case BS_AUTOCHECKBOX:
446 SendMessageA(hwnd,BM_SETCHECK,!(infoPtr->state & BUTTON_CHECKED),0);
447 break;
448 case BS_AUTORADIOBUTTON:
449 SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
450 break;
451 case BS_AUTO3STATE:
452 SendMessageA(hwnd,BM_SETCHECK,
453 (infoPtr->state & BUTTON_3STATE) ? 0 :
454 ((infoPtr->state & 3)+1),0);
455 break;
456 }
457 BUTTON_SendNotify(hwnd,BN_CLICKED);
458 }
459
460 return 0;
461}
462
463static LRESULT BUTTON_SysKeyUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
464{
465 if (wParam != VK_TAB) ReleaseCapture();
466
467 return 0;
468}
469
470static LRESULT BUTTON_SetFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
471{
472 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
473 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
474 DWORD style = dwStyle & 0x0f;
475
476 if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_SETFOCUS);
477
478 if (((style == BS_AUTORADIOBUTTON) || (style == BS_RADIOBUTTON)) &&
479 (GetCapture() != hwnd) && !(SendMessageA(hwnd,BM_GETCHECK,0,0) & BST_CHECKED))
480 {
481 /* The notification is sent when the button (BS_AUTORADIOBUTTON)
482 is unckecked and the focus was not given by a mouse click. */
483 if (style == BS_AUTORADIOBUTTON) SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
484 BUTTON_SendNotify(hwnd,BN_CLICKED);
485 }
486
487 infoPtr->state |= BUTTON_HASFOCUS;
488 PAINT_BUTTON(hwnd,style,ODA_FOCUS);
489
490 return 0;
491}
492
493static LRESULT BUTTON_KillFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
494{
495 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
496 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
497 DWORD style = dwStyle & 0x0f;
498
499 if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_KILLFOCUS);
500
501 if (infoPtr->state & BUTTON_HASFOCUS)
502 {
503 infoPtr->state &= ~BUTTON_HASFOCUS;
504 PAINT_BUTTON(hwnd,style,ODA_FOCUS);
505 }
506
507 return 0;
508}
509
510static LRESULT BUTTON_SysColorChange(HWND hwnd,WPARAM wParam,LPARAM lParam)
511{
512 InvalidateRect(hwnd,NULL,FALSE);
513
514 return 0;
515}
516
517static LRESULT BUTTON_Click(HWND hwnd,WPARAM wParam,LPARAM lParam)
518{
519 RECT rect;
520 LPARAM point;
521
522 GetClientRect(hwnd,&rect);
523 point = MAKELPARAM(rect.right/2,rect.bottom/2);
524 SendMessageA(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,point);
525 Sleep(100);
526 SendMessageA(hwnd,WM_LBUTTONUP,0,point);
527
528 return 0;
529}
530
531static LRESULT BUTTON_SetStyle(HWND hwnd,WPARAM wParam,LPARAM lParam)
532{
533 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE),newStyle;
534
535 if ((wParam & 0x0F) >= MAX_BTN_TYPE) return 0;
536 newStyle = (dwStyle & 0xFFFFFFF0) | (wParam & 0x0000000F);
537
538 if (newStyle != dwStyle)
539 {
540 SetWindowLongA(hwnd,GWL_STYLE,newStyle);
541 PAINT_BUTTON(hwnd,newStyle & 0x0F,ODA_DRAWENTIRE);
542 }
543
544 return 0;
545}
546
547static LRESULT BUTTON_SetImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
548{
549 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
550 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
551 HANDLE oldHbitmap = infoPtr->hImage;
552
553 if ((dwStyle & BS_BITMAP) || (dwStyle & BS_ICON))
554 {
555 infoPtr->hImage = (HANDLE)lParam;
556 InvalidateRect(hwnd,NULL,FALSE);
557 }
558
559 return oldHbitmap;
560}
561
562static LRESULT BUTTON_GetImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
563{
564 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
565
566 switch(wParam)
567 {
568 case IMAGE_BITMAP:
569 return (HBITMAP)infoPtr->hImage;
570 case IMAGE_ICON:
571 return (HICON)infoPtr->hImage;
572 default:
573 return (HICON)0;
574 }
575}
576
577static LRESULT BUTTON_GetCheck(HWND hwnd,WPARAM wParam,LPARAM lParam)
578{
579 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
580
581 return infoPtr->state & 3;
582}
583
584static LRESULT BUTTON_SetCheck(HWND hwnd,WPARAM wParam,LPARAM lParam)
585{
586 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
587 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
588 DWORD style = dwStyle & 0x0f;
589
590 if (wParam > maxCheckState[style]) wParam = maxCheckState[style];
591#ifndef __WIN32OS2__
592 //Must clear WS_TABSTOP of control that is already disabled or else
593 //multiple control can have this style ((auto)radiobutton) and
594 //GetNextDlgTabItem will return the wrong one
595 //Happens in Opera preferences dialog (multimedia) where all autoradio
596 //buttons have the WS_TABSTOP style.
597 if ((infoPtr->state & 3) != wParam)
598 {
599#endif
600 if ((style == BS_RADIOBUTTON) || (style == BS_AUTORADIOBUTTON))
601 {
602 DWORD oldStyle = dwStyle;
603
604 if (wParam)
605 dwStyle |= WS_TABSTOP;
606 else
607 dwStyle &= ~WS_TABSTOP;
608
609 if (oldStyle != dwStyle) SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
610 }
611#ifdef __WIN32OS2__
612 if ((infoPtr->state & 3) != wParam)
613 {
614#endif
615 infoPtr->state = (infoPtr->state & ~3) | wParam;
616 PAINT_BUTTON(hwnd,style,ODA_SELECT);
617 }
618 if ((style == BS_AUTORADIOBUTTON) && (wParam == BUTTON_CHECKED))
619 BUTTON_CheckAutoRadioButton(hwnd);
620
621 return 0;
622}
623
624static LRESULT BUTTON_GetState(HWND hwnd,WPARAM wParam,LPARAM lParam)
625{
626 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
627
628 return infoPtr->state;
629}
630
631static LRESULT BUTTON_SetState(HWND hwnd,WPARAM wParam,LPARAM lParam)
632{
633 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
634 DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0F;
635
636 if (wParam)
637 {
638 if (infoPtr->state & BUTTON_HIGHLIGHTED) return 0;
639 infoPtr->state |= BUTTON_HIGHLIGHTED;
640 } else
641 {
642 if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) return 0;
643 infoPtr->state &= ~BUTTON_HIGHLIGHTED;
644 }
645 PAINT_BUTTON(hwnd,style,ODA_SELECT);
646
647 return 0;
648}
649
650/***********************************************************************
651 * ButtonWndProc
652 */
653static
654LRESULT WINAPI ButtonWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
655{
656// dprintf(("ButtonWndProc hwnd: %04x, msg %s, wp %08x lp %08lx\n",
657// hwnd, GetMsgText(uMsg), wParam, lParam));
658
659 switch (uMsg)
660 {
661 case WM_GETDLGCODE:
662 return BUTTON_GetDlgCode(hwnd,wParam,lParam);
663
664 case WM_ENABLE:
665 return BUTTON_Enable(hwnd,wParam,lParam);
666
667 case WM_CREATE:
668 return BUTTON_Create(hwnd,wParam,lParam);
669
670 case WM_DESTROY:
671 return BUTTON_Destroy(hwnd,wParam,lParam);
672
673 case WM_ERASEBKGND:
674 return BUTTON_EraseBkgnd(hwnd,wParam,lParam);
675
676 case WM_PAINT:
677 return BUTTON_Paint(hwnd,wParam,lParam);
678
679 case WM_LBUTTONDBLCLK:
680 return BUTTON_LButtonDblClk(hwnd,wParam,lParam);
681
682 case WM_LBUTTONDOWN:
683 return BUTTON_LButtonDown(hwnd,wParam,lParam);
684
685 case WM_LBUTTONUP:
686 return BUTTON_LButtonUp(hwnd,wParam,lParam);
687
688 case WM_CAPTURECHANGED:
689 return BUTTON_CaptureChanged(hwnd,wParam,lParam);
690
691 case WM_MOUSEMOVE:
692 return BUTTON_MouseMove(hwnd,wParam,lParam);
693
694 case WM_NCHITTEST:
695 return BUTTON_NCHitTest(hwnd,wParam,lParam);
696
697 case WM_SETTEXT:
698 return BUTTON_SetText(hwnd,wParam,lParam);
699
700 case WM_SETFONT:
701 return BUTTON_SetFont(hwnd,wParam,lParam);
702
703 case WM_GETFONT:
704 return BUTTON_GetFont(hwnd,wParam,lParam);
705
706 case WM_KEYDOWN:
707 return BUTTON_KeyDown(hwnd,wParam,lParam);
708
709 case WM_KEYUP:
710 return BUTTON_KeyUp(hwnd,wParam,lParam);
711
712 case WM_SYSKEYUP:
713 return BUTTON_SysKeyUp(hwnd,wParam,lParam);
714
715 case WM_SETFOCUS:
716 return BUTTON_SetFocus(hwnd,wParam,lParam);
717
718 case WM_KILLFOCUS:
719 return BUTTON_KillFocus(hwnd,wParam,lParam);
720
721 case WM_SYSCOLORCHANGE:
722 return BUTTON_SysColorChange(hwnd,wParam,lParam);
723
724 case BM_CLICK:
725 return BUTTON_Click(hwnd,wParam,lParam);
726
727 case BM_SETSTYLE:
728 return BUTTON_SetStyle(hwnd,wParam,lParam);
729
730 case BM_SETIMAGE:
731 return BUTTON_SetImage(hwnd,wParam,lParam);
732
733 case BM_GETIMAGE:
734 return BUTTON_GetImage(hwnd,wParam,lParam);
735
736 case BM_GETCHECK:
737 return BUTTON_GetCheck(hwnd,wParam,lParam);
738
739 case BM_SETCHECK:
740 return BUTTON_SetCheck(hwnd,wParam,lParam);
741
742 case BM_GETSTATE:
743 return BUTTON_GetState(hwnd,wParam,lParam);
744
745 case BM_SETSTATE:
746 return BUTTON_SetState(hwnd,wParam,lParam);
747
748 default:
749 return DefWindowProcA(hwnd,uMsg,wParam,lParam);
750 }
751
752 return 0;
753}
754
755
756/**********************************************************************
757 * Push Button Functions
758 */
759static void PB_Paint( HWND hwnd, HDC hDC, WORD action )
760{
761 BUTTONINFO *infoPtr = (BUTTONINFO *)GetInfoPtr(hwnd);
762 BOOL bHighLighted = (infoPtr->state & BUTTON_HIGHLIGHTED);
763
764 /*
765 * Delegate this to the more generic pushbutton painting
766 * method.
767 */
768 BUTTON_DrawPushButton(hwnd,
769 hDC,
770 action,
771 bHighLighted);
772}
773
774static INT BUTTON_GetTextFormat(DWORD dwStyle,DWORD dwExStyle,INT defHorz,INT defVert)
775{
776 INT format = 0;
777
778 if (dwStyle & BS_LEFT) format = DT_LEFT;
779 else if (dwStyle & BS_CENTER) format = DT_CENTER;
780 else if ((dwStyle & BS_RIGHT) || (dwExStyle & WS_EX_RIGHT)) format = DT_RIGHT;
781 else format = defHorz;
782
783/*
784 if (dwStyle & BS_TOP) format |= DT_TOP;
785 else if (dwStyle & BS_VCENTER) format |= DT_VCENTER;
786 else if (dwStyle & BS_BOTTOM) format |= DT_BOTTOM;
787 else format |= defVert;
788*/
789
790 /*
791 * BS_CENTER is not a single bit-flag, but is actually BS_LEFT | BS_RIGHT.
792 * So we need an extra compare to distinguish it.
793 * TODO: Scan for more occurences like this and other multi-bit flags
794 */
795 if ((dwStyle & BS_CENTER) == BS_LEFT) format = DT_LEFT;
796 else if ((dwStyle & BS_CENTER) == BS_CENTER) format = DT_CENTER;
797 else if (((dwStyle & BS_RIGHT) == BS_RIGHT) || ((dwExStyle & WS_EX_RIGHT) == BS_RIGHT)) format = DT_RIGHT;
798 else format = defHorz;
799 if (!(dwStyle & BS_MULTILINE)) format |= DT_SINGLELINE;
800
801 return format;
802}
803
804/**********************************************************************
805 * This method will actually do the drawing of the pushbutton
806 * depending on it's state and the pushedState parameter.
807 */
808static void BUTTON_DrawPushButton(
809 HWND hwnd,
810 HDC hDC,
811 WORD action,
812 BOOL pushedState )
813{
814 RECT rc, focus_rect;
815 HPEN hOldPen;
816 HBRUSH hOldBrush;
817 BUTTONINFO *infoPtr = (BUTTONINFO *)GetInfoPtr(hwnd);
818 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
819 int xBorderOffset, yBorderOffset;
820 xBorderOffset = yBorderOffset = 0;
821 INT textLen;
822 char* text;
823
824 GetClientRect( hwnd, &rc );
825
826 /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
827 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
828 BUTTON_SEND_CTLCOLOR( hwnd, hDC );
829 hOldPen = (HPEN)SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
830 hOldBrush =(HBRUSH)SelectObject(hDC,GetSysColorBrush(COLOR_BTNFACE));
831 SetBkMode(hDC, TRANSPARENT);
832
833 if ((dwStyle & 0x000f) == BS_DEFPUSHBUTTON)
834 {
835 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
836 InflateRect( &rc, -1, -1 );
837 }
838
839 UINT uState = DFCS_BUTTONPUSH;
840
841 if (pushedState)
842 {
843 if ( (dwStyle & 0x000f) == BS_DEFPUSHBUTTON )
844 uState |= DFCS_FLAT;
845 else
846 uState |= DFCS_PUSHED;
847 }
848
849 if (dwStyle & BS_FLAT) uState |= DFCS_FLAT;
850
851 DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
852 InflateRect( &rc, -2, -2 );
853
854 focus_rect = rc;
855
856 if (pushedState)
857 {
858 rc.left += 2; /* To position the text down and right */
859 rc.top += 2;
860 }
861
862
863 /* draw button label, if any:
864 *
865 * In win9x we don't show text if there is a bitmap or icon.
866 * I don't know about win31 so I leave it as it was for win31.
867 * Dennis Björklund 12 Jul, 99
868 */
869 textLen = GetWindowTextLengthA(hwnd);
870 if ((textLen > 0) && (!(dwStyle & (BS_ICON|BS_BITMAP))))
871 {
872 INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_CENTER,DT_VCENTER);
873
874 textLen++;
875 text = (char*)malloc(textLen);
876 GetWindowTextA(hwnd,text,textLen);
877
878 if (dwStyle & WS_DISABLED) DrawDisabledText(hDC,text,&rc,format); else
879 {
880 SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
881 DrawTextA(hDC,text,-1,&rc,format);
882 /* do we have the focus?
883 * Win9x draws focus last with a size prop. to the button
884 */
885 }
886 free(text);
887 }
888 if ( ((dwStyle & BS_ICON) || (dwStyle & BS_BITMAP) ) &&
889 (infoPtr->hImage != 0) )
890 {
891 int yOffset, xOffset;
892 int imageWidth, imageHeight;
893
894 /*
895 * We extract the size of the image from the handle.
896 */
897 if (dwStyle & BS_ICON)
898 {
899 ICONINFO iconInfo;
900 BITMAP bm;
901
902 GetIconInfo((HICON)infoPtr->hImage,&iconInfo);
903 if (iconInfo.hbmColor)
904 {
905 GetObjectA(iconInfo.hbmColor,sizeof(BITMAP),&bm);
906 imageWidth = bm.bmWidth;
907 imageHeight = bm.bmHeight;
908 } else
909 {
910 GetObjectA(iconInfo.hbmMask,sizeof(BITMAP),&bm);
911 imageWidth = bm.bmWidth;
912 imageHeight = bm.bmHeight/2;
913 }
914
915 if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
916 if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
917
918 }
919 else
920 {
921 BITMAP bm;
922
923 GetObjectA (infoPtr->hImage, sizeof(BITMAP), &bm);
924
925 imageWidth = bm.bmWidth;
926 imageHeight = bm.bmHeight;
927 }
928
929 /* Center the bitmap */
930 xOffset = (((rc.right - rc.left) - 2*xBorderOffset) - imageWidth ) / 2;
931 yOffset = (((rc.bottom - rc.top) - 2*yBorderOffset) - imageHeight) / 2;
932
933 /* If the image is too big for the button then create a region*/
934 if(xOffset < 0 || yOffset < 0)
935 {
936 HRGN hBitmapRgn = 0;
937 hBitmapRgn = CreateRectRgn(
938 rc.left + xBorderOffset, rc.top +yBorderOffset,
939 rc.right - xBorderOffset, rc.bottom - yBorderOffset);
940 SelectClipRgn(hDC, hBitmapRgn);
941 DeleteObject(hBitmapRgn);
942 }
943
944 /* Let minimum 1 space from border */
945 xOffset++, yOffset++;
946
947 /*
948 * Draw the image now.
949 */
950 if (dwStyle & BS_ICON)
951 {
952 DrawIcon(hDC,
953 rc.left + xOffset, rc.top + yOffset,
954 (HICON)infoPtr->hImage);
955 }
956 else
957 {
958 HDC hdcMem;
959
960 hdcMem = CreateCompatibleDC (hDC);
961 SelectObject (hdcMem, (HBITMAP)infoPtr->hImage);
962 BitBlt(hDC,
963 rc.left + xOffset,
964 rc.top + yOffset,
965 imageWidth, imageHeight,
966 hdcMem, 0, 0, SRCCOPY);
967
968 DeleteDC (hdcMem);
969 }
970
971 if(xOffset < 0 || yOffset < 0)
972 {
973 SelectClipRgn(hDC, 0);
974 }
975 }
976
977 SelectObject( hDC, hOldPen );
978 SelectObject( hDC, hOldBrush );
979
980 if ((infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd))
981 {
982 InflateRect( &focus_rect, -1, -1 );
983 DrawFocusRect( hDC, &focus_rect );
984 }
985}
986
987
988static void DrawDisabledText(HDC hdc,char* text,RECT* rtext,UINT format)
989{
990 COLORREF textColor = (GetSysColor(COLOR_GRAYTEXT) == GetBkColor(hdc)) ? COLOR_BTNTEXT:COLOR_GRAYTEXT;
991 RECT rect = *rtext;
992 COLORREF oldMode;
993
994 //CB: bug in Open32 DrawText: underscore is always black! -> two black lines!
995 SetTextColor(hdc,GetSysColor(COLOR_3DHILIGHT));
996 DrawTextA(hdc,text,-1,&rect,format);
997 SetTextColor(hdc,GetSysColor(COLOR_GRAYTEXT));
998 oldMode = SetBkMode(hdc,TRANSPARENT);
999 OffsetRect(&rect,-1,-1);
1000 DrawTextA(hdc,text,-1,&rect,format);
1001 SetBkMode(hdc,oldMode);
1002}
1003
1004/**********************************************************************
1005 * Check Box & Radio Button Functions
1006 */
1007
1008static void CB_Paint(HWND hwnd,HDC hDC,WORD action)
1009{
1010 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1011 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1012 RECT rbox, rtext, client;
1013 HBRUSH hBrush, hOldBrush;
1014 HPEN hPen, hOldPen;
1015 COLORREF colour;
1016 int textLen, delta;
1017 char* text = NULL;
1018
1019 /*
1020 * if the button has a bitmap/icon, draw a normal pushbutton
1021 * instead of a radion button.
1022 */
1023 if (infoPtr->hImage != 0)
1024 {
1025 BOOL bHighLighted = ((infoPtr->state & BUTTON_HIGHLIGHTED) ||
1026 (infoPtr->state & BUTTON_CHECKED));
1027
1028 BUTTON_DrawPushButton(hwnd,
1029 hDC,
1030 action,
1031 bHighLighted);
1032 return;
1033 }
1034
1035 textLen = 0;
1036 GetClientRect(hwnd, &client);
1037 rbox = rtext = client;
1038
1039 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
1040
1041#ifdef __WIN32OS2__
1042 //(Auto)Check, (Auto)Radio & (Auto)3State buttons send WM_CTLCOLORSTATIC
1043 //instead of WM_CTLCOLORBTN (verified in NT4)
1044 hBrush = SendMessageW( GetParent(hwnd), WM_CTLCOLORSTATIC, hDC, (LPARAM)hwnd );
1045 if (!hBrush) /* did the app forget to call defwindowproc ? */
1046 hBrush = DefWindowProcW( GetParent(hwnd), WM_CTLCOLORSTATIC, hDC, (LPARAM)hwnd );
1047#endif
1048
1049 if (dwStyle & BS_LEFTTEXT)
1050 {
1051 /* magic +4 is what CTL3D expects */
1052
1053 rtext.right -= checkBoxWidth + 4;
1054 //CB: space for focus rect
1055 rtext.left++;
1056 rtext.right++;
1057 rbox.left = rbox.right - checkBoxWidth;
1058 }
1059 else
1060 {
1061 rtext.left += checkBoxWidth + 4;
1062 rbox.right = checkBoxWidth;
1063 }
1064
1065 /* Draw the check-box bitmap */
1066
1067 textLen = GetWindowTextLengthA(hwnd);
1068 if (textLen > 0)
1069 {
1070 textLen++;
1071 text = (char*)malloc(textLen);
1072 GetWindowTextA(hwnd,text,textLen);
1073 }
1074 if ((action == ODA_DRAWENTIRE) || (action == ODA_SELECT))
1075 {
1076 UINT state;
1077
1078 /* Since WM_ERASEBKGND does nothing, first prepare background */
1079 if (action == ODA_SELECT) FillRect( hDC, &rbox, hBrush );
1080 else FillRect( hDC, &client, hBrush );
1081
1082 if (((dwStyle & 0x0f) == BS_RADIOBUTTON) ||
1083 ((dwStyle & 0x0f) == BS_AUTORADIOBUTTON)) state = DFCS_BUTTONRADIO;
1084 else if (infoPtr->state & BUTTON_3STATE) state = DFCS_BUTTON3STATE;
1085 else state = DFCS_BUTTONCHECK;
1086
1087 if (infoPtr->state & (BUTTON_CHECKED | BUTTON_3STATE)) state |= DFCS_CHECKED;
1088
1089 if (infoPtr->state & BUTTON_HIGHLIGHTED) state |= DFCS_PUSHED;
1090
1091 if (dwStyle & WS_DISABLED) state |= DFCS_INACTIVE;
1092
1093 if (dwStyle & BS_FLAT) state |= DFCS_FLAT;
1094
1095 DrawFrameControl( hDC, &rbox, DFC_BUTTON, state );
1096
1097 if( text && action != ODA_SELECT )
1098 {
1099 INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_TOP,DT_VCENTER);
1100
1101 if (dwStyle & WS_DISABLED) DrawDisabledText(hDC,text,&rtext,format);
1102 else DrawTextA(hDC,text,-1,&rtext,format);
1103 }
1104 }
1105
1106 if ((action == ODA_FOCUS) ||
1107 ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd)))
1108 {
1109 /* again, this is what CTL3D expects */
1110
1111 SetRectEmpty(&rbox);
1112 if(textLen > 0)
1113 DrawTextA(hDC,text,-1,&rbox,DT_SINGLELINE | DT_CALCRECT);
1114 textLen = rbox.bottom - rbox.top;
1115 delta = ((rtext.bottom - rtext.top) - textLen)/2;
1116 rbox.bottom = (rbox.top = rtext.top + delta - 1) + textLen + 2;
1117 textLen = rbox.right - rbox.left;
1118 rbox.right = (rbox.left += --rtext.left) + textLen + 2;
1119 IntersectRect(&rbox, &rbox, &rtext);
1120 DrawFocusRect( hDC, &rbox );
1121 }
1122 if (text) free(text);
1123}
1124
1125
1126/**********************************************************************
1127 * BUTTON_CheckAutoRadioButton
1128 *
1129 * wndPtr is checked, uncheck every other auto radio button in group
1130 */
1131static void BUTTON_CheckAutoRadioButton(HWND hwnd)
1132{
1133 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1134 HWND parent, sibling, start;
1135
1136 if (!(dwStyle & WS_CHILD)) return;
1137 parent = GetParent(hwnd);
1138 /* assure that starting control is not disabled or invisible */
1139 //start = sibling = GetNextDlgGroupItem( parent, hwnd, TRUE );
1140 //@YD: bugfix
1141 //CB: doesn't work!
1142 start = sibling = GetNextDlgGroupItem( parent, hwnd, TRUE );
1143 do
1144 {
1145 if (!sibling) break;
1146 if ((hwnd != sibling) &&
1147 ((GetWindowLongA(sibling,GWL_STYLE) & 0x0f) == BS_AUTORADIOBUTTON))
1148 SendMessageA( sibling, BM_SETCHECK, BUTTON_UNCHECKED, 0 );
1149 sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
1150 } while (sibling != start);
1151}
1152
1153
1154/**********************************************************************
1155 * Group Box Functions
1156 */
1157
1158static void GB_Paint(HWND hwnd,HDC hDC,WORD action)
1159{
1160 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1161 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1162 RECT rc, rcFrame;
1163 TEXTMETRICA tm;
1164 INT textLen;
1165 char* text;
1166 HBRUSH hbr;
1167
1168 if (action != ODA_DRAWENTIRE) return;
1169
1170 /* GroupBox acts like static control, so it sends CTLCOLORSTATIC */
1171 hbr = GetControlBrush( hwnd, hDC, CTLCOLOR_STATIC );
1172
1173 GetClientRect(hwnd,&rc);
1174
1175 rcFrame = rc;
1176
1177 if (infoPtr->hFont)
1178 SelectObject (hDC, infoPtr->hFont);
1179 GetTextMetricsA (hDC, &tm);
1180 rcFrame.top += (tm.tmHeight / 2) - 1;
1181 DrawEdge (hDC, &rcFrame, EDGE_ETCHED, BF_RECT);
1182
1183 textLen = GetWindowTextLengthA(hwnd);
1184 if (textLen > 0)
1185 {
1186 INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_LEFT,DT_TOP) | DT_NOCLIP | DT_SINGLELINE;
1187
1188 textLen++;
1189 text = (char*)malloc(textLen);
1190 GetWindowTextA(hwnd,text,textLen);
1191 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
1192 rc.left += 10;
1193
1194 if (dwStyle & WS_DISABLED) {
1195 DrawDisabledText(hDC,text,&rc,format);
1196 }
1197 else
1198 {
1199 SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
1200 DrawTextA(hDC,text,-1,&rc,format);
1201 }
1202
1203 free(text);
1204 }
1205}
1206
1207
1208/**********************************************************************
1209 * User Button Functions
1210 */
1211
1212static void UB_Paint(HWND hwnd,HDC hDC,WORD action)
1213{
1214 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1215 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1216 RECT rc;
1217 HBRUSH hBrush;
1218 if (action == ODA_SELECT) return;
1219
1220 GetClientRect(hwnd,&rc);
1221
1222 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
1223 hBrush = GetControlBrush( hwnd, hDC, CTLCOLOR_BTN );
1224
1225 FillRect( hDC, &rc, hBrush );
1226 if ((action == ODA_FOCUS) ||
1227 ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd)))
1228 {
1229 DrawFocusRect( hDC, &rc );
1230 InflateRect(&rc,-1,-1);
1231 }
1232}
1233
1234
1235/**********************************************************************
1236 * Ownerdrawn Button Functions
1237 */
1238
1239static void OB_Paint(HWND hwnd,HDC hDC,WORD action)
1240{
1241 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1242 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1243 DRAWITEMSTRUCT dis;
1244
1245 dis.CtlType = ODT_BUTTON;
1246 dis.CtlID = GetWindowLongA(hwnd,GWL_ID);
1247 dis.itemID = 0;
1248 dis.itemAction = action;
1249 dis.itemState = ((infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0) |
1250 ((infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0) |
1251 ((dwStyle & WS_DISABLED) ? ODS_DISABLED : 0);
1252 dis.hwndItem = hwnd;
1253 dis.hDC = hDC;
1254 dis.itemData = 0;
1255 GetClientRect( hwnd, &dis.rcItem );
1256
1257 SetBkColor( hDC, GetSysColor( COLOR_BTNFACE ) );
1258
1259 dprintf(("OWNERDRAW button %x, enabled %d", hwnd, !(dwStyle & WS_DISABLED)));
1260 SendMessageA( GetParent(hwnd), WM_DRAWITEM,
1261 GetWindowLongA(hwnd,GWL_ID), (LPARAM)&dis );
1262}
1263
1264BOOL BUTTON_Register()
1265{
1266 WNDCLASSA wndClass;
1267
1268//SvL: Don't check this now
1269// if (GlobalFindAtomA(BUTTONCLASSNAME)) return FALSE;
1270
1271 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
1272 wndClass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC | CS_DBLCLKS;
1273 wndClass.lpfnWndProc = (WNDPROC)ButtonWndProc;
1274 wndClass.cbClsExtra = 0;
1275 wndClass.cbWndExtra = sizeof(BUTTONINFO);
1276 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);
1277 wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
1278 wndClass.lpszClassName = BUTTONCLASSNAME;
1279
1280 return RegisterClassA(&wndClass);
1281}
1282
1283BOOL BUTTON_Unregister()
1284{
1285 if (GlobalFindAtomA(BUTTONCLASSNAME))
1286 return UnregisterClassA(BUTTONCLASSNAME,(HINSTANCE)NULL);
1287 else return FALSE;
1288}
Note: See TracBrowser for help on using the repository browser.