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

Last change on this file since 6644 was 6644, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 34.4 KB
Line 
1/* $Id: datetime.c,v 1.18 2001-09-05 12:04:57 bird Exp $ */
2/*
3 * Date and time picker control
4 *
5 * Copyright 1998, 1999 Eric Kohl
6 * Copyright 1999, 2000 Alex Priem <alexp@sci.kun.nl>
7 * Copyright 2000 Chris Morgan <cmorgan@wpi.edu>
8 *
9 *
10 * TODO:
11 * - All messages.
12 * - All notifications.
13 *
14 */
15
16#include <math.h>
17#include <string.h>
18#include <stdio.h>
19
20#include "winbase.h"
21#include "wingdi.h"
22#include "commctrl.h"
23#include "debugtools.h"
24
25#ifdef __WIN32OS2__
26#include "ccbase.h"
27#define inline
28#endif
29
30DEFAULT_DEBUG_CHANNEL(datetime);
31
32typedef struct
33{
34#ifdef __WIN32OS2__
35 COMCTL32_HEADER header;
36#endif
37 HWND hMonthCal;
38 HWND hUpdown;
39 SYSTEMTIME date;
40 BOOL dateValid;
41 HWND hwndCheckbut;
42 RECT rcClient; /* rect around the edge of the window */
43 RECT rcDraw; /* rect inside of the border */
44 RECT checkbox; /* checkbox allowing the control to be enabled/disabled */
45 RECT calbutton; /* button that toggles the dropdown of the monthcal control */
46 BOOL bCalDepressed; /* TRUE = cal button is depressed */
47 int select;
48 HFONT hFont;
49 int nrFieldsAllocated;
50 int nrFields;
51 int haveFocus;
52 int *fieldspec;
53 RECT *fieldRect;
54 int *buflen;
55 char textbuf[256];
56 POINT monthcal_pos;
57} DATETIME_INFO, *LPDATETIME_INFO;
58
59/* in monthcal.c */
60extern int MONTHCAL_MonthLength(int month, int year);
61
62/* this list of defines is closely related to `allowedformatchars' defined
63 * in datetime.c; the high nibble indicates the `base type' of the format
64 * specifier.
65 * Do not change without first reading DATETIME_UseFormat.
66 *
67 */
68
69#define DT_END_FORMAT 0
70#define ONEDIGITDAY 0x01
71#define TWODIGITDAY 0x02
72#define THREECHARDAY 0x03
73#define FULLDAY 0x04
74#define ONEDIGIT12HOUR 0x11
75#define TWODIGIT12HOUR 0x12
76#define ONEDIGIT24HOUR 0x21
77#define TWODIGIT24HOUR 0x22
78#define ONEDIGITMINUTE 0x31
79#define TWODIGITMINUTE 0x32
80#define ONEDIGITMONTH 0x41
81#define TWODIGITMONTH 0x42
82#define THREECHARMONTH 0x43
83#define FULLMONTH 0x44
84#define ONEDIGITSECOND 0x51
85#define TWODIGITSECOND 0x52
86#define ONELETTERAMPM 0x61
87#define TWOLETTERAMPM 0x62
88#define ONEDIGITYEAR 0x71
89#define TWODIGITYEAR 0x72
90#ifdef __WIN32OS2__
91#define FULLYEAR 0x74
92#else
93#define FULLYEAR 0x73
94#endif
95#define FORMATCALLBACK 0x81 /* -> maximum of 0x80 callbacks possible */
96#define FORMATCALLMASK 0x80
97#define DT_STRING 0x0100
98
99#define DTHT_DATEFIELD 0xff /* for hit-testing */
100
101#define DTHT_NONE 0
102#define DTHT_CHECKBOX 0x200 /* these should end at '00' , to make */
103#define DTHT_MCPOPUP 0x300 /* & DTHT_DATEFIELD 0 when DATETIME_KeyDown */
104#define DTHT_GOTFOCUS 0x400 /* tests for date-fields */
105
106#define DATETIME_GetInfoPtr(hwnd) ((DATETIME_INFO *)GetWindowLongA (hwnd, 0))
107
108static BOOL DATETIME_SendSimpleNotify (HWND hwnd, UINT code);
109static BOOL DATETIME_SendDateTimeChangeNotify (HWND hwnd);
110extern void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to);
111static const char *allowedformatchars = {"dhHmMstyX'"};
112#ifdef __WIN32OS2__
113static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1,-1};
114//DT all wine xxx.nls contains yyyy for FULLYEAR
115#else
116static const int maxrepetition [] = {4,2,2,2,4,2,2,3,-1,-1};
117#endif
118
119static LRESULT
120DATETIME_GetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
121{
122 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
123 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
124 SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
125
126 TRACE("%04x %08lx\n",wParam,lParam);
127 if (!lParam) return GDT_NONE;
128
129 if ((dwStyle & DTS_SHOWNONE) &&
130 (SendMessageA (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0)))
131 return GDT_NONE;
132
133 MONTHCAL_CopyTime (&infoPtr->date, lprgSysTimeArray);
134
135 return GDT_VALID;
136}
137
138
139static LRESULT
140DATETIME_SetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
141{
142 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
143 SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
144
145 TRACE("%04x %08lx\n",wParam,lParam);
146 if (!lParam) return 0;
147
148 if (lParam==GDT_VALID)
149 MONTHCAL_CopyTime (lprgSysTimeArray, &infoPtr->date);
150 if (lParam==GDT_NONE) {
151 infoPtr->dateValid=FALSE;
152 SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 0, 0);
153 }
154 return 1;
155}
156
157static LRESULT
158DATETIME_GetRange (HWND hwnd, LPARAM lParam )
159{
160 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
161 LRESULT ret;
162
163 TRACE("%08lx\n", lParam);
164 ret = SendMessageA (infoPtr->hMonthCal, MCM_GETRANGE, 0, lParam);
165 if (!ret) ret = 1; /* bug emulation... */
166 return ret;
167}
168
169static LRESULT
170DATETIME_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam )
171{
172 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
173
174 TRACE("%04x %08lx\n",wParam,lParam);
175
176 return SendMessageA (infoPtr->hMonthCal, MCM_SETRANGE, wParam, lParam);
177}
178
179static LRESULT
180DATETIME_GetMonthCalColor (HWND hwnd, WPARAM wParam)
181{
182 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
183
184 TRACE("%04x\n",wParam);
185 return SendMessageA (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);
186}
187
188
189static LRESULT
190DATETIME_SetMonthCalColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
191{
192 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
193
194 TRACE("%04x %08lx\n",wParam,lParam);
195 return SendMessageA (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);
196}
197
198
199/* FIXME: need to get way to force font into monthcal structure */
200static LRESULT
201DATETIME_GetMonthCal (HWND hwnd)
202{
203 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
204
205 TRACE("\n");
206 return infoPtr->hMonthCal;
207}
208
209
210
211/* FIXME: need to get way to force font into monthcal structure */
212
213static LRESULT
214DATETIME_GetMonthCalFont (HWND hwnd)
215{
216
217 TRACE("\n");
218 return 0;
219}
220
221
222static LRESULT
223DATETIME_SetMonthCalFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
224{
225
226 TRACE("%04x %08lx\n",wParam,lParam);
227 return 0;
228}
229
230
231/*
232 Split up a formattxt in actions.
233 See ms documentation for the meaning of the letter codes/'specifiers'.
234
235 Notes:
236 *'dddddd' is handled as 'dddd' plus 'dd'.
237 *unrecognized formats are strings (here given the type DT_STRING;
238 start of the string is encoded in lower bits of DT_STRING.
239 Therefore, 'string' ends finally up as '<show seconds>tring'.
240
241 */
242
243
244static void
245DATETIME_UseFormat (DATETIME_INFO *infoPtr, const char *formattxt)
246{
247 int i,j,k,len;
248 int *nrFields=& infoPtr->nrFields;
249
250 TRACE ("%s\n",formattxt);
251
252
253 *nrFields=0;
254 infoPtr->fieldspec[*nrFields]=0;
255 len=strlen(allowedformatchars);
256 k=0;
257
258 for (i=0; i<strlen (formattxt); i++) {
259 TRACE ("\n%d %c:",i, formattxt[i]);
260 for (j=0; j<len; j++) {
261 if (allowedformatchars[j]==formattxt[i]) {
262 TRACE ("%c[%d,%x]",allowedformatchars[j], *nrFields,
263 infoPtr->fieldspec[*nrFields]);
264 if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
265 infoPtr->fieldspec[*nrFields]=(j<<4) +1;
266 break;
267 }
268 if (infoPtr->fieldspec[*nrFields]>>4!=j) {
269 (*nrFields)++;
270 infoPtr->fieldspec[*nrFields]=(j<<4) +1;
271 break;
272 }
273 if ((infoPtr->fieldspec[*nrFields] & 0x0f)==maxrepetition[j]) {
274 (*nrFields)++;
275 infoPtr->fieldspec[*nrFields]=(j<<4) +1;
276 break;
277 }
278 infoPtr->fieldspec[*nrFields]++;
279 break;
280 } /* if allowedformatchar */
281 } /* for j */
282
283
284 /* char is not a specifier: handle char like a string */
285 if (j==len) {
286 if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
287 infoPtr->fieldspec[*nrFields]=DT_STRING+k;
288 infoPtr->buflen[*nrFields]=0;
289 } else
290 if ((infoPtr->fieldspec[*nrFields] & DT_STRING)!=DT_STRING) {
291 (*nrFields)++;
292 infoPtr->fieldspec[*nrFields]=DT_STRING+k;
293 infoPtr->buflen[*nrFields]=0;
294 }
295 infoPtr->textbuf[k]=formattxt[i];
296 k++;
297 infoPtr->buflen[*nrFields]++;
298 } /* if j=len */
299
300 if (*nrFields==infoPtr->nrFieldsAllocated) {
301 FIXME ("out of memory; should reallocate. crash ahead.\n");
302 }
303
304 } /* for i */
305
306 TRACE("\n");
307
308 if (infoPtr->fieldspec[*nrFields]!=0) (*nrFields)++;
309}
310
311
312static LRESULT
313DATETIME_SetFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
314{
315 DATETIME_INFO *infoPtr= DATETIME_GetInfoPtr (hwnd);
316 char format_buf[80];
317 DWORD format_item;
318
319 TRACE("%04x %08lx\n",wParam,lParam);
320 if (!lParam) {
321 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
322
323 if (dwStyle & DTS_LONGDATEFORMAT)
324 format_item=LOCALE_SLONGDATE;
325 else if (dwStyle & DTS_TIMEFORMAT)
326 format_item=LOCALE_STIMEFORMAT;
327 else /* DTS_SHORTDATEFORMAT */
328 format_item=LOCALE_SSHORTDATE;
329 GetLocaleInfoA( GetSystemDefaultLCID(), format_item,format_buf,sizeof(format_buf));
330 DATETIME_UseFormat (infoPtr, format_buf);
331 }
332 else
333 DATETIME_UseFormat (infoPtr, (char *) lParam);
334
335 return infoPtr->nrFields;
336}
337
338
339static LRESULT
340DATETIME_SetFormatW (HWND hwnd, WPARAM wParam, LPARAM lParam)
341
342{
343 TRACE("%04x %08lx\n",wParam,lParam);
344 if (lParam) {
345 LPSTR buf;
346 int retval;
347 int len = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, NULL, 0, NULL, NULL );
348
349 buf = (LPSTR) COMCTL32_Alloc (len);
350 WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, buf, len, NULL, NULL );
351 retval=DATETIME_SetFormat (hwnd, 0, (LPARAM) buf);
352 COMCTL32_Free (buf);
353 return retval;
354 }
355 else
356 return DATETIME_SetFormat (hwnd, 0, 0);
357
358}
359
360
361static void
362DATETIME_ReturnTxt (DATETIME_INFO *infoPtr, int count, char *result)
363{
364 SYSTEMTIME date = infoPtr->date;
365 int spec;
366 char buffer[80];
367
368 *result=0;
369 TRACE ("%d,%d\n", infoPtr->nrFields, count);
370 if ((count>infoPtr->nrFields) || (count<0)) {
371 WARN ("buffer overrun, have %d want %d\n", infoPtr->nrFields, count);
372 return;
373 }
374
375 if (!infoPtr->fieldspec) return;
376
377 spec=infoPtr->fieldspec[count];
378 if (spec & DT_STRING) {
379 int txtlen=infoPtr->buflen[count];
380
381 strncpy (result, infoPtr->textbuf + (spec &~ DT_STRING), txtlen);
382 result[txtlen]=0;
383 TRACE ("arg%d=%x->[%s]\n",count,infoPtr->fieldspec[count],result);
384 return;
385 }
386
387
388 switch (spec) {
389 case DT_END_FORMAT:
390 *result=0;
391 break;
392 case ONEDIGITDAY:
393 sprintf (result,"%d",date.wDay);
394 break;
395 case TWODIGITDAY:
396 sprintf (result,"%.2d",date.wDay);
397 break;
398 case THREECHARDAY:
399 GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1+(date.wDayOfWeek+6)%7,
400 result,4);
401 /*sprintf (result,"%.3s",days[date.wDayOfWeek]);*/
402 break;
403 case FULLDAY:
404 GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SDAYNAME1+ (date.wDayOfWeek+6)%7,
405 buffer,sizeof(buffer));
406 strcpy (result,buffer);
407 break;
408 case ONEDIGIT12HOUR:
409 if (date.wHour>12)
410 sprintf (result,"%d",date.wHour-12);
411 else
412 sprintf (result,"%d",date.wHour);
413 break;
414 case TWODIGIT12HOUR:
415 if (date.wHour>12)
416 sprintf (result,"%.2d",date.wHour-12);
417 else
418 sprintf (result,"%.2d",date.wHour);
419 break;
420 case ONEDIGIT24HOUR:
421 sprintf (result,"%d",date.wHour);
422 break;
423 case TWODIGIT24HOUR:
424 sprintf (result,"%.2d",date.wHour);
425 break;
426 case ONEDIGITSECOND:
427 sprintf (result,"%d",date.wSecond);
428 break;
429 case TWODIGITSECOND:
430 sprintf (result,"%.2d",date.wSecond);
431 break;
432 case ONEDIGITMINUTE:
433 sprintf (result,"%d",date.wMinute);
434 break;
435 case TWODIGITMINUTE:
436 sprintf (result,"%.2d",date.wMinute);
437 break;
438 case ONEDIGITMONTH:
439 sprintf (result,"%d",date.wMonth);
440 break;
441 case TWODIGITMONTH:
442 sprintf (result,"%.2d",date.wMonth);
443 break;
444 case THREECHARMONTH:
445 GetLocaleInfoA( GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1,
446 buffer,sizeof(buffer));
447 sprintf (result,"%.3s",buffer);
448 break;
449 case FULLMONTH:
450 GetLocaleInfoA( GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1,
451#ifdef __WIN32OS2__
452 buffer,sizeof(buffer));
453 strcpy (result,buffer);
454#else
455 result,sizeof(result));
456#endif
457 break;
458 case ONELETTERAMPM:
459 if (date.wHour<12)
460 strcpy (result,"A");
461 else
462 strcpy (result,"P");
463 break;
464 case TWOLETTERAMPM:
465 if (date.wHour<12)
466 strcpy (result,"AM");
467 else
468 strcpy (result,"PM");
469 break;
470 case FORMATCALLBACK:
471 FIXME ("Not implemented\n");
472 strcpy (result,"xxx");
473 break;
474 case ONEDIGITYEAR:
475 sprintf (result,"%d",date.wYear-10* (int) floor(date.wYear/10));
476 break;
477 case TWODIGITYEAR:
478 sprintf (result,"%.2d",date.wYear-100* (int) floor(date.wYear/100));
479 break;
480 case FULLYEAR:
481 sprintf (result,"%d",date.wYear);
482 break;
483 }
484
485 TRACE ("arg%d=%x->[%s]\n",count,infoPtr->fieldspec[count],result);
486}
487
488
489static void
490DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number)
491{
492 SYSTEMTIME *date = &infoPtr->date;
493 int spec;
494
495 TRACE ("%d\n",number);
496 if ((number>infoPtr->nrFields) || (number<0)) return;
497
498 spec=infoPtr->fieldspec[number];
499 if ((spec & DTHT_DATEFIELD)==0) return;
500
501 switch (spec) {
502 case ONEDIGITDAY:
503 case TWODIGITDAY:
504 case THREECHARDAY:
505 case FULLDAY:
506 date->wDay++;
507 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear))
508 date->wDay=1;
509 break;
510 case ONEDIGIT12HOUR:
511 case TWODIGIT12HOUR:
512 case ONEDIGIT24HOUR:
513 case TWODIGIT24HOUR:
514 date->wHour++;
515 if (date->wHour>23) date->wHour=0;
516 break;
517 case ONEDIGITSECOND:
518 case TWODIGITSECOND:
519 date->wSecond++;
520 if (date->wSecond>59) date->wSecond=0;
521 break;
522 case ONEDIGITMINUTE:
523 case TWODIGITMINUTE:
524 date->wMinute++;
525 if (date->wMinute>59) date->wMinute=0;
526 break;
527 case ONEDIGITMONTH:
528 case TWODIGITMONTH:
529 case THREECHARMONTH:
530 case FULLMONTH:
531 date->wMonth++;
532 if (date->wMonth>12) date->wMonth=1;
533 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear))
534 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear);
535 break;
536 case ONELETTERAMPM:
537 case TWOLETTERAMPM:
538 date->wHour+=12;
539 if (date->wHour>23) date->wHour-=24;
540 break;
541 case FORMATCALLBACK:
542 FIXME ("Not implemented\n");
543 break;
544 case ONEDIGITYEAR:
545 case TWODIGITYEAR:
546 case FULLYEAR:
547 date->wYear++;
548 break;
549 }
550
551}
552
553
554static void
555DATETIME_DecreaseField (DATETIME_INFO *infoPtr, int number)
556{
557 SYSTEMTIME *date = & infoPtr->date;
558 int spec;
559
560 TRACE ("%d\n",number);
561 if ((number>infoPtr->nrFields) || (number<0)) return;
562
563 spec = infoPtr->fieldspec[number];
564 if ((spec & DTHT_DATEFIELD)==0) return;
565
566 TRACE ("%x\n",spec);
567
568 switch (spec) {
569 case ONEDIGITDAY:
570 case TWODIGITDAY:
571 case THREECHARDAY:
572 case FULLDAY:
573 date->wDay--;
574 if (date->wDay<1)
575 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear);
576 break;
577 case ONEDIGIT12HOUR:
578 case TWODIGIT12HOUR:
579 case ONEDIGIT24HOUR:
580 case TWODIGIT24HOUR:
581 if (date->wHour)
582 date->wHour--;
583 else
584 date->wHour=23;
585 break;
586 case ONEDIGITSECOND:
587 case TWODIGITSECOND:
588 if (date->wHour)
589 date->wSecond--;
590 else
591 date->wHour=59;
592 break;
593 case ONEDIGITMINUTE:
594 case TWODIGITMINUTE:
595 if (date->wMinute)
596 date->wMinute--;
597 else
598 date->wMinute=59;
599 break;
600 case ONEDIGITMONTH:
601 case TWODIGITMONTH:
602 case THREECHARMONTH:
603 case FULLMONTH:
604 if (date->wMonth>1)
605 date->wMonth--;
606 else
607 date->wMonth=12;
608 if (date->wDay>MONTHCAL_MonthLength(date->wMonth,date->wYear))
609 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear);
610 break;
611 case ONELETTERAMPM:
612 case TWOLETTERAMPM:
613 if (date->wHour<12)
614 date->wHour+=12;
615 else
616 date->wHour-=12;
617 break;
618 case FORMATCALLBACK:
619 FIXME ("Not implemented\n");
620 break;
621 case ONEDIGITYEAR:
622 case TWODIGITYEAR:
623 case FULLYEAR:
624 date->wYear--;
625 break;
626 }
627
628}
629
630
631static void
632DATETIME_ResetFieldDown (DATETIME_INFO *infoPtr, int number)
633{
634 SYSTEMTIME *date = &infoPtr->date;
635 int spec;
636
637 TRACE ("%d\n",number);
638 if ((number>infoPtr->nrFields) || (number<0)) return;
639
640 spec = infoPtr->fieldspec[number];
641 if ((spec & DTHT_DATEFIELD)==0) return;
642
643
644 switch (spec) {
645 case ONEDIGITDAY:
646 case TWODIGITDAY:
647 case THREECHARDAY:
648 case FULLDAY:
649 date->wDay = 1;
650 break;
651 case ONEDIGIT12HOUR:
652 case TWODIGIT12HOUR:
653 case ONEDIGIT24HOUR:
654 case TWODIGIT24HOUR:
655 case ONELETTERAMPM:
656 case TWOLETTERAMPM:
657 date->wHour = 0;
658 break;
659 case ONEDIGITSECOND:
660 case TWODIGITSECOND:
661 date->wSecond = 0;
662 break;
663 case ONEDIGITMINUTE:
664 case TWODIGITMINUTE:
665 date->wMinute = 0;
666 break;
667 case ONEDIGITMONTH:
668 case TWODIGITMONTH:
669 case THREECHARMONTH:
670 case FULLMONTH:
671 date->wMonth = 1;
672 case FORMATCALLBACK:
673 FIXME ("Not implemented\n");
674 break;
675 case ONEDIGITYEAR:
676 case TWODIGITYEAR:
677 /* FYI: On 9/14/1752 the calender changed and England and the American */
678 /* colonies changed to the Gregorian calender. This change involved */
679 /* having September 14th following September 2nd. So no date algorithms */
680 /* work before that date. */
681 case FULLYEAR:
682 date->wSecond = 0;
683 date->wMinute = 0;
684 date->wHour = 0;
685 date->wDay = 14; /* overactive ms-programmers..*/
686 date->wMonth = 9;
687 date->wYear = 1752;
688 break;
689 }
690
691}
692
693
694static void
695DATETIME_ResetFieldUp (DATETIME_INFO *infoPtr, int number)
696{
697 SYSTEMTIME *date = & infoPtr->date;
698 int spec;
699
700 TRACE("%d \n",number);
701 if ((number>infoPtr->nrFields) || (number<0)) return;
702
703 spec=infoPtr->fieldspec[number];
704 if ((spec & DTHT_DATEFIELD)==0) return;
705
706 switch (spec) {
707 case ONEDIGITDAY:
708 case TWODIGITDAY:
709 case THREECHARDAY:
710 case FULLDAY:
711 date->wDay=MONTHCAL_MonthLength(date->wMonth,date->wYear);
712 break;
713 case ONEDIGIT12HOUR:
714 case TWODIGIT12HOUR:
715 case ONEDIGIT24HOUR:
716 case TWODIGIT24HOUR:
717 case ONELETTERAMPM:
718 case TWOLETTERAMPM:
719 date->wHour=23;
720 break;
721 case ONEDIGITSECOND:
722 case TWODIGITSECOND:
723 date->wSecond=59;
724 break;
725 case ONEDIGITMINUTE:
726 case TWODIGITMINUTE:
727 date->wMinute=59;
728 break;
729 case ONEDIGITMONTH:
730 case TWODIGITMONTH:
731 case THREECHARMONTH:
732 case FULLMONTH:
733 date->wMonth=12;
734 case FORMATCALLBACK:
735 FIXME ("Not implemented\n");
736 break;
737 case ONEDIGITYEAR:
738 case TWODIGITYEAR:
739 case FULLYEAR:
740 date->wYear=9999; /* Y10K problem? naaah. */
741 break;
742 }
743
744}
745
746
747static void DATETIME_Refresh (HWND hwnd, HDC hdc)
748
749{
750 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
751 int i,prevright;
752 RECT *field;
753 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
754 RECT *rcDraw = &infoPtr->rcDraw;
755 RECT *rcClient = &infoPtr->rcClient;
756 RECT *calbutton = &infoPtr->calbutton;
757 RECT *checkbox = &infoPtr->checkbox;
758 HBRUSH hbr;
759 SIZE size;
760 COLORREF oldBk, oldTextColor;
761
762 /* draw control edge */
763 TRACE("\n");
764 hbr = CreateSolidBrush(RGB(255, 255, 255));
765 FillRect(hdc, rcClient, hbr);
766 DrawEdge(hdc, rcClient, EDGE_SUNKEN, BF_RECT);
767 DeleteObject(hbr);
768
769 if (infoPtr->dateValid) {
770 char txt[80];
771 HFONT oldFont;
772 oldFont = SelectObject (hdc, infoPtr->hFont);
773
774 DATETIME_ReturnTxt (infoPtr, 0, txt);
775 GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
776 rcDraw->bottom = size.cy+2;
777
778 if (dwStyle & DTS_SHOWNONE) checkbox->right = 18;
779
780 prevright = checkbox->right;
781
782 for (i=0; i<infoPtr->nrFields; i++) {
783 DATETIME_ReturnTxt (infoPtr, i, txt);
784 GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
785 field = & infoPtr->fieldRect[i];
786 field->left = prevright;
787 field->right = prevright+size.cx;
788 field->top = rcDraw->top;
789 field->bottom = rcDraw->bottom;
790 prevright = field->right;
791
792 if ((infoPtr->haveFocus) && (i==infoPtr->select)) {
793 hbr = CreateSolidBrush (GetSysColor (COLOR_ACTIVECAPTION));
794 FillRect(hdc, field, hbr);
795 oldBk = SetBkColor (hdc, GetSysColor(COLOR_ACTIVECAPTION));
796 oldTextColor = SetTextColor (hdc, GetSysColor(COLOR_WINDOW));
797 DeleteObject (hbr);
798 DrawTextA ( hdc, txt, strlen(txt), field,
799 DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
800 SetBkColor (hdc, oldBk);
801 SetTextColor (hdc, oldTextColor);
802 }
803 else
804 DrawTextA ( hdc, txt, strlen(txt), field,
805 DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
806 }
807
808 SelectObject (hdc, oldFont);
809 }
810
811 if (!(dwStyle & DTS_UPDOWN)) {
812 DrawFrameControl(hdc, calbutton, DFC_SCROLL,
813 DFCS_SCROLLDOWN | (infoPtr->bCalDepressed ? DFCS_PUSHED : 0) |
814 (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
815 }
816}
817
818
819static LRESULT
820DATETIME_HitTest (HWND hwnd, DATETIME_INFO *infoPtr, POINT pt)
821{
822 int i, retval;
823
824 TRACE ("%ld, %ld\n",pt.x,pt.y);
825
826 retval = DTHT_NONE;
827 if (PtInRect (&infoPtr->calbutton, pt))
828 {retval = DTHT_MCPOPUP; TRACE("Hit in calbutton(DTHT_MCPOPUP)\n"); goto done; }
829 if (PtInRect (&infoPtr->checkbox, pt))
830 {retval = DTHT_CHECKBOX; TRACE("Hit in checkbox(DTHT_CHECKBOX)\n"); goto done; }
831
832 for (i=0; i<infoPtr->nrFields; i++) {
833 if (PtInRect (&infoPtr->fieldRect[i], pt)) {
834 retval = i;
835 TRACE("Hit in date text in field %d\n", i);
836 break;
837 }
838 }
839
840done:
841 return retval;
842}
843
844
845static LRESULT
846DATETIME_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
847{
848 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
849 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
850 int old, new;
851 POINT pt;
852
853 TRACE ("\n");
854
855 old = infoPtr->select;
856 pt.x = (INT)LOWORD(lParam);
857 pt.y = (INT)HIWORD(lParam);
858
859 new = DATETIME_HitTest (hwnd, infoPtr, pt);
860
861 /* FIXME: might be conditions where we don't want to update infoPtr->select */
862 infoPtr->select = new;
863
864 if (infoPtr->select != old) {
865 infoPtr->haveFocus = DTHT_GOTFOCUS;
866 }
867
868 if (infoPtr->select == DTHT_MCPOPUP) {
869 /* FIXME: button actually is only depressed during dropdown of the */
870 /* calender control and when the mouse is over the button window */
871 infoPtr->bCalDepressed = TRUE;
872
873 /* recalculate the position of the monthcal popup */
874 if(dwStyle & DTS_RIGHTALIGN)
875 infoPtr->monthcal_pos.x = infoPtr->rcClient.right - ((infoPtr->calbutton.right -
876 infoPtr->calbutton.left) + 145);
877 else
878 infoPtr->monthcal_pos.x = 8;
879
880 infoPtr->monthcal_pos.y = infoPtr->rcClient.bottom;
881 ClientToScreen (hwnd, &(infoPtr->monthcal_pos));
882 SetWindowPos(infoPtr->hMonthCal, 0, infoPtr->monthcal_pos.x,
883 infoPtr->monthcal_pos.y, 145, 150, 0);
884
885 if(IsWindowVisible(infoPtr->hMonthCal))
886 ShowWindow(infoPtr->hMonthCal, SW_HIDE);
887 else
888 ShowWindow(infoPtr->hMonthCal, SW_SHOW);
889
890 TRACE ("dt:%x mc:%x mc parent:%x, desktop:%x, mcpp:%x\n",
891 hwnd,infoPtr->hMonthCal,
892 GetParent (infoPtr->hMonthCal),
893 GetDesktopWindow (),
894 GetParent (GetParent (infoPtr->hMonthCal)));
895 DATETIME_SendSimpleNotify (hwnd, DTN_DROPDOWN);
896 }
897
898 InvalidateRect(hwnd, NULL, FALSE);
899
900 return 0;
901}
902
903
904static LRESULT
905DATETIME_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
906{
907 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
908
909 TRACE("\n");
910
911 if(infoPtr->bCalDepressed == TRUE) {
912 infoPtr->bCalDepressed = FALSE;
913 InvalidateRect(hwnd, &(infoPtr->calbutton), TRUE);
914 }
915
916 return 0;
917}
918
919
920static LRESULT
921DATETIME_Paint (HWND hwnd, WPARAM wParam)
922{
923 HDC hdc;
924 PAINTSTRUCT ps;
925
926 hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
927 DATETIME_Refresh (hwnd, hdc);
928 if(!wParam)
929 EndPaint (hwnd, &ps);
930 return 0;
931}
932
933
934static LRESULT
935DATETIME_ParentNotify (HWND hwnd, WPARAM wParam, LPARAM lParam)
936{
937 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
938 LPNMHDR lpnmh = (LPNMHDR) lParam;
939
940#ifdef __WIN32OS2__
941//DT: if lParam a pointer or a handle
942// if the index forgotten or is it zero
943 TRACE ("DATETIME_ParentNotify %x,%lx\n",wParam, lParam);
944#else
945 TRACE ("%x,%lx\n",wParam, lParam);
946 TRACE ("Got notification %x from %x\n", lpnmh->code, lpnmh->hwndFrom);
947#endif
948 TRACE ("info: %x %x %x\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
949 return 0;
950}
951
952
953static LRESULT
954DATETIME_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
955
956{
957 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
958 LPNMHDR lpnmh = (LPNMHDR) lParam;
959
960 TRACE ("%x,%lx\n",wParam, lParam);
961 TRACE ("Got notification %x from %x\n", lpnmh->code, lpnmh->hwndFrom);
962 TRACE ("info: %x %x %x\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
963 return 0;
964}
965
966
967static LRESULT
968DATETIME_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
969{
970 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
971 int FieldNum,wrap=0;
972
973 TRACE("%x %lx %x\n",wParam, lParam, infoPtr->select);
974
975 FieldNum = infoPtr->select & DTHT_DATEFIELD;
976
977 if (!(infoPtr->haveFocus)) return 0;
978 if ((FieldNum==0) && (infoPtr->select)) return 0;
979
980 if (infoPtr->select & FORMATCALLMASK) {
981 FIXME ("Callbacks not implemented yet\n");
982 }
983
984 switch (wParam) {
985 case VK_ADD:
986 case VK_UP:
987 DATETIME_IncreaseField (infoPtr,FieldNum);
988 DATETIME_SendDateTimeChangeNotify (hwnd);
989 break;
990 case VK_SUBTRACT:
991 case VK_DOWN:
992 DATETIME_DecreaseField (infoPtr,FieldNum);
993 DATETIME_SendDateTimeChangeNotify (hwnd);
994 break;
995 case VK_HOME:
996 DATETIME_ResetFieldDown (infoPtr,FieldNum);
997 DATETIME_SendDateTimeChangeNotify (hwnd);
998 break;
999 case VK_END:
1000 DATETIME_ResetFieldUp(infoPtr,FieldNum);
1001 DATETIME_SendDateTimeChangeNotify (hwnd);
1002 break;
1003 case VK_LEFT:
1004 do {
1005 if (infoPtr->select==0) {
1006 infoPtr->select = infoPtr->nrFields - 1;
1007 wrap++;
1008 } else
1009 infoPtr->select--;
1010 }
1011 while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2));
1012 break;
1013 case VK_RIGHT:
1014 do {
1015 infoPtr->select++;
1016 if (infoPtr->select==infoPtr->nrFields) {
1017 infoPtr->select = 0;
1018 wrap++;
1019 }
1020 }
1021 while ((infoPtr->fieldspec[infoPtr->select] & DT_STRING) && (wrap<2));
1022 break;
1023 }
1024
1025 InvalidateRect(hwnd, NULL, FALSE);
1026
1027 return 0;
1028}
1029
1030
1031static LRESULT
1032DATETIME_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1033{
1034 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
1035
1036 TRACE ("\n");
1037
1038 if (infoPtr->haveFocus) {
1039 DATETIME_SendSimpleNotify (hwnd, NM_KILLFOCUS);
1040 infoPtr->haveFocus = 0;
1041 }
1042
1043 InvalidateRect (hwnd, NULL, TRUE);
1044
1045 return 0;
1046}
1047
1048
1049static LRESULT
1050DATETIME_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
1051{
1052 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
1053
1054 TRACE ("\n");
1055
1056 if (infoPtr->haveFocus==0) {
1057 DATETIME_SendSimpleNotify (hwnd, NM_SETFOCUS);
1058 infoPtr->haveFocus = DTHT_GOTFOCUS;
1059 }
1060
1061 InvalidateRect(hwnd, NULL, FALSE);
1062
1063 return 0;
1064}
1065
1066
1067static BOOL
1068DATETIME_SendDateTimeChangeNotify (HWND hwnd)
1069
1070{
1071 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
1072 NMDATETIMECHANGE dtdtc;
1073
1074 TRACE ("\n");
1075 dtdtc.nmhdr.hwndFrom = hwnd;
1076 dtdtc.nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
1077 dtdtc.nmhdr.code = DTN_DATETIMECHANGE;
1078
1079 if ((GetWindowLongA (hwnd, GWL_STYLE) & DTS_SHOWNONE))
1080 dtdtc.dwFlags = GDT_NONE;
1081 else
1082 dtdtc.dwFlags = GDT_VALID;
1083
1084 MONTHCAL_CopyTime (&infoPtr->date, &dtdtc.st);
1085 return (BOOL) SendMessageA (GetParent (hwnd), WM_NOTIFY,
1086 (WPARAM)dtdtc.nmhdr.idFrom, (LPARAM)&dtdtc);
1087}
1088
1089
1090static BOOL
1091DATETIME_SendSimpleNotify (HWND hwnd, UINT code)
1092{
1093 NMHDR nmhdr;
1094
1095 TRACE("%x\n",code);
1096 nmhdr.hwndFrom = hwnd;
1097 nmhdr.idFrom = GetWindowLongA( hwnd, GWL_ID);
1098 nmhdr.code = code;
1099
1100 return (BOOL) SendMessageA (GetParent (hwnd), WM_NOTIFY,
1101 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1102}
1103
1104static LRESULT
1105DATETIME_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1106{
1107 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr(hwnd);
1108 DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
1109
1110 /* set size */
1111 infoPtr->rcClient.bottom = HIWORD(lParam);
1112 infoPtr->rcClient.right = LOWORD(lParam);
1113
1114 TRACE("Height=%d, Width=%d\n", infoPtr->rcClient.bottom, infoPtr->rcClient.right);
1115
1116 /* use DrawEdge to adjust the size of rcEdge to get rcDraw */
1117 memcpy((&infoPtr->rcDraw), (&infoPtr->rcClient), sizeof(infoPtr->rcDraw));
1118
1119 DrawEdge((HDC)NULL, &(infoPtr->rcDraw), EDGE_SUNKEN, BF_RECT | BF_ADJUST);
1120
1121 /* set the size of the button that drops the calender down */
1122 /* FIXME: account for style that allows button on left side */
1123 infoPtr->calbutton.top = infoPtr->rcDraw.top;
1124 infoPtr->calbutton.bottom= infoPtr->rcDraw.bottom;
1125 infoPtr->calbutton.left = infoPtr->rcDraw.right-15;
1126 infoPtr->calbutton.right = infoPtr->rcDraw.right;
1127
1128 /* set enable/disable button size for show none style being enabled */
1129 /* FIXME: these dimensions are completely incorrect */
1130 infoPtr->checkbox.top = infoPtr->rcDraw.top;
1131 infoPtr->checkbox.bottom = infoPtr->rcDraw.bottom;
1132 infoPtr->checkbox.left = infoPtr->rcDraw.left;
1133 infoPtr->checkbox.right = infoPtr->rcDraw.left + 10;
1134
1135 /* update the position of the monthcal control */
1136 if(dwStyle & DTS_RIGHTALIGN)
1137 infoPtr->monthcal_pos.x = infoPtr->rcClient.right - ((infoPtr->calbutton.right -
1138 infoPtr->calbutton.left) + 145);
1139 else
1140 infoPtr->monthcal_pos.x = 8;
1141
1142 infoPtr->monthcal_pos.y = infoPtr->rcClient.bottom;
1143 ClientToScreen (hwnd, &(infoPtr->monthcal_pos));
1144 SetWindowPos(infoPtr->hMonthCal, 0, infoPtr->monthcal_pos.x,
1145 infoPtr->monthcal_pos.y,
1146 145, 150, 0);
1147
1148 InvalidateRect(hwnd, NULL, FALSE);
1149
1150 return 0;
1151}
1152
1153
1154static LRESULT
1155DATETIME_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
1156{
1157 DATETIME_INFO *infoPtr;
1158 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
1159
1160 /* allocate memory for info structure */
1161 TRACE("%04x %08lx\n",wParam,lParam);
1162#ifdef __WIN32OS2__
1163 infoPtr = (DATETIME_INFO*)initControl(hwnd,sizeof(DATETIME_INFO));
1164#else
1165 infoPtr = (DATETIME_INFO *)COMCTL32_Alloc (sizeof(DATETIME_INFO));
1166#endif
1167 if (infoPtr == NULL) {
1168 ERR("could not allocate info memory!\n");
1169 return 0;
1170 }
1171
1172 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
1173
1174 if (dwStyle & DTS_SHOWNONE) {
1175 infoPtr->hwndCheckbut=CreateWindowExA (0,"button", 0,
1176 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
1177 2,2,13,13,
1178 hwnd,
1179 0, GetWindowLongA (hwnd, GWL_HINSTANCE), 0);
1180 SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0);
1181 }
1182
1183 if (dwStyle & DTS_UPDOWN) {
1184 infoPtr->hUpdown=CreateUpDownControl (
1185 WS_CHILD | WS_BORDER | WS_VISIBLE,
1186 120,1,20,20,
1187 hwnd,1,0,0,
1188 UD_MAXVAL, UD_MINVAL, 0);
1189 }
1190
1191 infoPtr->fieldspec = (int *) COMCTL32_Alloc (32*sizeof(int));
1192 infoPtr->fieldRect = (RECT *) COMCTL32_Alloc (32*sizeof(RECT));
1193 infoPtr->buflen = (int *) COMCTL32_Alloc (32*sizeof(int));
1194 infoPtr->nrFieldsAllocated = 32;
1195
1196 DATETIME_SetFormat (hwnd, 0, 0);
1197
1198 /* create the monthcal control */
1199 infoPtr->hMonthCal = CreateWindowExA (0,"SysMonthCal32", 0,
1200 WS_BORDER | WS_POPUP | WS_CLIPSIBLINGS,
1201 0, 0, 0, 0,
1202 GetParent(hwnd),
1203 0, 0, 0);
1204
1205 /* initialize info structure */
1206 GetSystemTime (&infoPtr->date);
1207 infoPtr->dateValid = TRUE;
1208 infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
1209 return 0;
1210}
1211
1212
1213static LRESULT
1214DATETIME_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
1215{
1216 DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
1217
1218 TRACE("\n");
1219 COMCTL32_Free (infoPtr);
1220 SetWindowLongA( hwnd, 0, 0 );
1221 return 0;
1222}
1223
1224
1225static LRESULT WINAPI
1226DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1227{
1228
1229 if (!DATETIME_GetInfoPtr(hwnd) && (uMsg != WM_CREATE))
1230 return DefWindowProcA( hwnd, uMsg, wParam, lParam );
1231
1232 switch (uMsg)
1233 {
1234
1235 case DTM_GETSYSTEMTIME:
1236 return DATETIME_GetSystemTime (hwnd, wParam, lParam);
1237
1238 case DTM_SETSYSTEMTIME:
1239 return DATETIME_SetSystemTime (hwnd, wParam, lParam);
1240
1241 case DTM_GETRANGE:
1242 return DATETIME_GetRange(hwnd, lParam);
1243
1244 case DTM_SETRANGE:
1245 return DATETIME_SetRange(hwnd, wParam, lParam);
1246
1247 case DTM_SETFORMATA:
1248 return DATETIME_SetFormat (hwnd, wParam, lParam);
1249
1250 case DTM_SETFORMATW:
1251 return DATETIME_SetFormatW (hwnd, wParam, lParam);
1252
1253 case DTM_SETMCCOLOR:
1254 return DATETIME_SetMonthCalColor (hwnd, wParam, lParam);
1255
1256 case DTM_GETMCCOLOR:
1257 return DATETIME_GetMonthCalColor (hwnd, wParam);
1258
1259 case DTM_GETMONTHCAL:
1260 return DATETIME_GetMonthCal (hwnd);
1261
1262 case DTM_SETMCFONT:
1263 return DATETIME_SetMonthCalFont (hwnd, wParam, lParam);
1264
1265 case DTM_GETMCFONT:
1266 return DATETIME_GetMonthCalFont (hwnd);
1267
1268 case WM_PARENTNOTIFY:
1269 return DATETIME_ParentNotify (hwnd, wParam, lParam);
1270
1271 case WM_NOTIFY:
1272 return DATETIME_Notify (hwnd, wParam, lParam);
1273
1274 case WM_GETDLGCODE:
1275 return DLGC_WANTARROWS | DLGC_WANTCHARS;
1276
1277 case WM_PAINT:
1278 return DATETIME_Paint (hwnd, wParam);
1279
1280 case WM_KEYDOWN:
1281 return DATETIME_KeyDown (hwnd, wParam, lParam);
1282
1283 case WM_KILLFOCUS:
1284 return DATETIME_KillFocus (hwnd, wParam, lParam);
1285
1286 case WM_SETFOCUS:
1287 return DATETIME_SetFocus (hwnd, wParam, lParam);
1288
1289 case WM_SIZE:
1290 return DATETIME_Size (hwnd, wParam, lParam);
1291
1292 case WM_LBUTTONDOWN:
1293 return DATETIME_LButtonDown (hwnd, wParam, lParam);
1294
1295 case WM_LBUTTONUP:
1296 return DATETIME_LButtonUp (hwnd, wParam, lParam);
1297
1298 case WM_CREATE:
1299 return DATETIME_Create (hwnd, wParam, lParam);
1300
1301 case WM_DESTROY:
1302 return DATETIME_Destroy (hwnd, wParam, lParam);
1303
1304 default:
1305 if (uMsg >= WM_USER)
1306 ERR("unknown msg %04x wp=%08x lp=%08lx\n",
1307 uMsg, wParam, lParam);
1308#ifdef __WIN32OS2__
1309 return defComCtl32ProcA (hwnd, uMsg, wParam, lParam);
1310#else
1311 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1312#endif
1313 }
1314 return 0;
1315}
1316
1317
1318VOID
1319DATETIME_Register (void)
1320{
1321 WNDCLASSA wndClass;
1322
1323 TRACE("\n");
1324 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1325 wndClass.style = CS_GLOBALCLASS;
1326 wndClass.lpfnWndProc = (WNDPROC)DATETIME_WindowProc;
1327 wndClass.cbClsExtra = 0;
1328 wndClass.cbWndExtra = sizeof(DATETIME_INFO *);
1329 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1330 wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1331 wndClass.lpszClassName = DATETIMEPICK_CLASSA;
1332
1333 RegisterClassA (&wndClass);
1334}
1335
1336
1337VOID
1338DATETIME_Unregister (void)
1339{
1340 TRACE("\n");
1341 UnregisterClassA (DATETIMEPICK_CLASSA, (HINSTANCE)NULL);
1342}
1343
1344
Note: See TracBrowser for help on using the repository browser.