source: trunk/src/comctl32/datetime.cpp@ 2875

Last change on this file since 2875 was 2875, checked in by cbratschi, 26 years ago

C -> C++, WINE animate, treeview WM_VSCROLL fixed

File size: 14.9 KB
Line 
1/* $Id: datetime.cpp,v 1.1 2000-02-23 17:09:41 cbratschi Exp $ */
2/*
3 * Date and time picker control
4 *
5 * Copyright 1998, 1999 Eric Kohl
6 * Copyright 1999 Alex Priem <alexp@sci.kun.nl>
7 * Copyright 1999 Achim Hasenmueller
8 * Copyright 1999 Christoph Bratschi
9 *
10 *
11 * TODO:
12 * - All messages.
13 * - All notifications.
14 *
15 */
16
17/* WINE 20000130 level */
18
19#include "winbase.h"
20#include "commctrl.h"
21#include "datetime.h"
22#include "monthcal.h"
23#include <string.h>
24#include <stdio.h>
25
26
27#define DATETIME_GetInfoPtr(hwnd) ((DATETIME_INFO *)GetWindowLongA (hwnd, 0))
28static BOOL
29
30DATETIME_SendSimpleNotify (HWND hwnd, UINT code);
31
32static char *days[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
33 "Thursday", "Friday", "Saturday", NULL};
34
35static char *monthtxt[] = {"January", "February", "March", "April", "May",
36 "June", "July", "August", "September", "October",
37 "November", "December"};
38
39static LRESULT
40DATETIME_GetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
41{
42 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
43 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
44 SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
45
46 if (!lParam) return GDT_NONE;
47
48 if ((dwStyle & DTS_SHOWNONE) &&
49 (SendMessageA (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0)))
50 return GDT_NONE;
51
52 MONTHCAL_CopyTime (&infoPtr->date, lprgSysTimeArray);
53
54 return GDT_VALID;
55}
56
57
58static LRESULT
59DATETIME_SetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
60{
61 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
62 SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
63
64 if (!lParam) return 0;
65
66 if (lParam==GDT_VALID)
67 MONTHCAL_CopyTime (lprgSysTimeArray, &infoPtr->date);
68 if (lParam==GDT_NONE) {
69 infoPtr->dateValid=FALSE;
70 SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 0, 0);
71 }
72 return 1;
73}
74
75
76static LRESULT
77DATETIME_GetMonthCalColor (HWND hwnd, WPARAM wParam)
78{
79 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
80
81 return SendMessageA (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);
82}
83
84static LRESULT
85DATETIME_SetMonthCalColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
86{
87 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
88
89 return SendMessageA (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);
90}
91
92
93/* FIXME: need to get way to force font into monthcal structure */
94
95static LRESULT
96DATETIME_GetMonthCal (HWND hwnd)
97{
98 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
99
100 return infoPtr->hMonthCal;
101}
102
103
104
105/* FIXME: need to get way to force font into monthcal structure */
106
107static LRESULT
108DATETIME_GetMonthCalFont (HWND hwnd)
109{
110
111 return 0;
112}
113
114static LRESULT
115DATETIME_SetMonthCalFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
116{
117
118 return 0;
119}
120
121
122static void DATETIME_Refresh (HWND hwnd, HDC hdc)
123
124{
125 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
126 RECT *daytxt = &infoPtr->daytxt;
127 RECT *daynumtxt= &infoPtr->daynumtxt;
128 RECT *rmonthtxt= &infoPtr->rmonthtxt;
129 RECT *yeartxt = &infoPtr->yeartxt;
130 RECT *calbutton= &infoPtr->calbutton;
131 RECT *checkbox = &infoPtr->checkbox;
132 RECT *rect = &infoPtr->rect;
133 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
134 SYSTEMTIME date = infoPtr->date;
135 SIZE size;
136 BOOL prssed=FALSE;
137 COLORREF oldBk = 0;
138
139
140
141 if (infoPtr->dateValid) {
142 char txt[80];
143 HFONT oldFont;
144 oldFont = SelectObject (hdc, infoPtr->hFont);
145
146 GetClientRect (hwnd, rect);
147
148 sprintf (txt,"%s,",days[date.wDayOfWeek]);
149 GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
150 rect->bottom=size.cy+2;
151
152 checkbox->left = 0;
153 checkbox->right = 0;
154 checkbox->top = rect->top;
155 checkbox->bottom= rect->bottom;
156 if (dwStyle & DTS_SHOWNONE) { /* FIXME: draw checkbox */
157 checkbox->right=18;
158 }
159
160
161 if (infoPtr->select==(DTHT_DAY|DTHT_GOTFOCUS))
162 oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
163 daytxt->left = checkbox->right;
164 daytxt->right = checkbox->right+size.cx;
165 daytxt->top = rect->top;
166 daytxt->bottom= rect->bottom;
167 DrawTextA ( hdc, txt, strlen(txt), daytxt,
168 DT_LEFT | DT_VCENTER | DT_SINGLELINE );
169 if (infoPtr->select==(DTHT_DAY|DTHT_GOTFOCUS))
170 SetBkColor (hdc, oldBk);
171
172 if (infoPtr->select==(DTHT_MONTH|DTHT_GOTFOCUS))
173 oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
174 strcpy (txt, monthtxt[date.wMonth]);
175 GetTextExtentPoint32A (hdc, "September", 9, &size);
176 rmonthtxt->left = daytxt->right;
177 rmonthtxt->right = daytxt->right+size.cx;
178 rmonthtxt->top = rect->top;
179 rmonthtxt->bottom= rect->bottom;
180 DrawTextA ( hdc, txt, strlen(txt), rmonthtxt,
181 DT_CENTER | DT_VCENTER | DT_SINGLELINE );
182 if (infoPtr->select==(DTHT_MONTH|DTHT_GOTFOCUS))
183 SetBkColor (hdc, oldBk);
184
185 if (infoPtr->select==(DTHT_DAYNUM|DTHT_GOTFOCUS))
186 oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
187 sprintf (txt,"%d,",date.wDay);
188 GetTextExtentPoint32A (hdc, "31,", 3, &size);
189 daynumtxt->left = rmonthtxt->right;
190 daynumtxt->right = rmonthtxt->right+size.cx;
191 daynumtxt->top = rect->top;
192 daynumtxt->bottom= rect->bottom;
193 DrawTextA ( hdc, txt, strlen(txt), daynumtxt,
194 DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
195 if (infoPtr->select==(DTHT_DAYNUM|DTHT_GOTFOCUS))
196 SetBkColor (hdc, oldBk);
197
198 if (infoPtr->select==(DTHT_YEAR|DTHT_GOTFOCUS))
199 oldBk=SetBkColor (hdc, COLOR_GRAYTEXT);
200 sprintf (txt,"%d",date.wYear);
201 GetTextExtentPoint32A (hdc, "2000", 5, &size);
202 yeartxt->left = daynumtxt->right;
203 yeartxt->right = daynumtxt->right+size.cx;
204 yeartxt->top = rect->top;
205 yeartxt->bottom= rect->bottom;
206 DrawTextA ( hdc, txt, strlen(txt), yeartxt,
207 DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
208 if (infoPtr->select==(DTHT_YEAR|DTHT_GOTFOCUS))
209 SetBkColor (hdc, oldBk);
210
211 SelectObject (hdc, oldFont);
212 }
213
214 if (!(dwStyle & DTS_UPDOWN)) {
215
216 calbutton->right = rect->right;
217 calbutton->left = rect->right-15;
218 calbutton->top = rect->top;
219 calbutton->bottom= rect->bottom;
220
221 DrawFrameControl(hdc, calbutton, DFC_SCROLL,
222 DFCS_SCROLLDOWN | (prssed ? DFCS_PUSHED : 0) |
223 (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
224 }
225
226}
227
228static LRESULT
229DATETIME_HitTest (HWND hwnd, DATETIME_INFO *infoPtr, POINT pt)
230{
231 //TRACE ("%ld, %ld\n",pt.x,pt.y);
232
233 if (PtInRect (&infoPtr->calbutton, pt)) return DTHT_MCPOPUP;
234 if (PtInRect (&infoPtr->yeartxt, pt)) return DTHT_YEAR;
235 if (PtInRect (&infoPtr->daynumtxt, pt)) return DTHT_DAYNUM;
236 if (PtInRect (&infoPtr->rmonthtxt, pt)) return DTHT_MONTH;
237 if (PtInRect (&infoPtr->daytxt, pt)) return DTHT_DAY;
238 if (PtInRect (&infoPtr->checkbox, pt)) return DTHT_CHECKBOX;
239
240 return 0;
241}
242
243static LRESULT
244DATETIME_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
245{
246 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
247 POINT pt;
248 int old;
249
250 //TRACE ("\n");
251
252 old=infoPtr->select;
253 pt.x=(INT)LOWORD(lParam);
254 pt.y=(INT)HIWORD(lParam);
255 infoPtr->select=DATETIME_HitTest (hwnd, infoPtr, pt);
256
257 if (infoPtr->select!=old) {
258 HDC hdc;
259
260 SetFocus (hwnd);
261 hdc=GetDC (hwnd);
262 DATETIME_Refresh (hwnd,hdc);
263 ReleaseDC (hwnd, hdc);
264 }
265 if (infoPtr->select==DTHT_MCPOPUP) {
266 POINT pt;
267
268 pt.x=8;
269 pt.y=infoPtr->rect.bottom+5;
270 ClientToScreen (hwnd, &pt);
271 infoPtr->hMonthCal=CreateWindowExA (0,"SysMonthCal32", 0,
272 WS_POPUP | WS_BORDER,
273 pt.x,pt.y,145,150,
274 GetParent (hwnd),
275 0,0,0);
276
277 //TRACE ("dt:%x mc:%x mc parent:%x, desktop:%x, mcpp:%x\n",
278 //hwnd,infoPtr->hMonthCal,
279 //GetParent (infoPtr->hMonthCal),
280 //GetDesktopWindow (),
281 //GetParent (GetParent (infoPtr->hMonthCal)));
282
283 SetFocus (hwnd);
284 DATETIME_SendSimpleNotify (hwnd, DTN_DROPDOWN);
285 }
286 return 0;
287}
288
289
290static LRESULT
291DATETIME_Paint (HWND hwnd, WPARAM wParam)
292{
293 HDC hdc;
294 PAINTSTRUCT ps;
295
296 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
297 DATETIME_Refresh (hwnd, hdc);
298 if(!wParam)
299 EndPaint (hwnd, &ps);
300 return 0;
301}
302
303static LRESULT
304DATETIME_ParentNotify (HWND hwnd, WPARAM wParam, LPARAM lParam)
305{
306 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
307 LPNMHDR lpnmh=(LPNMHDR) lParam;
308
309 //TRACE ("%x,%lx\n",wParam, lParam);
310 //TRACE ("Got notification %x from %x\n", lpnmh->code, lpnmh->hwndFrom);
311 //TRACE ("info: %x %x %x\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
312 return 0;
313}
314
315static LRESULT
316DATETIME_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
317
318{
319 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
320 LPNMHDR lpnmh=(LPNMHDR) lParam;
321
322 //TRACE ("%x,%lx\n",wParam, lParam);
323 //TRACE ("Got notification %x from %x\n", lpnmh->code, lpnmh->hwndFrom);
324 //TRACE ("info: %x %x %x\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
325 return 0;
326}
327
328static LRESULT
329DATETIME_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
330{
331 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
332 HDC hdc;
333
334 //TRACE ("\n");
335
336 if (infoPtr->select) {
337 DATETIME_SendSimpleNotify (hwnd, NM_KILLFOCUS);
338 infoPtr->select&= ~DTHT_GOTFOCUS;
339 }
340 hdc = GetDC (hwnd);
341 DATETIME_Refresh (hwnd, hdc);
342 ReleaseDC (hwnd, hdc);
343 InvalidateRect (hwnd, NULL, TRUE);
344
345 return 0;
346}
347
348
349static LRESULT
350DATETIME_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
351{
352 HDC hdc;
353 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
354
355 //TRACE ("\n");
356
357 if (infoPtr->select) {
358 DATETIME_SendSimpleNotify (hwnd, NM_SETFOCUS);
359 infoPtr->select|=DTHT_GOTFOCUS;
360 }
361 hdc = GetDC (hwnd);
362 DATETIME_Refresh (hwnd, hdc);
363 ReleaseDC (hwnd, hdc);
364
365 return 0;
366}
367
368
369static BOOL
370DATETIME_SendSimpleNotify (HWND hwnd, UINT code)
371{
372 NMHDR nmhdr;
373
374 //TRACE("%x\n",code);
375 nmhdr.hwndFrom = hwnd;
376 nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
377 nmhdr.code = code;
378
379 return (BOOL) SendMessageA (GetParent (hwnd), WM_NOTIFY,
380 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
381}
382
383
384
385
386
387
388static LRESULT
389DATETIME_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
390{
391 DATETIME_INFO *infoPtr;
392 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
393
394 /* allocate memory for info structure */
395 infoPtr = (DATETIME_INFO *)COMCTL32_Alloc (sizeof(DATETIME_INFO));
396 if (infoPtr == NULL) {
397 //ERR("could not allocate info memory!\n");
398 return 0;
399 }
400
401 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
402
403 if (dwStyle & DTS_SHOWNONE) {
404 infoPtr->hwndCheckbut=CreateWindowExA (0,"button", 0,
405 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
406 2,2,13,13,
407 hwnd,
408 0, GetWindowLongA (hwnd, GWL_HINSTANCE), 0);
409 SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0);
410 }
411
412 if (dwStyle & DTS_UPDOWN) {
413
414 infoPtr->hUpdown=CreateUpDownControl (
415 WS_CHILD | WS_BORDER | WS_VISIBLE,
416 120,1,20,20,
417 hwnd,1,0,0,
418 UD_MAXVAL, UD_MINVAL, 0);
419 }
420
421 /* initialize info structure */
422 infoPtr->hMonthCal=0;
423 GetSystemTime (&infoPtr->date);
424 infoPtr->dateValid = TRUE;
425 infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
426 return 0;
427}
428
429
430static LRESULT
431DATETIME_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
432{
433 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
434
435 COMCTL32_Free (infoPtr);
436 return 0;
437}
438
439
440
441
442
443static LRESULT WINAPI
444DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
445{
446
447 switch (uMsg)
448 {
449
450 case DTM_GETSYSTEMTIME:
451 DATETIME_GetSystemTime (hwnd, wParam, lParam);
452
453 case DTM_SETSYSTEMTIME:
454 DATETIME_SetSystemTime (hwnd, wParam, lParam);
455
456 case DTM_GETRANGE:
457 //FIXME("Unimplemented msg DTM_GETRANGE\n");
458 return 0;
459
460 case DTM_SETRANGE:
461 //FIXME("Unimplemented msg DTM_SETRANGE\n");
462 return 1;
463
464 case DTM_SETFORMATA:
465 //FIXME("Unimplemented msg DTM_SETFORMAT32A\n");
466 return 1;
467
468 case DTM_SETFORMATW:
469 //FIXME("Unimplemented msg DTM_SETFORMAT32W\n");
470 return 1;
471
472 case DTM_SETMCCOLOR:
473 return DATETIME_SetMonthCalColor (hwnd, wParam, lParam);
474
475 case DTM_GETMCCOLOR:
476 return DATETIME_GetMonthCalColor (hwnd, wParam);
477
478 case DTM_GETMONTHCAL:
479 return DATETIME_GetMonthCal (hwnd);
480
481 case DTM_SETMCFONT:
482 return DATETIME_SetMonthCalFont (hwnd, wParam, lParam);
483
484 case DTM_GETMCFONT:
485 return DATETIME_GetMonthCalFont (hwnd);
486
487 case WM_PARENTNOTIFY:
488 return DATETIME_ParentNotify (hwnd, wParam, lParam);
489
490 case WM_NOTIFY:
491 return DATETIME_Notify (hwnd, wParam, lParam);
492
493 case WM_PAINT:
494 return DATETIME_Paint (hwnd, wParam);
495
496 case WM_KILLFOCUS:
497 return DATETIME_KillFocus (hwnd, wParam, lParam);
498
499 case WM_SETFOCUS:
500 return DATETIME_SetFocus (hwnd, wParam, lParam);
501
502 case WM_LBUTTONDOWN:
503 return DATETIME_LButtonDown (hwnd, wParam, lParam);
504
505 case WM_CREATE:
506 return DATETIME_Create (hwnd, wParam, lParam);
507
508 case WM_DESTROY:
509 return DATETIME_Destroy (hwnd, wParam, lParam);
510
511 default:
512 //if (uMsg >= WM_USER)
513 //ERR("unknown msg %04x wp=%08x lp=%08lx\n",
514 // uMsg, wParam, lParam);
515 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
516 }
517 return 0;
518}
519
520
521VOID
522DATETIME_Register (void)
523{
524 WNDCLASSA wndClass;
525
526//SvL: Don't check this now
527// if (GlobalFindAtomA (DATETIMEPICK_CLASSA)) return;
528
529 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
530 wndClass.style = CS_GLOBALCLASS;
531 wndClass.lpfnWndProc = (WNDPROC)DATETIME_WindowProc;
532 wndClass.cbClsExtra = 0;
533 wndClass.cbWndExtra = sizeof(DATETIME_INFO *);
534 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
535 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
536 wndClass.lpszClassName = DATETIMEPICK_CLASSA;
537
538 RegisterClassA (&wndClass);
539}
540
541
542VOID
543DATETIME_Unregister (void)
544{
545 if (GlobalFindAtomA (DATETIMEPICK_CLASSA))
546 UnregisterClassA (DATETIMEPICK_CLASSA, (HINSTANCE)NULL);
547}
548
Note: See TracBrowser for help on using the repository browser.