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

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

* empty log message *

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