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

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

DT: Commented out TRACE call in DATETIME_ParentNotify

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