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

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

DT: datetime fixes

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