source: trunk/src/user32/button.cpp@ 6605

Last change on this file since 6605 was 6605, checked in by phaller, 24 years ago

Fix for ACMSetup, don't draw invisible buttons

File size: 34.2 KB
Line 
1/* $Id: button.cpp,v 1.43 2001-08-29 10:37:25 phaller 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 DefWindowProcA(hwnd,WM_SETTEXT,wParam,lParam);
338 if (dwStyle & WS_VISIBLE) PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
339
340 return 0;
341}
342
343static LRESULT BUTTON_SetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
344{
345 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
346 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
347
348#ifdef __WIN32OS2__
349 if ((dwStyle & 0x0f) == BS_GROUPBOX) {
350 RECT rc;
351 TEXTMETRICA tm;
352 HDC hdc = GetDC(hwnd);
353 int fh1 = 0, fh2 = 0;
354
355 // select old font (if exists)
356 if (infoPtr->hFont) {
357 SelectObject (hdc, infoPtr->hFont);
358 GetTextMetricsA (hdc, &tm);
359 fh1 = tm.tmHeight;
360 }
361 // select new font (if exists)
362 if (wParam) {
363 SelectObject (hdc, wParam);
364 GetTextMetricsA (hdc, &tm);
365 fh2 = tm.tmHeight;
366 }
367 // Erases top border line and (old) text background
368 GetClientRect(hwnd, &rc);
369 rc.bottom = rc.top + max( fh1, fh2) + 1;
370 HBRUSH hbr = GetControlBrush( hwnd, hdc, CTLCOLOR_STATIC );
371 FillRect(hdc, &rc, hbr);
372 ReleaseDC(hwnd,hdc);
373 }
374#endif
375
376 infoPtr->hFont = (HFONT)wParam;
377 if (lParam && (dwStyle & WS_VISIBLE)) PAINT_BUTTON(hwnd,dwStyle & 0x0f,ODA_DRAWENTIRE);
378
379 return 0;
380}
381
382static LRESULT BUTTON_GetFont(HWND hwnd,WPARAM wParam,LPARAM lParam)
383{
384 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
385
386 return infoPtr->hFont;
387}
388
389static LRESULT BUTTON_KeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
390{
391 if (wParam == VK_SPACE)
392 {
393 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
394
395 SendMessageA(hwnd,BM_SETSTATE,TRUE,0);
396 infoPtr->state |= BUTTON_BTNPRESSED;
397 }
398
399 return 0;
400}
401
402static LRESULT BUTTON_KeyUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
403{
404 if (wParam == VK_SPACE)
405 {
406 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
407 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
408
409 if (!(infoPtr->state & BUTTON_BTNPRESSED)) return 0;
410 infoPtr->state &= BUTTON_NSTATES;
411 if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) return 0;
412 SendMessageA(hwnd,BM_SETSTATE,FALSE,0);
413
414 switch(dwStyle & 0x0f)
415 {
416 case BS_AUTOCHECKBOX:
417 SendMessageA(hwnd,BM_SETCHECK,!(infoPtr->state & BUTTON_CHECKED),0);
418 break;
419 case BS_AUTORADIOBUTTON:
420 SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
421 break;
422 case BS_AUTO3STATE:
423 SendMessageA(hwnd,BM_SETCHECK,
424 (infoPtr->state & BUTTON_3STATE) ? 0 :
425 ((infoPtr->state & 3)+1),0);
426 break;
427 }
428 BUTTON_SendNotify(hwnd,BN_CLICKED);
429 }
430
431 return 0;
432}
433
434static LRESULT BUTTON_SysKeyUp(HWND hwnd,WPARAM wParam,LPARAM lParam)
435{
436 if (wParam != VK_TAB) ReleaseCapture();
437
438 return 0;
439}
440
441static LRESULT BUTTON_SetFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
442{
443 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
444 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
445 DWORD style = dwStyle & 0x0f;
446
447 if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_SETFOCUS);
448
449 if (((style == BS_AUTORADIOBUTTON) || (style == BS_RADIOBUTTON)) &&
450 (GetCapture() != hwnd) && !(SendMessageA(hwnd,BM_GETCHECK,0,0) & BST_CHECKED))
451 {
452 /* The notification is sent when the button (BS_AUTORADIOBUTTON)
453 is unckecked and the focus was not given by a mouse click. */
454 if (style == BS_AUTORADIOBUTTON) SendMessageA(hwnd,BM_SETCHECK,TRUE,0);
455 BUTTON_SendNotify(hwnd,BN_CLICKED);
456 }
457
458 infoPtr->state |= BUTTON_HASFOCUS;
459 PAINT_BUTTON(hwnd,style,ODA_FOCUS);
460
461 return 0;
462}
463
464static LRESULT BUTTON_KillFocus(HWND hwnd,WPARAM wParam,LPARAM lParam)
465{
466 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
467 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
468 DWORD style = dwStyle & 0x0f;
469
470 if (dwStyle & BS_NOTIFY) BUTTON_SendNotify(hwnd,BN_KILLFOCUS);
471
472 if (infoPtr->state & BUTTON_HASFOCUS)
473 {
474 infoPtr->state &= ~BUTTON_HASFOCUS;
475 PAINT_BUTTON(hwnd,style,ODA_FOCUS);
476 }
477
478 return 0;
479}
480
481static LRESULT BUTTON_SysColorChange(HWND hwnd,WPARAM wParam,LPARAM lParam)
482{
483 InvalidateRect(hwnd,NULL,FALSE);
484
485 return 0;
486}
487
488static LRESULT BUTTON_Click(HWND hwnd,WPARAM wParam,LPARAM lParam)
489{
490 RECT rect;
491 LPARAM point;
492
493 GetClientRect(hwnd,&rect);
494 point = MAKELPARAM(rect.right/2,rect.bottom/2);
495 SendMessageA(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,point);
496 Sleep(100);
497 SendMessageA(hwnd,WM_LBUTTONUP,0,point);
498
499 return 0;
500}
501
502static LRESULT BUTTON_SetStyle(HWND hwnd,WPARAM wParam,LPARAM lParam)
503{
504 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE),newStyle;
505
506 if ((wParam & 0x0F) >= MAX_BTN_TYPE) return 0;
507 newStyle = (dwStyle & 0xFFFFFFF0) | (wParam & 0x0000000F);
508
509 if (newStyle != dwStyle)
510 {
511 SetWindowLongA(hwnd,GWL_STYLE,newStyle);
512 PAINT_BUTTON(hwnd,newStyle & 0x0F,ODA_DRAWENTIRE);
513 }
514
515 return 0;
516}
517
518static LRESULT BUTTON_SetImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
519{
520 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
521 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
522 HANDLE oldHbitmap = infoPtr->hImage;
523
524 if ((dwStyle & BS_BITMAP) || (dwStyle & BS_ICON))
525 {
526 infoPtr->hImage = (HANDLE)lParam;
527 InvalidateRect(hwnd,NULL,FALSE);
528 }
529
530 return oldHbitmap;
531}
532
533static LRESULT BUTTON_GetImage(HWND hwnd,WPARAM wParam,LPARAM lParam)
534{
535 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
536
537 switch(wParam)
538 {
539 case IMAGE_BITMAP:
540 return (HBITMAP)infoPtr->hImage;
541 case IMAGE_ICON:
542 return (HICON)infoPtr->hImage;
543 default:
544 return (HICON)0;
545 }
546}
547
548static LRESULT BUTTON_GetCheck(HWND hwnd,WPARAM wParam,LPARAM lParam)
549{
550 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
551
552 return infoPtr->state & 3;
553}
554
555static LRESULT BUTTON_SetCheck(HWND hwnd,WPARAM wParam,LPARAM lParam)
556{
557 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
558 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
559 DWORD style = dwStyle & 0x0f;
560
561 if (wParam > maxCheckState[style]) wParam = maxCheckState[style];
562#ifndef __WIN32OS2__
563 //Must clear WS_TABSTOP of control that is already disabled or else
564 //multiple control can have this style ((auto)radiobutton) and
565 //GetNextDlgTabItem will return the wrong one
566 //Happens in Opera preferences dialog (multimedia) where all autoradio
567 //buttons have the WS_TABSTOP style.
568 if ((infoPtr->state & 3) != wParam)
569 {
570#endif
571 if ((style == BS_RADIOBUTTON) || (style == BS_AUTORADIOBUTTON))
572 {
573 DWORD oldStyle = dwStyle;
574
575 if (wParam)
576 dwStyle |= WS_TABSTOP;
577 else
578 dwStyle &= ~WS_TABSTOP;
579
580 if (oldStyle != dwStyle) SetWindowLongA(hwnd,GWL_STYLE,dwStyle);
581 }
582#ifdef __WIN32OS2__
583 if ((infoPtr->state & 3) != wParam)
584 {
585#endif
586 infoPtr->state = (infoPtr->state & ~3) | wParam;
587 PAINT_BUTTON(hwnd,style,ODA_SELECT);
588 }
589 if ((style == BS_AUTORADIOBUTTON) && (wParam == BUTTON_CHECKED))
590 BUTTON_CheckAutoRadioButton(hwnd);
591
592 return 0;
593}
594
595static LRESULT BUTTON_GetState(HWND hwnd,WPARAM wParam,LPARAM lParam)
596{
597 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
598
599 return infoPtr->state;
600}
601
602static LRESULT BUTTON_SetState(HWND hwnd,WPARAM wParam,LPARAM lParam)
603{
604 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
605 DWORD style = GetWindowLongA(hwnd,GWL_STYLE) & 0x0F;
606
607 if (wParam)
608 {
609 if (infoPtr->state & BUTTON_HIGHLIGHTED) return 0;
610 infoPtr->state |= BUTTON_HIGHLIGHTED;
611 } else
612 {
613 if (!(infoPtr->state & BUTTON_HIGHLIGHTED)) return 0;
614 infoPtr->state &= ~BUTTON_HIGHLIGHTED;
615 }
616 PAINT_BUTTON(hwnd,style,ODA_SELECT);
617
618 return 0;
619}
620
621/***********************************************************************
622 * ButtonWndProc
623 */
624static
625LRESULT WINAPI ButtonWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
626{
627// dprintf(("ButtonWndProc hwnd: %04x, msg %s, wp %08x lp %08lx\n",
628// hwnd, GetMsgText(uMsg), wParam, lParam));
629
630 switch (uMsg)
631 {
632 case WM_GETDLGCODE:
633 return BUTTON_GetDlgCode(hwnd,wParam,lParam);
634
635 case WM_ENABLE:
636 return BUTTON_Enable(hwnd,wParam,lParam);
637
638 case WM_CREATE:
639 return BUTTON_Create(hwnd,wParam,lParam);
640
641 case WM_DESTROY:
642 return BUTTON_Destroy(hwnd,wParam,lParam);
643
644 case WM_ERASEBKGND:
645 return BUTTON_EraseBkgnd(hwnd,wParam,lParam);
646
647 case WM_PAINT:
648 return BUTTON_Paint(hwnd,wParam,lParam);
649
650 case WM_LBUTTONDBLCLK:
651 return BUTTON_LButtonDblClk(hwnd,wParam,lParam);
652
653 case WM_LBUTTONDOWN:
654 return BUTTON_LButtonDown(hwnd,wParam,lParam);
655
656 case WM_LBUTTONUP:
657 return BUTTON_LButtonUp(hwnd,wParam,lParam);
658
659 case WM_CAPTURECHANGED:
660 return BUTTON_CaptureChanged(hwnd,wParam,lParam);
661
662 case WM_MOUSEMOVE:
663 return BUTTON_MouseMove(hwnd,wParam,lParam);
664
665 case WM_NCHITTEST:
666 return BUTTON_NCHitTest(hwnd,wParam,lParam);
667
668 case WM_SETTEXT:
669 return BUTTON_SetText(hwnd,wParam,lParam);
670
671 case WM_SETFONT:
672 return BUTTON_SetFont(hwnd,wParam,lParam);
673
674 case WM_GETFONT:
675 return BUTTON_GetFont(hwnd,wParam,lParam);
676
677 case WM_KEYDOWN:
678 return BUTTON_KeyDown(hwnd,wParam,lParam);
679
680 case WM_KEYUP:
681 return BUTTON_KeyUp(hwnd,wParam,lParam);
682
683 case WM_SYSKEYUP:
684 return BUTTON_SysKeyUp(hwnd,wParam,lParam);
685
686 case WM_SETFOCUS:
687 return BUTTON_SetFocus(hwnd,wParam,lParam);
688
689 case WM_KILLFOCUS:
690 return BUTTON_KillFocus(hwnd,wParam,lParam);
691
692 case WM_SYSCOLORCHANGE:
693 return BUTTON_SysColorChange(hwnd,wParam,lParam);
694
695 case BM_CLICK:
696 return BUTTON_Click(hwnd,wParam,lParam);
697
698 case BM_SETSTYLE:
699 return BUTTON_SetStyle(hwnd,wParam,lParam);
700
701 case BM_SETIMAGE:
702 return BUTTON_SetImage(hwnd,wParam,lParam);
703
704 case BM_GETIMAGE:
705 return BUTTON_GetImage(hwnd,wParam,lParam);
706
707 case BM_GETCHECK:
708 return BUTTON_GetCheck(hwnd,wParam,lParam);
709
710 case BM_SETCHECK:
711 return BUTTON_SetCheck(hwnd,wParam,lParam);
712
713 case BM_GETSTATE:
714 return BUTTON_GetState(hwnd,wParam,lParam);
715
716 case BM_SETSTATE:
717 return BUTTON_SetState(hwnd,wParam,lParam);
718
719 default:
720 return DefWindowProcA(hwnd,uMsg,wParam,lParam);
721 }
722
723 return 0;
724}
725
726
727/**********************************************************************
728 * Push Button Functions
729 */
730static void PB_Paint( HWND hwnd, HDC hDC, WORD action )
731{
732 BUTTONINFO *infoPtr = (BUTTONINFO *)GetInfoPtr(hwnd);
733 BOOL bHighLighted = (infoPtr->state & BUTTON_HIGHLIGHTED);
734
735 /*
736 * Delegate this to the more generic pushbutton painting
737 * method.
738 */
739 BUTTON_DrawPushButton(hwnd,
740 hDC,
741 action,
742 bHighLighted);
743}
744
745static INT BUTTON_GetTextFormat(DWORD dwStyle,DWORD dwExStyle,INT defHorz,INT defVert)
746{
747 INT format = 0;
748
749 if (dwStyle & BS_LEFT) format = DT_LEFT;
750 else if (dwStyle & BS_CENTER) format = DT_CENTER;
751 else if ((dwStyle & BS_RIGHT) || (dwExStyle & WS_EX_RIGHT)) format = DT_RIGHT;
752 else format = defHorz;
753
754 if (dwStyle & BS_TOP) format |= DT_TOP;
755 else if (dwStyle & BS_VCENTER) format |= DT_VCENTER;
756 else if (dwStyle & BS_BOTTOM) format |= DT_BOTTOM;
757 else format |= defVert;
758
759 if (!(dwStyle & BS_MULTILINE)) format |= DT_SINGLELINE;
760
761 return format;
762}
763
764/**********************************************************************
765 * This method will actually do the drawing of the pushbutton
766 * depending on it's state and the pushedState parameter.
767 */
768static void BUTTON_DrawPushButton(
769 HWND hwnd,
770 HDC hDC,
771 WORD action,
772 BOOL pushedState )
773{
774 RECT rc, focus_rect;
775 HPEN hOldPen;
776 HBRUSH hOldBrush;
777 BUTTONINFO *infoPtr = (BUTTONINFO *)GetInfoPtr(hwnd);
778 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
779 int xBorderOffset, yBorderOffset;
780 xBorderOffset = yBorderOffset = 0;
781 INT textLen;
782 char* text;
783
784 GetClientRect( hwnd, &rc );
785
786 /* Send WM_CTLCOLOR to allow changing the font (the colors are fixed) */
787 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
788 BUTTON_SEND_CTLCOLOR( hwnd, hDC );
789 hOldPen = (HPEN)SelectObject(hDC, GetSysColorPen(COLOR_WINDOWFRAME));
790 hOldBrush =(HBRUSH)SelectObject(hDC,GetSysColorBrush(COLOR_BTNFACE));
791 SetBkMode(hDC, TRANSPARENT);
792
793 if ((dwStyle & 0x000f) == BS_DEFPUSHBUTTON)
794 {
795 Rectangle(hDC, rc.left, rc.top, rc.right, rc.bottom);
796 InflateRect( &rc, -1, -1 );
797 }
798
799 UINT uState = DFCS_BUTTONPUSH;
800
801 if (pushedState)
802 {
803 if ( (dwStyle & 0x000f) == BS_DEFPUSHBUTTON )
804 uState |= DFCS_FLAT;
805 else
806 uState |= DFCS_PUSHED;
807 }
808
809 if (dwStyle & BS_FLAT) uState |= DFCS_FLAT;
810
811 DrawFrameControl( hDC, &rc, DFC_BUTTON, uState );
812 InflateRect( &rc, -2, -2 );
813
814 focus_rect = rc;
815
816 if (pushedState)
817 {
818 rc.left += 2; /* To position the text down and right */
819 rc.top += 2;
820 }
821
822
823 /* draw button label, if any:
824 *
825 * In win9x we don't show text if there is a bitmap or icon.
826 * I don't know about win31 so I leave it as it was for win31.
827 * Dennis Björklund 12 Jul, 99
828 */
829 textLen = GetWindowTextLengthA(hwnd);
830 if ((textLen > 0) && (!(dwStyle & (BS_ICON|BS_BITMAP))))
831 {
832 INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_CENTER,DT_VCENTER);
833
834 textLen++;
835 text = (char*)malloc(textLen);
836 GetWindowTextA(hwnd,text,textLen);
837
838 if (dwStyle & WS_DISABLED) DrawDisabledText(hDC,text,&rc,format); else
839 {
840 SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
841 DrawTextA(hDC,text,-1,&rc,format);
842 /* do we have the focus?
843 * Win9x draws focus last with a size prop. to the button
844 */
845 }
846 free(text);
847 }
848 if ( ((dwStyle & BS_ICON) || (dwStyle & BS_BITMAP) ) &&
849 (infoPtr->hImage != 0) )
850 {
851 int yOffset, xOffset;
852 int imageWidth, imageHeight;
853
854 /*
855 * We extract the size of the image from the handle.
856 */
857 if (dwStyle & BS_ICON)
858 {
859 ICONINFO iconInfo;
860 BITMAP bm;
861
862 GetIconInfo((HICON)infoPtr->hImage,&iconInfo);
863 if (iconInfo.hbmColor)
864 {
865 GetObjectA(iconInfo.hbmColor,sizeof(BITMAP),&bm);
866 imageWidth = bm.bmWidth;
867 imageHeight = bm.bmHeight;
868 } else
869 {
870 GetObjectA(iconInfo.hbmMask,sizeof(BITMAP),&bm);
871 imageWidth = bm.bmWidth;
872 imageHeight = bm.bmHeight/2;
873 }
874
875 if (iconInfo.hbmColor) DeleteObject(iconInfo.hbmColor);
876 if (iconInfo.hbmMask) DeleteObject(iconInfo.hbmMask);
877
878 }
879 else
880 {
881 BITMAP bm;
882
883 GetObjectA (infoPtr->hImage, sizeof(BITMAP), &bm);
884
885 imageWidth = bm.bmWidth;
886 imageHeight = bm.bmHeight;
887 }
888
889 /* Center the bitmap */
890 xOffset = (((rc.right - rc.left) - 2*xBorderOffset) - imageWidth ) / 2;
891 yOffset = (((rc.bottom - rc.top) - 2*yBorderOffset) - imageHeight) / 2;
892
893 /* If the image is too big for the button then create a region*/
894 if(xOffset < 0 || yOffset < 0)
895 {
896 HRGN hBitmapRgn = 0;
897 hBitmapRgn = CreateRectRgn(
898 rc.left + xBorderOffset, rc.top +yBorderOffset,
899 rc.right - xBorderOffset, rc.bottom - yBorderOffset);
900 SelectClipRgn(hDC, hBitmapRgn);
901 DeleteObject(hBitmapRgn);
902 }
903
904 /* Let minimum 1 space from border */
905 xOffset++, yOffset++;
906
907 /*
908 * Draw the image now.
909 */
910 if (dwStyle & BS_ICON)
911 {
912 DrawIcon(hDC,
913 rc.left + xOffset, rc.top + yOffset,
914 (HICON)infoPtr->hImage);
915 }
916 else
917 {
918 HDC hdcMem;
919
920 hdcMem = CreateCompatibleDC (hDC);
921 SelectObject (hdcMem, (HBITMAP)infoPtr->hImage);
922 BitBlt(hDC,
923 rc.left + xOffset,
924 rc.top + yOffset,
925 imageWidth, imageHeight,
926 hdcMem, 0, 0, SRCCOPY);
927
928 DeleteDC (hdcMem);
929 }
930
931 if(xOffset < 0 || yOffset < 0)
932 {
933 SelectClipRgn(hDC, 0);
934 }
935 }
936
937 SelectObject( hDC, hOldPen );
938 SelectObject( hDC, hOldBrush );
939
940 if ((infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd))
941 {
942 InflateRect( &focus_rect, -1, -1 );
943 DrawFocusRect( hDC, &focus_rect );
944 }
945}
946
947
948static void DrawDisabledText(HDC hdc,char* text,RECT* rtext,UINT format)
949{
950 COLORREF textColor = (GetSysColor(COLOR_GRAYTEXT) == GetBkColor(hdc)) ? COLOR_BTNTEXT:COLOR_GRAYTEXT;
951 RECT rect = *rtext;
952 COLORREF oldMode;
953
954 //CB: bug in Open32 DrawText: underscore is always black! -> two black lines!
955 SetTextColor(hdc,GetSysColor(COLOR_3DHILIGHT));
956 DrawTextA(hdc,text,-1,&rect,format);
957 SetTextColor(hdc,GetSysColor(COLOR_GRAYTEXT));
958 oldMode = SetBkMode(hdc,TRANSPARENT);
959 OffsetRect(&rect,-1,-1);
960 DrawTextA(hdc,text,-1,&rect,format);
961 SetBkMode(hdc,oldMode);
962}
963
964/**********************************************************************
965 * Check Box & Radio Button Functions
966 */
967
968static void CB_Paint(HWND hwnd,HDC hDC,WORD action)
969{
970 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
971 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
972 RECT rbox, rtext, client;
973 HBRUSH hBrush, hOldBrush;
974 HPEN hPen, hOldPen;
975 COLORREF colour;
976 int textLen, delta;
977 char* text = NULL;
978
979 /*
980 * if the button has a bitmap/icon, draw a normal pushbutton
981 * instead of a radion button.
982 */
983 if (infoPtr->hImage != 0)
984 {
985 BOOL bHighLighted = ((infoPtr->state & BUTTON_HIGHLIGHTED) ||
986 (infoPtr->state & BUTTON_CHECKED));
987
988 BUTTON_DrawPushButton(hwnd,
989 hDC,
990 action,
991 bHighLighted);
992 return;
993 }
994
995 textLen = 0;
996 GetClientRect(hwnd, &client);
997 rbox = rtext = client;
998
999 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
1000
1001 /* GetControlBrush16 sends WM_CTLCOLORBTN, plus it returns default brush
1002 * if parent didn't return valid one. So we kill two hares at once
1003 */
1004 hBrush = GetControlBrush( hwnd, hDC, CTLCOLOR_BTN );
1005
1006 /* In order to make things right, draw the rectangle background! */
1007 if ( !(infoPtr->state & BUTTON_HASFOCUS) && (action == ODA_DRAWENTIRE) )
1008 {
1009 colour = GetBkColor(hDC);
1010 hPen = CreatePen( PS_SOLID, 1, colour );
1011 if ( hPen )
1012 {
1013 hOldBrush = SelectObject( hDC, hBrush );
1014 hOldPen = SelectObject( hDC, hPen );
1015 Rectangle( hDC, client.left, client.top, client.right, client.bottom );
1016 SelectObject( hDC, hOldPen );
1017 SelectObject( hDC, hOldBrush );
1018 DeleteObject( hPen );
1019 }
1020 }
1021
1022 if (dwStyle & BS_LEFTTEXT)
1023 {
1024 /* magic +4 is what CTL3D expects */
1025
1026 rtext.right -= checkBoxWidth + 4;
1027 //CB: space for focus rect
1028 rtext.left++;
1029 rtext.right++;
1030 rbox.left = rbox.right - checkBoxWidth;
1031 }
1032 else
1033 {
1034 rtext.left += checkBoxWidth + 4;
1035 rbox.right = checkBoxWidth;
1036 }
1037
1038 /* Draw the check-box bitmap */
1039
1040 textLen = GetWindowTextLengthA(hwnd);
1041 if (textLen > 0)
1042 {
1043 textLen++;
1044 text = (char*)malloc(textLen);
1045 GetWindowTextA(hwnd,text,textLen);
1046 }
1047 if ((action == ODA_DRAWENTIRE) || (action == ODA_SELECT))
1048 {
1049 UINT state;
1050
1051 if (((dwStyle & 0x0f) == BS_RADIOBUTTON) ||
1052 ((dwStyle & 0x0f) == BS_AUTORADIOBUTTON)) state = DFCS_BUTTONRADIO;
1053 else if (infoPtr->state & BUTTON_3STATE) state = DFCS_BUTTON3STATE;
1054 else state = DFCS_BUTTONCHECK;
1055
1056 if (infoPtr->state & (BUTTON_CHECKED | BUTTON_3STATE)) state |= DFCS_CHECKED;
1057
1058 if (infoPtr->state & BUTTON_HIGHLIGHTED) state |= DFCS_PUSHED;
1059
1060 if (dwStyle & WS_DISABLED) state |= DFCS_INACTIVE;
1061
1062 if (dwStyle & BS_FLAT) state |= DFCS_FLAT;
1063
1064 DrawFrameControl( hDC, &rbox, DFC_BUTTON, state );
1065
1066 if( text && action != ODA_SELECT )
1067 {
1068 INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_TOP,DT_VCENTER);
1069
1070 if (dwStyle & WS_DISABLED) DrawDisabledText(hDC,text,&rtext,format);
1071 else DrawTextA(hDC,text,-1,&rtext,format);
1072 }
1073 }
1074
1075 if ((action == ODA_FOCUS) ||
1076 ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd)))
1077 {
1078 /* again, this is what CTL3D expects */
1079
1080 SetRectEmpty(&rbox);
1081 if(textLen > 0)
1082 DrawTextA(hDC,text,-1,&rbox,DT_SINGLELINE | DT_CALCRECT);
1083 textLen = rbox.bottom - rbox.top;
1084 delta = ((rtext.bottom - rtext.top) - textLen)/2;
1085 rbox.bottom = (rbox.top = rtext.top + delta - 1) + textLen + 2;
1086 textLen = rbox.right - rbox.left;
1087 rbox.right = (rbox.left += --rtext.left) + textLen + 2;
1088 IntersectRect(&rbox, &rbox, &rtext);
1089 DrawFocusRect( hDC, &rbox );
1090 }
1091 if (text) free(text);
1092}
1093
1094
1095/**********************************************************************
1096 * BUTTON_CheckAutoRadioButton
1097 *
1098 * wndPtr is checked, uncheck every other auto radio button in group
1099 */
1100static void BUTTON_CheckAutoRadioButton(HWND hwnd)
1101{
1102 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1103 HWND parent, sibling, start;
1104
1105 if (!(dwStyle & WS_CHILD)) return;
1106 parent = GetParent(hwnd);
1107 /* assure that starting control is not disabled or invisible */
1108 //start = sibling = GetNextDlgGroupItem( parent, hwnd, TRUE );
1109 //@YD: bugfix
1110 //CB: doesn't work!
1111 start = sibling = GetNextDlgGroupItem( parent, hwnd, FALSE );
1112 do
1113 {
1114 if (!sibling) break;
1115 if ((hwnd != sibling) &&
1116 ((GetWindowLongA(sibling,GWL_STYLE) & 0x0f) == BS_AUTORADIOBUTTON))
1117 SendMessageA( sibling, BM_SETCHECK, BUTTON_UNCHECKED, 0 );
1118 sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
1119 } while (sibling != start);
1120}
1121
1122
1123/**********************************************************************
1124 * Group Box Functions
1125 */
1126
1127static void GB_Paint(HWND hwnd,HDC hDC,WORD action)
1128{
1129 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1130 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1131 RECT rc, rcFrame;
1132 TEXTMETRICA tm;
1133 INT textLen;
1134 char* text;
1135 HBRUSH hbr;
1136
1137 if (action != ODA_DRAWENTIRE) return;
1138
1139 /* GroupBox acts like static control, so it sends CTLCOLORSTATIC */
1140 hbr = GetControlBrush( hwnd, hDC, CTLCOLOR_STATIC );
1141
1142 GetClientRect(hwnd,&rc);
1143
1144 rcFrame = rc;
1145
1146 if (infoPtr->hFont)
1147 SelectObject (hDC, infoPtr->hFont);
1148 GetTextMetricsA (hDC, &tm);
1149 rcFrame.top += (tm.tmHeight / 2) - 1;
1150 DrawEdge (hDC, &rcFrame, EDGE_ETCHED, BF_RECT);
1151
1152 textLen = GetWindowTextLengthA(hwnd);
1153 if (textLen > 0)
1154 {
1155 INT format = BUTTON_GetTextFormat(dwStyle,GetWindowLongA(hwnd,GWL_EXSTYLE),DT_LEFT,DT_TOP) | DT_NOCLIP | DT_SINGLELINE;
1156
1157 textLen++;
1158 text = (char*)malloc(textLen);
1159 GetWindowTextA(hwnd,text,textLen);
1160 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
1161 rc.left += 10;
1162
1163 if (dwStyle & WS_DISABLED) {
1164 DrawDisabledText(hDC,text,&rc,format);
1165 }
1166 else
1167 {
1168 SetTextColor(hDC,GetSysColor(COLOR_BTNTEXT));
1169 DrawTextA(hDC,text,-1,&rc,format);
1170 }
1171
1172 free(text);
1173 }
1174}
1175
1176
1177/**********************************************************************
1178 * User Button Functions
1179 */
1180
1181static void UB_Paint(HWND hwnd,HDC hDC,WORD action)
1182{
1183 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1184 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1185 RECT rc;
1186 HBRUSH hBrush;
1187 if (action == ODA_SELECT) return;
1188
1189 GetClientRect(hwnd,&rc);
1190
1191 if (infoPtr->hFont) SelectObject( hDC, infoPtr->hFont );
1192 hBrush = GetControlBrush( hwnd, hDC, CTLCOLOR_BTN );
1193
1194 FillRect( hDC, &rc, hBrush );
1195 if ((action == ODA_FOCUS) ||
1196 ((action == ODA_DRAWENTIRE) && (infoPtr->state & BUTTON_HASFOCUS) && IsWindowEnabled(hwnd)))
1197 {
1198 DrawFocusRect( hDC, &rc );
1199 InflateRect(&rc,-1,-1);
1200 }
1201}
1202
1203
1204/**********************************************************************
1205 * Ownerdrawn Button Functions
1206 */
1207
1208static void OB_Paint(HWND hwnd,HDC hDC,WORD action)
1209{
1210 BUTTONINFO* infoPtr = (BUTTONINFO*)GetInfoPtr(hwnd);
1211 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1212 DRAWITEMSTRUCT dis;
1213
1214 dis.CtlType = ODT_BUTTON;
1215 dis.CtlID = GetWindowLongA(hwnd,GWL_ID);
1216 dis.itemID = 0;
1217 dis.itemAction = action;
1218 dis.itemState = ((infoPtr->state & BUTTON_HASFOCUS) ? ODS_FOCUS : 0) |
1219 ((infoPtr->state & BUTTON_HIGHLIGHTED) ? ODS_SELECTED : 0) |
1220 ((dwStyle & WS_DISABLED) ? ODS_DISABLED : 0);
1221 dis.hwndItem = hwnd;
1222 dis.hDC = hDC;
1223 dis.itemData = 0;
1224 GetClientRect( hwnd, &dis.rcItem );
1225
1226 SetBkColor( hDC, GetSysColor( COLOR_BTNFACE ) );
1227
1228 dprintf(("OWNERDRAW button %x, enabled %d", hwnd, !(dwStyle & WS_DISABLED)));
1229 SendMessageA( GetParent(hwnd), WM_DRAWITEM,
1230 GetWindowLongA(hwnd,GWL_ID), (LPARAM)&dis );
1231}
1232
1233BOOL BUTTON_Register()
1234{
1235 WNDCLASSA wndClass;
1236
1237//SvL: Don't check this now
1238// if (GlobalFindAtomA(BUTTONCLASSNAME)) return FALSE;
1239
1240 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
1241 wndClass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC | CS_DBLCLKS;
1242 wndClass.lpfnWndProc = (WNDPROC)ButtonWndProc;
1243 wndClass.cbClsExtra = 0;
1244 wndClass.cbWndExtra = sizeof(BUTTONINFO);
1245 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);
1246 wndClass.hbrBackground = GetSysColorBrush(COLOR_BTNFACE);
1247 wndClass.lpszClassName = BUTTONCLASSNAME;
1248
1249 return RegisterClassA(&wndClass);
1250}
1251
1252BOOL BUTTON_Unregister()
1253{
1254 if (GlobalFindAtomA(BUTTONCLASSNAME))
1255 return UnregisterClassA(BUTTONCLASSNAME,(HINSTANCE)NULL);
1256 else return FALSE;
1257}
Note: See TracBrowser for help on using the repository browser.