source: trunk/src/comctl32/datetime.c@ 1036

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

wine-990731 update

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