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

Last change on this file since 6011 was 6011, checked in by sandervl, 24 years ago

button setcheck bugfix

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