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

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

DT: datetime update + listview fix

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