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

Last change on this file since 3833 was 3662, checked in by sandervl, 25 years ago

Major rewrite: frame/client -> frame

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