ReactOS  0.4.15-dev-2991-g632fa1c
datetime.c
Go to the documentation of this file.
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  * Copyright 2012 Owen Rudge for CodeWeavers
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22  *
23  * TODO:
24  * -- DTS_APPCANPARSE
25  * -- DTS_SHORTDATECENTURYFORMAT
26  * -- DTN_FORMAT
27  * -- DTN_FORMATQUERY
28  * -- DTN_USERSTRING
29  * -- DTN_WMKEYDOWN
30  * -- FORMATCALLBACK
31  */
32 
33 #include <math.h>
34 #include <string.h>
35 #include <stdarg.h>
36 #include <stdio.h>
37 #include <limits.h>
38 
39 #include "windef.h"
40 #include "winbase.h"
41 #include "wingdi.h"
42 #include "winuser.h"
43 #include "winnls.h"
44 #include "commctrl.h"
45 #include "comctl32.h"
46 #include "wine/debug.h"
47 
49 
50 typedef struct
51 {
60  RECT rcClient; /* rect around the edge of the window */
61  RECT rcDraw; /* rect inside of the border */
62  RECT checkbox; /* checkbox allowing the control to be enabled/disabled */
63  RECT calbutton; /* button that toggles the dropdown of the monthcal control */
64  BOOL bCalDepressed; /* TRUE = cal button is depressed */
66  int select;
67  WCHAR charsEntered[4];
71  int nrFields;
72  int haveFocus;
73  int *fieldspec;
75  int *buflen;
76  WCHAR textbuf[256];
80 
81 /* in monthcal.c */
82 extern int MONTHCAL_MonthLength(int month, int year);
83 extern int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace);
84 
85 /* this list of defines is closely related to `allowedformatchars' defined
86  * in datetime.c; the high nibble indicates the `base type' of the format
87  * specifier.
88  * Do not change without first reading DATETIME_UseFormat.
89  *
90  */
91 
92 #define DT_END_FORMAT 0
93 #define ONEDIGITDAY 0x01
94 #define TWODIGITDAY 0x02
95 #define THREECHARDAY 0x03
96 #define FULLDAY 0x04
97 #define ONEDIGIT12HOUR 0x11
98 #define TWODIGIT12HOUR 0x12
99 #define ONEDIGIT24HOUR 0x21
100 #define TWODIGIT24HOUR 0x22
101 #define ONEDIGITMINUTE 0x31
102 #define TWODIGITMINUTE 0x32
103 #define ONEDIGITMONTH 0x41
104 #define TWODIGITMONTH 0x42
105 #define THREECHARMONTH 0x43
106 #define FULLMONTH 0x44
107 #define ONEDIGITSECOND 0x51
108 #define TWODIGITSECOND 0x52
109 #define ONELETTERAMPM 0x61
110 #define TWOLETTERAMPM 0x62
111 #define ONEDIGITYEAR 0x71
112 #define TWODIGITYEAR 0x72
113 #define INVALIDFULLYEAR 0x73 /* FIXME - yyy is not valid - we'll treat it as yyyy */
114 #define FULLYEAR 0x74
115 #define FORMATCALLBACK 0x81 /* -> maximum of 0x80 callbacks possible */
116 #define FORMATCALLMASK 0x80
117 #define DT_STRING 0x0100
118 
119 #define DTHT_DATEFIELD 0xff /* for hit-testing */
120 
121 #define DTHT_NONE 0x1000
122 #define DTHT_CHECKBOX 0x2000 /* these should end at '00' , to make */
123 #define DTHT_MCPOPUP 0x3000 /* & DTHT_DATEFIELD 0 when DATETIME_KeyDown */
124 #define DTHT_GOTFOCUS 0x4000 /* tests for date-fields */
125 #define DTHT_NODATEMASK 0xf000 /* to mask check and drop down from others */
126 
127 static BOOL DATETIME_SendSimpleNotify (const DATETIME_INFO *infoPtr, UINT code);
129 static const WCHAR allowedformatchars[] = L"dhHmMstyX";
130 static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1};
131 
132 /* valid date limits */
133 #ifndef __REACTOS__
134 static const SYSTEMTIME max_allowed_date = { .wYear = 9999, .wMonth = 12, .wDayOfWeek = 0, .wDay = 31 };
135 static const SYSTEMTIME min_allowed_date = { .wYear = 1752, .wMonth = 9, .wDayOfWeek = 0, .wDay = 14 };
136 #else
137 static const SYSTEMTIME max_allowed_date = { /*.wYear =*/ 9999, /*.wMonth =*/ 12, /*.wDayOfWeek =*/ 0, /*.wDay =*/ 31 };
138 static const SYSTEMTIME min_allowed_date = { /*.wYear =*/ 1752, /*.wMonth =*/ 9, /*.wDayOfWeek =*/ 0, /*.wDay =*/ 14 };
139 #endif
140 
141 static DWORD
143 {
144  if (!systime) return GDT_NONE;
145 
146  if ((infoPtr->dwStyle & DTS_SHOWNONE) &&
147  (SendMessageW (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0) == BST_UNCHECKED))
148  return GDT_NONE;
149 
150  *systime = infoPtr->date;
151 
152  return GDT_VALID;
153 }
154 
155 /* Checks value is within configured date range
156  *
157  * PARAMETERS
158  *
159  * [I] infoPtr : valid pointer to control data
160  * [I] date : pointer to valid date data to check
161  *
162  * RETURN VALUE
163  *
164  * TRUE - date within configured range
165  * FALSE - date is outside configured range
166  */
168 {
169  SYSTEMTIME range[2];
170  DWORD limits;
171 
174  return FALSE;
175 
176  limits = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, 0, (LPARAM)range);
177 
178  if (limits & GDTR_MAX)
179  {
180  if (MONTHCAL_CompareSystemTime(date, &range[1]) == 1)
181  return FALSE;
182  }
183 
184  if (limits & GDTR_MIN)
185  {
186  if (MONTHCAL_CompareSystemTime(date, &range[0]) == -1)
187  return FALSE;
188  }
189 
190  return TRUE;
191 }
192 
193 static BOOL
195 {
196  if (!systime) return FALSE;
197 
198  TRACE("%04d/%02d/%02d %02d:%02d:%02d\n",
199  systime->wYear, systime->wMonth, systime->wDay,
200  systime->wHour, systime->wMinute, systime->wSecond);
201 
202  if (flag == GDT_VALID) {
203  if (systime->wYear == 0 ||
204  systime->wMonth < 1 || systime->wMonth > 12 ||
205  systime->wDay < 1 ||
206  systime->wDay > MONTHCAL_MonthLength(systime->wMonth, systime->wYear) ||
207  systime->wHour > 23 ||
208  systime->wMinute > 59 ||
209  systime->wSecond > 59 ||
210  systime->wMilliseconds > 999
211  )
212  return FALSE;
213 
214  /* Windows returns true if the date is valid but outside the limits set */
215  if (!DATETIME_IsDateInValidRange(infoPtr, systime))
216  return TRUE;
217 
218  infoPtr->dateValid = TRUE;
219  infoPtr->date = *systime;
220  /* always store a valid day of week */
222 
223  SendMessageW (infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
225  } else if ((infoPtr->dwStyle & DTS_SHOWNONE) && (flag == GDT_NONE)) {
226  infoPtr->dateValid = FALSE;
228  }
229  else
230  return FALSE;
231 
232  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
233  return TRUE;
234 }
235 
236 
237 /***
238  * Split up a formattxt in actions.
239  * See ms documentation for the meaning of the letter codes/'specifiers'.
240  *
241  * Notes:
242  * *'dddddd' is handled as 'dddd' plus 'dd'.
243  * *unrecognized formats are strings (here given the type DT_STRING;
244  * start of the string is encoded in lower bits of DT_STRING.
245  * Therefore, 'string' ends up as '<show seconds>tring'.
246  *
247  */
248 static void
250 {
251  unsigned int i;
252  int j, k, len;
253  BOOL inside_literal = FALSE; /* inside '...' */
254  int *nrFields = &infoPtr->nrFields;
255 
256  *nrFields = 0;
257  infoPtr->fieldspec[*nrFields] = 0;
259  k = 0;
260 
261  for (i = 0; formattxt[i]; i++) {
262  TRACE ("\n%d %c:", i, formattxt[i]);
263  if (!inside_literal) {
264  for (j = 0; j < len; j++) {
265  if (allowedformatchars[j]==formattxt[i]) {
266  TRACE ("%c[%d,%x]", allowedformatchars[j], *nrFields, infoPtr->fieldspec[*nrFields]);
267  if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
268  infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
269  break;
270  }
271  if (infoPtr->fieldspec[*nrFields] >> 4 != j) {
272  (*nrFields)++;
273  infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
274  break;
275  }
276  if ((infoPtr->fieldspec[*nrFields] & 0x0f) == maxrepetition[j]) {
277  (*nrFields)++;
278  infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
279  break;
280  }
281  infoPtr->fieldspec[*nrFields]++;
282  break;
283  } /* if allowedformatchar */
284  } /* for j */
285  }
286  else
287  j = len;
288 
289  if (formattxt[i] == '\'')
290  {
291  inside_literal = !inside_literal;
292  continue;
293  }
294 
295  /* char is not a specifier: handle char like a string */
296  if (j == len) {
297  if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
298  infoPtr->fieldspec[*nrFields] = DT_STRING + k;
299  infoPtr->buflen[*nrFields] = 0;
300  } else if ((infoPtr->fieldspec[*nrFields] & DT_STRING) != DT_STRING) {
301  (*nrFields)++;
302  infoPtr->fieldspec[*nrFields] = DT_STRING + k;
303  infoPtr->buflen[*nrFields] = 0;
304  }
305  infoPtr->textbuf[k] = formattxt[i];
306  k++;
307  infoPtr->buflen[*nrFields]++;
308  } /* if j=len */
309 
310  if (*nrFields == infoPtr->nrFieldsAllocated) {
311  FIXME ("out of memory; should reallocate. crash ahead.\n");
312  }
313  } /* for i */
314 
315  TRACE("\n");
316 
317  if (infoPtr->fieldspec[*nrFields] != 0) (*nrFields)++;
318 }
319 
320 
321 static BOOL
323 {
324  WCHAR format_buf[80];
325 
326  if (!format) {
327  DWORD format_item;
328 
330  format_item = LOCALE_SSHORTDATE;
331  else if ((infoPtr->dwStyle & DTS_LONGDATEFORMAT) == DTS_LONGDATEFORMAT)
332  format_item = LOCALE_SLONGDATE;
333  else if ((infoPtr->dwStyle & DTS_TIMEFORMAT) == DTS_TIMEFORMAT)
334  format_item = LOCALE_STIMEFORMAT;
335  else /* DTS_SHORTDATEFORMAT */
336  format_item = LOCALE_SSHORTDATE;
337  GetLocaleInfoW(LOCALE_USER_DEFAULT, format_item, format_buf, ARRAY_SIZE(format_buf));
338  format = format_buf;
339  }
340 
341  DATETIME_UseFormat (infoPtr, format);
342  InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
343 
344  return TRUE;
345 }
346 
347 
348 static BOOL
350 {
351  if (lpszFormat) {
352  BOOL retval;
353  INT len = MultiByteToWideChar(CP_ACP, 0, lpszFormat, -1, NULL, 0);
354  LPWSTR wstr = Alloc(len * sizeof(WCHAR));
355  if (wstr) MultiByteToWideChar(CP_ACP, 0, lpszFormat, -1, wstr, len);
356  retval = DATETIME_SetFormatW (infoPtr, wstr);
357  Free (wstr);
358  return retval;
359  }
360  else
361  return DATETIME_SetFormatW (infoPtr, 0);
362 
363 }
364 
365 
366 static void
367 DATETIME_ReturnTxt (const DATETIME_INFO *infoPtr, int count, LPWSTR result, int resultSize)
368 {
369  SYSTEMTIME date = infoPtr->date;
370  int spec;
371  WCHAR buffer[80];
372 
373  *result=0;
374  TRACE ("%d,%d\n", infoPtr->nrFields, count);
375  if (count>infoPtr->nrFields || count < 0) {
376  WARN ("buffer overrun, have %d want %d\n", infoPtr->nrFields, count);
377  return;
378  }
379 
380  if (!infoPtr->fieldspec) return;
381 
382  spec = infoPtr->fieldspec[count];
383  if (spec & DT_STRING) {
384  int txtlen = infoPtr->buflen[count];
385 
386  if (txtlen > resultSize)
387  txtlen = resultSize - 1;
388  memcpy (result, infoPtr->textbuf + (spec &~ DT_STRING), txtlen * sizeof(WCHAR));
389  result[txtlen] = 0;
390  TRACE ("arg%d=%x->[%s]\n", count, infoPtr->fieldspec[count], debugstr_w(result));
391  return;
392  }
393 
394 
395  switch (spec) {
396  case DT_END_FORMAT:
397  *result = 0;
398  break;
399  case ONEDIGITDAY:
400  wsprintfW (result, L"%d", date.wDay);
401  break;
402  case TWODIGITDAY:
403  wsprintfW (result, L"%.2d", date.wDay);
404  break;
405  case THREECHARDAY:
407  /*wsprintfW (result,"%.3s",days[date.wDayOfWeek]);*/
408  break;
409  case FULLDAY:
410  GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDAYNAME1+(date.wDayOfWeek+6)%7, result, resultSize);
411  break;
412  case ONEDIGIT12HOUR:
413  if (date.wHour == 0) {
414  result[0] = '1';
415  result[1] = '2';
416  result[2] = 0;
417  }
418  else
419  wsprintfW (result, L"%d", date.wHour - (date.wHour > 12 ? 12 : 0));
420  break;
421  case TWODIGIT12HOUR:
422  if (date.wHour == 0) {
423  result[0] = '1';
424  result[1] = '2';
425  result[2] = 0;
426  }
427  else
428  wsprintfW (result, L"%.2d", date.wHour - (date.wHour > 12 ? 12 : 0));
429  break;
430  case ONEDIGIT24HOUR:
431  wsprintfW (result, L"%d", date.wHour);
432  break;
433  case TWODIGIT24HOUR:
434  wsprintfW (result, L"%.2d", date.wHour);
435  break;
436  case ONEDIGITSECOND:
437  wsprintfW (result, L"%d", date.wSecond);
438  break;
439  case TWODIGITSECOND:
440  wsprintfW (result, L"%.2d", date.wSecond);
441  break;
442  case ONEDIGITMINUTE:
443  wsprintfW (result, L"%d", date.wMinute);
444  break;
445  case TWODIGITMINUTE:
446  wsprintfW (result, L"%.2d", date.wMinute);
447  break;
448  case ONEDIGITMONTH:
449  wsprintfW (result, L"%d", date.wMonth);
450  break;
451  case TWODIGITMONTH:
452  wsprintfW (result, L"%.2d", date.wMonth);
453  break;
454  case THREECHARMONTH:
456  wsprintfW (result, L"%s.3s", buffer);
457  break;
458  case FULLMONTH:
460  result, resultSize);
461  break;
462  case ONELETTERAMPM:
463  result[0] = (date.wHour < 12 ? 'A' : 'P');
464  result[1] = 0;
465  break;
466  case TWOLETTERAMPM:
467  result[0] = (date.wHour < 12 ? 'A' : 'P');
468  result[1] = 'M';
469  result[2] = 0;
470  break;
471  case FORMATCALLBACK:
472  FIXME ("Not implemented\n");
473  result[0] = 'x';
474  result[1] = 0;
475  break;
476  case ONEDIGITYEAR:
477  wsprintfW (result, L"%d", date.wYear % 10);
478  break;
479  case TWODIGITYEAR:
480  wsprintfW (result, L"%.2d", date.wYear % 100);
481  break;
482  case INVALIDFULLYEAR:
483  case FULLYEAR:
484  wsprintfW (result, L"%d", date.wYear);
485  break;
486  }
487 
488  TRACE ("arg%d=%x->[%s]\n", count, infoPtr->fieldspec[count], debugstr_w(result));
489 }
490 
491 static int wrap(int val, int delta, int minVal, int maxVal)
492 {
493  val += delta;
494  if (delta == INT_MIN || val < minVal) return maxVal;
495  if (delta == INT_MAX || val > maxVal) return minVal;
496  return val;
497 }
498 
499 static void
500 DATETIME_IncreaseField (DATETIME_INFO *infoPtr, int number, int delta)
501 {
502  SYSTEMTIME *date = &infoPtr->date;
503  SYSTEMTIME range[2];
504  DWORD limits;
505  BOOL min;
506 
507  TRACE ("%d\n", number);
508  if ((number > infoPtr->nrFields) || (number < 0)) return;
509 
510  if ((infoPtr->fieldspec[number] & DTHT_DATEFIELD) == 0) return;
511 
512  switch (infoPtr->fieldspec[number]) {
513  case ONEDIGITYEAR:
514  case TWODIGITYEAR:
515  case FULLYEAR:
516  if (delta == INT_MIN)
517  date->wYear = 1752;
518  else if (delta == INT_MAX)
519  date->wYear = 9999;
520  else
521  date->wYear = max(min(date->wYear + delta, 9999), 1752);
522 
523  if (date->wDay > MONTHCAL_MonthLength(date->wMonth, date->wYear))
524  /* This can happen when moving away from a leap year. */
525  date->wDay = MONTHCAL_MonthLength(date->wMonth, date->wYear);
527  break;
528  case ONEDIGITMONTH:
529  case TWODIGITMONTH:
530  case THREECHARMONTH:
531  case FULLMONTH:
532  date->wMonth = wrap(date->wMonth, delta, 1, 12);
534  delta = 0;
535  /* fall through */
536  case ONEDIGITDAY:
537  case TWODIGITDAY:
538  case THREECHARDAY:
539  case FULLDAY:
540  date->wDay = wrap(date->wDay, delta, 1, MONTHCAL_MonthLength(date->wMonth, date->wYear));
542  break;
543  case ONELETTERAMPM:
544  case TWOLETTERAMPM:
545  delta *= 12;
546  /* fall through */
547  case ONEDIGIT12HOUR:
548  case TWODIGIT12HOUR:
549  case ONEDIGIT24HOUR:
550  case TWODIGIT24HOUR:
551  date->wHour = wrap(date->wHour, delta, 0, 23);
552  break;
553  case ONEDIGITMINUTE:
554  case TWODIGITMINUTE:
555  date->wMinute = wrap(date->wMinute, delta, 0, 59);
556  break;
557  case ONEDIGITSECOND:
558  case TWODIGITSECOND:
559  date->wSecond = wrap(date->wSecond, delta, 0, 59);
560  break;
561  case FORMATCALLBACK:
562  FIXME ("Not implemented\n");
563  break;
564  }
565 
566  /* FYI: On 1752/9/14 the calendar changed and England and the
567  * American colonies changed to the Gregorian calendar. This change
568  * involved having September 14th follow September 2nd. So no date
569  * algorithm works before that date.
570  */
571  if (10000 * date->wYear + 100 * date->wMonth + date->wDay < 17520914) {
572  date->wYear = 1752;
573  date->wMonth = 9;
574  date->wDay = 14;
575  date->wSecond = 0;
576  date->wMinute = 0;
577  date->wHour = 0;
578  }
579 
580  /* Ensure time is within bounds */
581  limits = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, 0, (LPARAM)range);
582  min = delta < 0;
583 
584  if (limits & (min ? GDTR_MIN : GDTR_MAX))
585  {
586  int i = (min ? 0 : 1);
587 
588  if (MONTHCAL_CompareSystemTime(date, &range[i]) == (min ? -1 : 1))
589  {
590  date->wYear = range[i].wYear;
591  date->wMonth = range[i].wMonth;
592  date->wDayOfWeek = range[i].wDayOfWeek;
593  date->wDay = range[i].wDay;
594  date->wHour = range[i].wHour;
595  date->wMinute = range[i].wMinute;
596  date->wSecond = range[i].wSecond;
597  date->wMilliseconds = range[i].wMilliseconds;
598  }
599  }
600 }
601 
602 static int DATETIME_GetFieldWidth (const DATETIME_INFO *infoPtr, HDC hdc, int count)
603 {
604  /* fields are a fixed width, determined by the largest possible string */
605  /* presumably, these widths should be language dependent */
606  int spec;
607  WCHAR buffer[80];
608  LPCWSTR bufptr;
609  SIZE size;
610 
611  if (!infoPtr->fieldspec) return 0;
612 
613  spec = infoPtr->fieldspec[count];
614  if (spec & DT_STRING) {
615  int txtlen = infoPtr->buflen[count];
616 
617  if (txtlen > 79)
618  txtlen = 79;
619  memcpy (buffer, infoPtr->textbuf + (spec &~ DT_STRING), txtlen * sizeof(WCHAR));
620  buffer[txtlen] = 0;
621  bufptr = buffer;
622  }
623  else {
624  switch (spec) {
625  case ONEDIGITDAY:
626  case ONEDIGIT12HOUR:
627  case ONEDIGIT24HOUR:
628  case ONEDIGITSECOND:
629  case ONEDIGITMINUTE:
630  case ONEDIGITMONTH:
631  case ONEDIGITYEAR:
632  /* these seem to use a two byte field */
633  case TWODIGITDAY:
634  case TWODIGIT12HOUR:
635  case TWODIGIT24HOUR:
636  case TWODIGITSECOND:
637  case TWODIGITMINUTE:
638  case TWODIGITMONTH:
639  case TWODIGITYEAR:
640  bufptr = L"22";
641  break;
642  case INVALIDFULLYEAR:
643  case FULLYEAR:
644  bufptr = L"2222";
645  break;
646  case THREECHARMONTH:
647  case FULLMONTH:
648  case THREECHARDAY:
649  case FULLDAY:
650  {
651  const WCHAR *fall;
652  LCTYPE lctype;
653  INT i, max_count;
654  LONG cx;
655 
656  /* choose locale data type and fallback string */
657  switch (spec) {
658  case THREECHARDAY:
659  fall = L"Wed";
660  lctype = LOCALE_SABBREVDAYNAME1;
661  max_count = 7;
662  break;
663  case FULLDAY:
664  fall = L"Wednesday";
665  lctype = LOCALE_SDAYNAME1;
666  max_count = 7;
667  break;
668  case THREECHARMONTH:
669  fall = L"Dec";
670  lctype = LOCALE_SABBREVMONTHNAME1;
671  max_count = 12;
672  break;
673  default: /* FULLMONTH */
674  fall = L"September";
675  lctype = LOCALE_SMONTHNAME1;
676  max_count = 12;
677  break;
678  }
679 
680  cx = 0;
681  for (i = 0; i < max_count; i++)
682  {
683  if(GetLocaleInfoW(LOCALE_USER_DEFAULT, lctype + i,
685  {
687  if (size.cx > cx) cx = size.cx;
688  }
689  else /* locale independent fallback on failure */
690  {
691  GetTextExtentPoint32W(hdc, fall, lstrlenW(fall), &size);
692  cx = size.cx;
693  break;
694  }
695  }
696  return cx;
697  }
698  case ONELETTERAMPM:
699  bufptr = L"A";
700  break;
701  case TWOLETTERAMPM:
702  bufptr = L"AM";
703  break;
704  default:
705  bufptr = L"2";
706  break;
707  }
708  }
710  return size.cx;
711 }
712 
713 static void
715 {
716  TRACE("\n");
717 
718  if (infoPtr->dateValid) {
719  int i, prevright;
720  RECT *field;
721  RECT *rcDraw = &infoPtr->rcDraw;
722  SIZE size;
723  COLORREF oldTextColor;
724  HFONT oldFont = SelectObject (hdc, infoPtr->hFont);
725  INT oldBkMode = SetBkMode (hdc, TRANSPARENT);
726  WCHAR txt[80];
727 
728  DATETIME_ReturnTxt (infoPtr, 0, txt, ARRAY_SIZE(txt));
729  GetTextExtentPoint32W (hdc, txt, lstrlenW(txt), &size);
730  rcDraw->bottom = size.cy + 2;
731 
732  prevright = infoPtr->checkbox.right = ((infoPtr->dwStyle & DTS_SHOWNONE) ? 18 : 2);
733 
734  for (i = 0; i < infoPtr->nrFields; i++) {
735  DATETIME_ReturnTxt (infoPtr, i, txt, ARRAY_SIZE(txt));
736  GetTextExtentPoint32W (hdc, txt, lstrlenW(txt), &size);
737  field = &infoPtr->fieldRect[i];
738  field->left = prevright;
739  field->right = prevright + DATETIME_GetFieldWidth (infoPtr, hdc, i);
740  field->top = rcDraw->top;
741  field->bottom = rcDraw->bottom;
742  prevright = field->right;
743 
744  if (infoPtr->dwStyle & WS_DISABLED)
745  oldTextColor = SetTextColor (hdc, comctl32_color.clrGrayText);
746  else if ((infoPtr->haveFocus) && (i == infoPtr->select)) {
747  RECT selection;
748 
749  /* fill if focused */
751 
752  if (infoPtr->nCharsEntered)
753  {
754  memcpy(txt, infoPtr->charsEntered, infoPtr->nCharsEntered * sizeof(WCHAR));
755  txt[infoPtr->nCharsEntered] = 0;
756  GetTextExtentPoint32W (hdc, txt, lstrlenW(txt), &size);
757  }
758 
759  SetRect(&selection, 0, 0, size.cx, size.cy);
760  /* center rectangle */
761  OffsetRect(&selection, (field->right + field->left - size.cx)/2,
762  (field->bottom - size.cy)/2);
763 
764  FillRect(hdc, &selection, hbr);
765  DeleteObject (hbr);
766  oldTextColor = SetTextColor (hdc, comctl32_color.clrWindow);
767  }
768  else
769  oldTextColor = SetTextColor (hdc, comctl32_color.clrWindowText);
770 
771  /* draw the date text using the colour set above */
773  SetTextColor (hdc, oldTextColor);
774  }
775  SetBkMode (hdc, oldBkMode);
776  SelectObject (hdc, oldFont);
777  }
778 
779  if (!(infoPtr->dwStyle & DTS_UPDOWN)) {
781  DFCS_SCROLLDOWN | (infoPtr->bCalDepressed ? DFCS_PUSHED : 0) |
782  (infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
783  }
784 }
785 
786 
787 static INT
789 {
790  int i;
791 
792  TRACE ("%s\n", wine_dbgstr_point(&pt));
793 
794  if (PtInRect (&infoPtr->calbutton, pt)) return DTHT_MCPOPUP;
795  if (PtInRect (&infoPtr->checkbox, pt)) return DTHT_CHECKBOX;
796 
797  for (i = 0; i < infoPtr->nrFields; i++) {
798  if (PtInRect (&infoPtr->fieldRect[i], pt)) return i;
799  }
800 
801  return DTHT_NONE;
802 }
803 
804 /* Returns index of the nearest preceding date field from given,
805  or -1 if none was found */
806 static int DATETIME_GetPrevDateField(const DATETIME_INFO *infoPtr, int i)
807 {
808  for(--i; i >= 0; i--)
809  {
810  if (infoPtr->fieldspec[i] & DTHT_DATEFIELD) return i;
811  }
812  return -1;
813 }
814 
815 static void
817 {
818  int fieldNum = infoPtr->select & DTHT_DATEFIELD;
819  int i, val = 0;
820  BOOL clamp_day = FALSE;
821  SYSTEMTIME date = infoPtr->date;
822  int oldyear;
823 
824  if (infoPtr->select == -1 || infoPtr->nCharsEntered == 0)
825  return;
826 
827  if ((infoPtr->fieldspec[fieldNum] == ONELETTERAMPM) ||
828  (infoPtr->fieldspec[fieldNum] == TWOLETTERAMPM))
829  val = infoPtr->charsEntered[0];
830  else {
831  for (i=0; i<infoPtr->nCharsEntered; i++)
832  val = val * 10 + infoPtr->charsEntered[i] - '0';
833  }
834 
835  infoPtr->nCharsEntered = 0;
836 
837  switch (infoPtr->fieldspec[fieldNum]) {
838  case ONEDIGITYEAR:
839  case TWODIGITYEAR:
840  oldyear = date.wYear;
841  date.wYear = date.wYear - (date.wYear%100) + val;
842 
843  if (DATETIME_IsDateInValidRange(infoPtr, &date))
844  clamp_day = TRUE;
845  else
846  date.wYear = oldyear;
847 
848  break;
849  case INVALIDFULLYEAR:
850  case FULLYEAR:
851  oldyear = date.wYear;
852  date.wYear = val;
853 
854  if (DATETIME_IsDateInValidRange(infoPtr, &date))
855  clamp_day = TRUE;
856  else
857  date.wYear = oldyear;
858 
859  break;
860  case ONEDIGITMONTH:
861  case TWODIGITMONTH:
862  date.wMonth = val;
863  clamp_day = TRUE;
864  break;
865  case ONEDIGITDAY:
866  case TWODIGITDAY:
867  date.wDay = val;
868  break;
869  case ONEDIGIT12HOUR:
870  case TWODIGIT12HOUR:
871  if (val >= 24)
872  val -= 20;
873 
874  if (val >= 13)
875  date.wHour = val;
876  else if (val != 0) {
877  if (date.wHour >= 12) /* preserve current AM/PM state */
878  date.wHour = (val == 12 ? 12 : val + 12);
879  else
880  date.wHour = (val == 12 ? 0 : val);
881  }
882  break;
883  case ONEDIGIT24HOUR:
884  case TWODIGIT24HOUR:
885  date.wHour = val;
886  break;
887  case ONEDIGITMINUTE:
888  case TWODIGITMINUTE:
889  date.wMinute = val;
890  break;
891  case ONEDIGITSECOND:
892  case TWODIGITSECOND:
893  date.wSecond = val;
894  break;
895  case ONELETTERAMPM:
896  case TWOLETTERAMPM:
897  if (val == 'a' || val == 'A') {
898  if (date.wHour >= 12)
899  date.wHour -= 12;
900  } else if (val == 'p' || val == 'P') {
901  if (date.wHour < 12)
902  date.wHour += 12;
903  }
904  break;
905  }
906 
907  if (clamp_day && date.wDay > MONTHCAL_MonthLength(date.wMonth, date.wYear))
908  date.wDay = MONTHCAL_MonthLength(date.wMonth, date.wYear);
909 
910  if (DATETIME_SetSystemTime(infoPtr, GDT_VALID, &date))
912 }
913 
914 static void
916 {
918 
919  infoPtr->select = select;
920  infoPtr->nCharsEntered = 0;
921 }
922 
923 static LRESULT
925 {
926  POINT pt;
927  int new;
928 
929  pt.x = x;
930  pt.y = y;
931  new = DATETIME_HitTest (infoPtr, pt);
932 
933  SetFocus(infoPtr->hwndSelf);
934 
935  if (!(new & DTHT_NODATEMASK) || (new == DTHT_NONE))
936  {
937  if (new == DTHT_NONE)
938  new = infoPtr->nrFields - 1;
939  else
940  {
941  /* hitting string part moves selection to next date field to left */
942  if (infoPtr->fieldspec[new] & DT_STRING)
943  {
944  new = DATETIME_GetPrevDateField(infoPtr, new);
945  if (new == -1) return 0;
946  }
947  /* never select full day of week */
948  if (infoPtr->fieldspec[new] == FULLDAY) return 0;
949  }
950  }
951 
952  DATETIME_SetSelectedField(infoPtr, new);
953 
954  if (infoPtr->select == DTHT_MCPOPUP) {
955  RECT rcMonthCal;
956  POINT pos;
957  SendMessageW(infoPtr->hMonthCal, MCM_GETMINREQRECT, 0, (LPARAM)&rcMonthCal);
958 
959  /* FIXME: button actually is only depressed during dropdown of the */
960  /* calendar control and when the mouse is over the button window */
961  infoPtr->bCalDepressed = TRUE;
962 
963  /* recalculate the position of the monthcal popup */
964  if(infoPtr->dwStyle & DTS_RIGHTALIGN)
965  pos.x = infoPtr->calbutton.left - (rcMonthCal.right - rcMonthCal.left);
966  else
967  /* FIXME: this should be after the area reserved for the checkbox */
968  pos.x = infoPtr->rcDraw.left;
969 
970  pos.y = infoPtr->rcClient.bottom;
971  OffsetRect( &rcMonthCal, pos.x, pos.y );
972  MapWindowPoints( infoPtr->hwndSelf, 0, (POINT *)&rcMonthCal, 2 );
973  SetWindowPos(infoPtr->hMonthCal, 0, rcMonthCal.left, rcMonthCal.top,
974  rcMonthCal.right - rcMonthCal.left, rcMonthCal.bottom - rcMonthCal.top, 0);
975 
976  if(IsWindowVisible(infoPtr->hMonthCal)) {
977  ShowWindow(infoPtr->hMonthCal, SW_HIDE);
978  infoPtr->bDropdownEnabled = FALSE;
980  } else {
981  const SYSTEMTIME *lprgSysTimeArray = &infoPtr->date;
982  TRACE("update calendar %04d/%02d/%02d\n",
983  lprgSysTimeArray->wYear, lprgSysTimeArray->wMonth, lprgSysTimeArray->wDay);
984  SendMessageW(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
985 
986  if (infoPtr->bDropdownEnabled) {
987  ShowWindow(infoPtr->hMonthCal, SW_SHOW);
989  }
990  infoPtr->bDropdownEnabled = TRUE;
991  }
992 
993  TRACE ("dt:%p mc:%p mc parent:%p, desktop:%p\n",
994  infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hwndNotify, GetDesktopWindow ());
995  }
996 
997  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
998 
999  return 0;
1000 }
1001 
1002 
1003 static LRESULT
1005 {
1006  if(infoPtr->bCalDepressed) {
1007  infoPtr->bCalDepressed = FALSE;
1008  InvalidateRect(infoPtr->hwndSelf, &(infoPtr->calbutton), TRUE);
1009  }
1010 
1011  return 0;
1012 }
1013 
1014 
1015 static LRESULT
1017 {
1018  if (!hdc) {
1019  PAINTSTRUCT ps;
1020  hdc = BeginPaint (infoPtr->hwndSelf, &ps);
1021  DATETIME_Refresh (infoPtr, hdc);
1022  EndPaint (infoPtr->hwndSelf, &ps);
1023  } else {
1024  DATETIME_Refresh (infoPtr, hdc);
1025  }
1026 
1027  /* Not a click on the dropdown box, enabled it */
1028  infoPtr->bDropdownEnabled = TRUE;
1029 
1030  return 0;
1031 }
1032 
1033 
1034 static LRESULT
1036 {
1037  if( HIWORD(wParam) == BN_CLICKED) {
1039  infoPtr->dateValid = (state == BST_CHECKED);
1040  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1041  }
1042  return 0;
1043 }
1044 
1045 
1046 
1047 static LRESULT
1049 {
1050  TRACE("hwndbutton = %p\n", infoPtr->hwndCheckbut);
1051  if(infoPtr->hwndCheckbut == (HWND)lParam)
1052  return DATETIME_Button_Command(infoPtr, wParam, lParam);
1053  return 0;
1054 }
1055 
1056 
1057 static LRESULT
1059 {
1060  TRACE("%p %s\n", infoPtr, bEnable ? "TRUE" : "FALSE");
1061  if (bEnable)
1062  infoPtr->dwStyle &= ~WS_DISABLED;
1063  else
1064  infoPtr->dwStyle |= WS_DISABLED;
1065 
1066  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1067 
1068  return 0;
1069 }
1070 
1071 
1072 static LRESULT
1074 {
1075  HBRUSH hBrush, hSolidBrush = NULL;
1076  RECT rc;
1077 
1078  if (infoPtr->dwStyle & WS_DISABLED)
1079  hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrBtnFace);
1080  else
1081  {
1082  hBrush = (HBRUSH)SendMessageW(infoPtr->hwndNotify, WM_CTLCOLOREDIT,
1083  (WPARAM)hdc, (LPARAM)infoPtr->hwndSelf);
1084  if (!hBrush)
1085  hBrush = hSolidBrush = CreateSolidBrush(comctl32_color.clrWindow);
1086  }
1087 
1088  GetClientRect (infoPtr->hwndSelf, &rc);
1089 
1090  FillRect (hdc, &rc, hBrush);
1091 
1092  if (hSolidBrush)
1093  DeleteObject(hSolidBrush);
1094 
1095  return -1;
1096 }
1097 
1098 
1099 static LRESULT
1100 DATETIME_Notify (DATETIME_INFO *infoPtr, const NMHDR *lpnmh)
1101 {
1102  TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom);
1103  TRACE ("info: %p %p %p\n", infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hUpdown);
1104 
1105  if (lpnmh->code == MCN_SELECT) {
1106  ShowWindow(infoPtr->hMonthCal, SW_HIDE);
1107  infoPtr->dateValid = TRUE;
1108  SendMessageW (infoPtr->hMonthCal, MCM_GETCURSEL, 0, (LPARAM)&infoPtr->date);
1109  TRACE("got from calendar %04d/%02d/%02d day of week %d\n",
1110  infoPtr->date.wYear, infoPtr->date.wMonth, infoPtr->date.wDay, infoPtr->date.wDayOfWeek);
1112  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1115  }
1116  if ((lpnmh->hwndFrom == infoPtr->hUpdown) && (lpnmh->code == UDN_DELTAPOS)) {
1117  const NM_UPDOWN *lpnmud = (const NM_UPDOWN*)lpnmh;
1118  TRACE("Delta pos %d\n", lpnmud->iDelta);
1119  infoPtr->pendingUpdown = lpnmud->iDelta;
1120  }
1121  return 0;
1122 }
1123 
1124 
1125 static LRESULT
1127 {
1128  int fieldNum = infoPtr->select & DTHT_DATEFIELD;
1129  int wrap = 0;
1130  int new;
1131 
1132  if (!(infoPtr->haveFocus)) return 0;
1133  if ((fieldNum==0) && (infoPtr->select)) return 0;
1134 
1135  if (infoPtr->select & FORMATCALLMASK) {
1136  FIXME ("Callbacks not implemented yet\n");
1137  }
1138 
1139  switch (vkCode) {
1140  case VK_ADD:
1141  case VK_UP:
1142  infoPtr->nCharsEntered = 0;
1143  DATETIME_IncreaseField (infoPtr, fieldNum, 1);
1145  break;
1146  case VK_SUBTRACT:
1147  case VK_DOWN:
1148  infoPtr->nCharsEntered = 0;
1149  DATETIME_IncreaseField (infoPtr, fieldNum, -1);
1151  break;
1152  case VK_HOME:
1153  infoPtr->nCharsEntered = 0;
1154  DATETIME_IncreaseField (infoPtr, fieldNum, INT_MIN);
1156  break;
1157  case VK_END:
1158  infoPtr->nCharsEntered = 0;
1159  DATETIME_IncreaseField (infoPtr, fieldNum, INT_MAX);
1161  break;
1162  case VK_LEFT:
1163  new = infoPtr->select;
1164  do {
1165  if (new == 0) {
1166  new = new - 1;
1167  wrap++;
1168  } else {
1169  new--;
1170  }
1171  } while ((infoPtr->fieldspec[new] & DT_STRING) && (wrap<2));
1172  if (new != infoPtr->select)
1173  DATETIME_SetSelectedField(infoPtr, new);
1174  break;
1175  case VK_RIGHT:
1176  new = infoPtr->select;
1177  do {
1178  new++;
1179  if (new==infoPtr->nrFields) {
1180  new = 0;
1181  wrap++;
1182  }
1183  } while ((infoPtr->fieldspec[new] & DT_STRING) && (wrap<2));
1184  if (new != infoPtr->select)
1185  DATETIME_SetSelectedField(infoPtr, new);
1186  break;
1187  }
1188 
1189  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1190 
1191  return 0;
1192 }
1193 
1194 
1195 static LRESULT
1197 {
1198  int fieldNum, fieldSpec;
1199 
1200  fieldNum = infoPtr->select & DTHT_DATEFIELD;
1201  fieldSpec = infoPtr->fieldspec[fieldNum];
1202 
1203  if (fieldSpec == ONELETTERAMPM || fieldSpec == TWOLETTERAMPM) {
1204  infoPtr->charsEntered[0] = vkCode;
1205  infoPtr->nCharsEntered = 1;
1206 
1207  DATETIME_ApplySelectedField(infoPtr);
1208  } else if (vkCode >= '0' && vkCode <= '9') {
1209  int maxChars;
1210 
1211  infoPtr->charsEntered[infoPtr->nCharsEntered++] = vkCode;
1212 
1213  if (fieldSpec == INVALIDFULLYEAR || fieldSpec == FULLYEAR)
1214  maxChars = 4;
1215  else
1216  maxChars = 2;
1217 
1218  if ((fieldSpec == ONEDIGIT12HOUR ||
1219  fieldSpec == TWODIGIT12HOUR ||
1220  fieldSpec == ONEDIGIT24HOUR ||
1221  fieldSpec == TWODIGIT24HOUR) &&
1222  (infoPtr->nCharsEntered == 1))
1223  {
1224  if (vkCode >= '3')
1225  maxChars = 1;
1226  }
1227 
1228  if (maxChars == infoPtr->nCharsEntered)
1229  DATETIME_ApplySelectedField(infoPtr);
1230  }
1231 
1232  return 0;
1233 }
1234 
1235 
1236 static LRESULT
1238 {
1239  int fieldNum = infoPtr->select & DTHT_DATEFIELD;
1240 
1241  if ((SHORT)LOWORD(wScroll) != SB_THUMBPOSITION) return 0;
1242  if (!(infoPtr->haveFocus)) return 0;
1243  if ((fieldNum==0) && (infoPtr->select)) return 0;
1244 
1245  if (infoPtr->pendingUpdown >= 0) {
1246  DATETIME_IncreaseField (infoPtr, fieldNum, 1);
1248  }
1249  else {
1250  DATETIME_IncreaseField (infoPtr, fieldNum, -1);
1252  }
1253 
1254  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1255 
1256  return 0;
1257 }
1258 
1259 
1260 static LRESULT
1262 {
1263  TRACE("lost focus to %p\n", lostFocus);
1264 
1265  if (infoPtr->haveFocus) {
1267  infoPtr->haveFocus = 0;
1268  DATETIME_SetSelectedField (infoPtr, -1);
1269  }
1270 
1271  InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
1272 
1273  return 0;
1274 }
1275 
1276 
1277 static LRESULT
1279 {
1280  DWORD dwExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
1281  /* force control to have client edge */
1282  dwExStyle |= WS_EX_CLIENTEDGE;
1283  SetWindowLongW(hwnd, GWL_EXSTYLE, dwExStyle);
1284 
1285  return 1;
1286 }
1287 
1288 
1289 static LRESULT
1290 DATETIME_SetFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
1291 {
1292  TRACE("got focus from %p\n", lostFocus);
1293 
1294  /* if monthcal is open and it loses focus, close monthcal */
1295  if (infoPtr->hMonthCal && (lostFocus == infoPtr->hMonthCal) &&
1296  IsWindowVisible(infoPtr->hMonthCal))
1297  {
1298  ShowWindow(infoPtr->hMonthCal, SW_HIDE);
1300  /* note: this get triggered even if monthcal loses focus to a dropdown
1301  * box click, which occurs without an intermediate WM_PAINT call
1302  */
1303  infoPtr->bDropdownEnabled = FALSE;
1304  return 0;
1305  }
1306 
1307  if (infoPtr->haveFocus == 0) {
1309  infoPtr->haveFocus = DTHT_GOTFOCUS;
1310  }
1311 
1312  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
1313 
1314  return 0;
1315 }
1316 
1317 
1318 static BOOL
1320 {
1321  NMDATETIMECHANGE dtdtc;
1322 
1323  dtdtc.nmhdr.hwndFrom = infoPtr->hwndSelf;
1324  dtdtc.nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
1325  dtdtc.nmhdr.code = DTN_DATETIMECHANGE;
1326 
1327  dtdtc.dwFlags = infoPtr->dateValid ? GDT_VALID : GDT_NONE;
1328 
1329  dtdtc.st = infoPtr->date;
1330  return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
1331  dtdtc.nmhdr.idFrom, (LPARAM)&dtdtc);
1332 }
1333 
1334 
1335 static BOOL
1337 {
1338  NMHDR nmhdr;
1339 
1340  TRACE("%x\n", code);
1341  nmhdr.hwndFrom = infoPtr->hwndSelf;
1342  nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
1343  nmhdr.code = code;
1344 
1345  return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
1346  nmhdr.idFrom, (LPARAM)&nmhdr);
1347 }
1348 
1349 static LRESULT
1351 {
1352  /* set size */
1353  infoPtr->rcClient.bottom = height;
1354  infoPtr->rcClient.right = width;
1355 
1356  TRACE("Height=%d, Width=%d\n", infoPtr->rcClient.bottom, infoPtr->rcClient.right);
1357 
1358  infoPtr->rcDraw = infoPtr->rcClient;
1359 
1360  if (infoPtr->dwStyle & DTS_UPDOWN) {
1361  SetWindowPos(infoPtr->hUpdown, NULL,
1362  infoPtr->rcClient.right-14, 0,
1363  15, infoPtr->rcClient.bottom - infoPtr->rcClient.top,
1365  }
1366  else {
1367  /* set the size of the button that drops the calendar down */
1368  /* FIXME: account for style that allows button on left side */
1369  infoPtr->calbutton.top = infoPtr->rcDraw.top;
1370  infoPtr->calbutton.bottom= infoPtr->rcDraw.bottom;
1371  infoPtr->calbutton.left = infoPtr->rcDraw.right-15;
1372  infoPtr->calbutton.right = infoPtr->rcDraw.right;
1373  }
1374 
1375  /* set enable/disable button size for show none style being enabled */
1376  /* FIXME: these dimensions are completely incorrect */
1377  infoPtr->checkbox.top = infoPtr->rcDraw.top;
1378  infoPtr->checkbox.bottom = infoPtr->rcDraw.bottom;
1379  infoPtr->checkbox.left = infoPtr->rcDraw.left;
1380  infoPtr->checkbox.right = infoPtr->rcDraw.left + 10;
1381 
1382  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
1383 
1384  return 0;
1385 }
1386 
1387 static LRESULT
1389 {
1390  TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
1391  wStyleType, lpss->styleOld, lpss->styleNew);
1392 
1393  /* block DTS_SHOWNONE change */
1394  if ((lpss->styleNew ^ lpss->styleOld) & DTS_SHOWNONE)
1395  {
1396  if (lpss->styleOld & DTS_SHOWNONE)
1397  lpss->styleNew |= DTS_SHOWNONE;
1398  else
1399  lpss->styleNew &= ~DTS_SHOWNONE;
1400  }
1401 
1402  return 0;
1403 }
1404 
1405 static LRESULT
1406 DATETIME_StyleChanged(DATETIME_INFO *infoPtr, WPARAM wStyleType, const STYLESTRUCT *lpss)
1407 {
1408  TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
1409  wStyleType, lpss->styleOld, lpss->styleNew);
1410 
1411  if (wStyleType != GWL_STYLE) return 0;
1412 
1413  infoPtr->dwStyle = lpss->styleNew;
1414 
1415  if ( !(lpss->styleOld & DTS_SHOWNONE) && (lpss->styleNew & DTS_SHOWNONE) ) {
1417  2, 2, 13, 13, infoPtr->hwndSelf, 0,
1419  SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, infoPtr->dateValid ? 1 : 0, 0);
1420  }
1421  if ( (lpss->styleOld & DTS_SHOWNONE) && !(lpss->styleNew & DTS_SHOWNONE) ) {
1422  DestroyWindow(infoPtr->hwndCheckbut);
1423  infoPtr->hwndCheckbut = 0;
1424  }
1425  if ( !(lpss->styleOld & DTS_UPDOWN) && (lpss->styleNew & DTS_UPDOWN) ) {
1426  infoPtr->hUpdown = CreateUpDownControl (WS_CHILD | WS_BORDER | WS_VISIBLE, 120, 1, 20, 20,
1427  infoPtr->hwndSelf, 1, 0, 0, UD_MAXVAL, UD_MINVAL, 0);
1428  }
1429  if ( (lpss->styleOld & DTS_UPDOWN) && !(lpss->styleNew & DTS_UPDOWN) ) {
1430  DestroyWindow(infoPtr->hUpdown);
1431  infoPtr->hUpdown = 0;
1432  }
1433 
1434  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1435  return 0;
1436 }
1437 
1439 {
1440  SIZE field_size;
1441  RECT rect;
1442  WCHAR txt[80];
1443  HDC hdc;
1444  HFONT oldFont;
1445  int i;
1446 
1447  size->cx = size->cy = 0;
1448 
1449  hdc = GetDC(infoPtr->hwndSelf);
1450  oldFont = SelectObject(hdc, infoPtr->hFont);
1451 
1452  /* Get text font height */
1453  DATETIME_ReturnTxt(infoPtr, 0, txt, ARRAY_SIZE(txt));
1454  GetTextExtentPoint32W(hdc, txt, lstrlenW(txt), &field_size);
1455  size->cy = field_size.cy;
1456 
1457  /* Get text font width */
1458  for (i = 0; i < infoPtr->nrFields; i++)
1459  {
1460  size->cx += DATETIME_GetFieldWidth(infoPtr, hdc, i);
1461  }
1462 
1463  SelectObject(hdc, oldFont);
1464  ReleaseDC(infoPtr->hwndSelf, hdc);
1465 
1466  if (infoPtr->dwStyle & DTS_UPDOWN)
1467  {
1468  GetWindowRect(infoPtr->hUpdown, &rect);
1469  size->cx += rect.right - rect.left;
1470  }
1471  else
1472  {
1473  size->cx += infoPtr->calbutton.right - infoPtr->calbutton.left;
1474  }
1475 
1476  if (infoPtr->dwStyle & DTS_SHOWNONE)
1477  {
1478  size->cx += infoPtr->checkbox.right - infoPtr->checkbox.left;
1479  }
1480 
1481  /* Add space between controls for them not to get too close */
1482  size->cx += 12;
1483  size->cy += 4;
1484 
1485  TRACE("cx=%d cy=%d\n", size->cx, size->cy);
1486  return TRUE;
1487 }
1488 
1489 static LRESULT
1491 {
1492  infoPtr->hFont = font;
1493  if (repaint) InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
1494  return 0;
1495 }
1496 
1497 
1498 static LRESULT
1500 {
1501  DATETIME_INFO *infoPtr = Alloc (sizeof(DATETIME_INFO));
1502  STYLESTRUCT ss = { 0, lpcs->style };
1503 
1504  if (!infoPtr) return -1;
1505 
1506  infoPtr->hwndSelf = hwnd;
1507  infoPtr->dwStyle = lpcs->style;
1508 
1509  infoPtr->nrFieldsAllocated = 32;
1510  infoPtr->fieldspec = Alloc (infoPtr->nrFieldsAllocated * sizeof(int));
1511  infoPtr->fieldRect = Alloc (infoPtr->nrFieldsAllocated * sizeof(RECT));
1512  infoPtr->buflen = Alloc (infoPtr->nrFieldsAllocated * sizeof(int));
1513  infoPtr->hwndNotify = lpcs->hwndParent;
1514  infoPtr->select = -1; /* initially, nothing is selected */
1515  infoPtr->bDropdownEnabled = TRUE;
1516 
1517  DATETIME_StyleChanged(infoPtr, GWL_STYLE, &ss);
1518  DATETIME_SetFormatW (infoPtr, 0);
1519 
1520  /* create the monthcal control */
1522  0, 0, 0, 0, infoPtr->hwndSelf, 0, 0, 0);
1523 
1524  /* initialize info structure */
1525  GetLocalTime (&infoPtr->date);
1526  infoPtr->dateValid = TRUE;
1528 
1529  SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
1530 
1531  return 0;
1532 }
1533 
1534 
1535 
1536 static LRESULT
1538 {
1539  if (infoPtr->hwndCheckbut)
1540  DestroyWindow(infoPtr->hwndCheckbut);
1541  if (infoPtr->hUpdown)
1542  DestroyWindow(infoPtr->hUpdown);
1543  if (infoPtr->hMonthCal)
1544  DestroyWindow(infoPtr->hMonthCal);
1545  SetWindowLongPtrW( infoPtr->hwndSelf, 0, 0 ); /* clear infoPtr */
1546  Free (infoPtr->buflen);
1547  Free (infoPtr->fieldRect);
1548  Free (infoPtr->fieldspec);
1549  Free (infoPtr);
1550  return 0;
1551 }
1552 
1553 
1554 static INT
1556 {
1557  WCHAR buf[80];
1558  int i;
1559 
1560  if (!dst || (count <= 0)) return 0;
1561 
1562  dst[0] = 0;
1563  for (i = 0; i < infoPtr->nrFields; i++)
1564  {
1565  DATETIME_ReturnTxt(infoPtr, i, buf, ARRAY_SIZE(buf));
1566  if ((lstrlenW(dst) + lstrlenW(buf)) < count)
1567  lstrcatW(dst, buf);
1568  else break;
1569  }
1570  return lstrlenW(dst);
1571 }
1572 
1574 {
1575  int i, length = 0;
1576  WCHAR buffer[80];
1577 
1578  TRACE("%p.\n", info);
1579 
1580  for (i = 0; i < info->nrFields; i++)
1581  {
1583  length += lstrlenW(buffer);
1584  }
1585  return length;
1586 }
1587 
1588 static LRESULT WINAPI
1590 {
1591  DATETIME_INFO *infoPtr = ((DATETIME_INFO *)GetWindowLongPtrW (hwnd, 0));
1592 
1593  TRACE ("%x, %lx, %lx\n", uMsg, wParam, lParam);
1594 
1595  if (!infoPtr && (uMsg != WM_CREATE) && (uMsg != WM_NCCREATE))
1596  return DefWindowProcW( hwnd, uMsg, wParam, lParam );
1597 
1598  switch (uMsg) {
1599 
1600  case DTM_GETSYSTEMTIME:
1601  return DATETIME_GetSystemTime (infoPtr, (SYSTEMTIME *) lParam);
1602 
1603  case DTM_SETSYSTEMTIME:
1604  return DATETIME_SetSystemTime (infoPtr, wParam, (SYSTEMTIME *) lParam);
1605 
1606  case DTM_GETRANGE:
1607  return SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, wParam, lParam);
1608 
1609  case DTM_SETRANGE:
1610  return SendMessageW (infoPtr->hMonthCal, MCM_SETRANGE, wParam, lParam);
1611 
1612  case DTM_SETFORMATA:
1613  return DATETIME_SetFormatA (infoPtr, (LPCSTR)lParam);
1614 
1615  case DTM_SETFORMATW:
1616  return DATETIME_SetFormatW (infoPtr, (LPCWSTR)lParam);
1617 
1618  case DTM_GETMONTHCAL:
1619  return (LRESULT)infoPtr->hMonthCal;
1620 
1621  case DTM_SETMCCOLOR:
1622  return SendMessageW (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);
1623 
1624  case DTM_GETMCCOLOR:
1625  return SendMessageW (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);
1626 
1627  case DTM_SETMCFONT:
1628  return SendMessageW (infoPtr->hMonthCal, WM_SETFONT, wParam, lParam);
1629 
1630  case DTM_GETMCFONT:
1631  return SendMessageW (infoPtr->hMonthCal, WM_GETFONT, wParam, lParam);
1632 
1633  case DTM_GETIDEALSIZE:
1634  return DATETIME_GetIdealSize(infoPtr, (SIZE *)lParam);
1635 
1636  case WM_NOTIFY:
1637  return DATETIME_Notify (infoPtr, (LPNMHDR)lParam);
1638 
1639  case WM_ENABLE:
1640  return DATETIME_Enable (infoPtr, (BOOL)wParam);
1641 
1642  case WM_ERASEBKGND:
1643  return DATETIME_EraseBackground (infoPtr, (HDC)wParam);
1644 
1645  case WM_GETDLGCODE:
1647 
1648  case WM_PRINTCLIENT:
1649  case WM_PAINT:
1650  return DATETIME_Paint (infoPtr, (HDC)wParam);
1651 
1652  case WM_KEYDOWN:
1653  return DATETIME_KeyDown (infoPtr, wParam);
1654 
1655  case WM_CHAR:
1656  return DATETIME_Char (infoPtr, wParam);
1657 
1658  case WM_KILLFOCUS:
1659  return DATETIME_KillFocus (infoPtr, (HWND)wParam);
1660 
1661  case WM_NCCREATE:
1663 
1664  case WM_SETFOCUS:
1665  return DATETIME_SetFocus (infoPtr, (HWND)wParam);
1666 
1667  case WM_SIZE:
1668  return DATETIME_Size (infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
1669 
1670  case WM_LBUTTONDOWN:
1671  return DATETIME_LButtonDown (infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
1672 
1673  case WM_LBUTTONUP:
1674  return DATETIME_LButtonUp (infoPtr);
1675 
1676  case WM_VSCROLL:
1677  return DATETIME_VScroll (infoPtr, (WORD)wParam);
1678 
1679  case WM_CREATE:
1681 
1682  case WM_DESTROY:
1683  return DATETIME_Destroy (infoPtr);
1684 
1685  case WM_COMMAND:
1686  return DATETIME_Command (infoPtr, wParam, lParam);
1687 
1688  case WM_STYLECHANGING:
1690 
1691  case WM_STYLECHANGED:
1692  return DATETIME_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
1693 
1694  case WM_SETFONT:
1695  return DATETIME_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);
1696 
1697  case WM_GETFONT:
1698  return (LRESULT) infoPtr->hFont;
1699 
1700  case WM_GETTEXT:
1701  return (LRESULT) DATETIME_GetText(infoPtr, wParam, (LPWSTR)lParam);
1702 
1703  case WM_GETTEXTLENGTH:
1704  return (LRESULT)DATETIME_GetTextLength(infoPtr);
1705 
1706  case WM_SETTEXT:
1707  return CB_ERR;
1708 
1709  default:
1710  if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
1711  ERR("unknown msg %04x wp=%08lx lp=%08lx\n",
1712  uMsg, wParam, lParam);
1713  return DefWindowProcW (hwnd, uMsg, wParam, lParam);
1714  }
1715 }
1716 
1717 
1718 void
1720 {
1721  WNDCLASSW wndClass;
1722 
1723  ZeroMemory (&wndClass, sizeof(WNDCLASSW));
1724  wndClass.style = CS_GLOBALCLASS;
1725  wndClass.lpfnWndProc = DATETIME_WindowProc;
1726  wndClass.cbClsExtra = 0;
1727  wndClass.cbWndExtra = sizeof(DATETIME_INFO *);
1728  wndClass.hCursor = LoadCursorW (0, (LPCWSTR)IDC_ARROW);
1729  wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
1731 
1732  RegisterClassW (&wndClass);
1733 }
1734 
1735 
1736 void
1738 {
1740 }
#define VK_SUBTRACT
Definition: winuser.h:2227
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define DTM_GETRANGE
Definition: commctrl.h:4333
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define WM_GETTEXTLENGTH
Definition: winuser.h:1601
#define WS_DISABLED
Definition: pedump.c:621
BOOL dateValid
Definition: datetime.c:58
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define NM_KILLFOCUS
Definition: commctrl.h:136
#define DTM_SETRANGE
Definition: commctrl.h:4335
GLint GLint GLsizei width
Definition: gl.h:1546
#define MCN_SELECT
Definition: commctrl.h:4305
#define max(a, b)
Definition: svc.c:63
void DATETIME_Unregister(void)
Definition: datetime.c:1737
int * fieldspec
Definition: datetime.c:73
#define DLGC_WANTCHARS
Definition: winuser.h:2593
#define FULLMONTH
Definition: datetime.c:106
static LRESULT DATETIME_StyleChanging(DATETIME_INFO *infoPtr, WPARAM wStyleType, STYLESTRUCT *lpss)
Definition: datetime.c:1388
#define DTHT_DATEFIELD
Definition: datetime.c:119
static BOOL DATETIME_SetFormatW(DATETIME_INFO *infoPtr, LPCWSTR format)
Definition: datetime.c:322
#define LOCALE_SABBREVMONTHNAME1
Definition: winnls.h:104
#define DTN_DROPDOWN
Definition: commctrl.h:4453
UINT style
Definition: winuser.h:3151
#define WM_GETDLGCODE
Definition: winuser.h:1671
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define WM_CHAR
Definition: winuser.h:1699
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
static unsigned int bufptr
Definition: tncon.cpp:77
#define INT_MAX
Definition: limits.h:40
GLuint64EXT * result
Definition: glext.h:11304
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WORD wMonth
Definition: winbase.h:900
HDC WINAPI GetDC(_In_opt_ HWND)
Definition: mk_font.cpp:20
#define MCM_GETMINREQRECT
Definition: commctrl.h:4200
static BOOL DATETIME_GetIdealSize(DATETIME_INFO *infoPtr, SIZE *size)
Definition: datetime.c:1438
#define TRUE
Definition: types.h:120
#define TWODIGITYEAR
Definition: datetime.c:112
#define pt(x, y)
Definition: drawing.c:79
#define SW_HIDE
Definition: winuser.h:762
static int DATETIME_GetFieldWidth(const DATETIME_INFO *infoPtr, HDC hdc, int count)
Definition: datetime.c:602
#define TWODIGITMONTH
Definition: datetime.c:104
static LRESULT DATETIME_Button_Command(DATETIME_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: datetime.c:1035
#define CP_ACP
Definition: compat.h:109
#define DTM_SETFORMATW
Definition: commctrl.h:4338
#define TWODIGITDAY
Definition: datetime.c:94
#define LOCALE_SABBREVDAYNAME1
Definition: winnls.h:84
#define LOCALE_USER_DEFAULT
WORD wDayOfWeek
Definition: winbase.h:901
RECT calbutton
Definition: datetime.c:63
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define WM_GETTEXT
Definition: winuser.h:1600
#define WARN(fmt,...)
Definition: debug.h:112
#define THREECHARDAY
Definition: datetime.c:95
static LRESULT DATETIME_NCCreate(HWND hwnd, const CREATESTRUCTW *lpcs)
Definition: datetime.c:1278
#define MCM_GETRANGE
Definition: commctrl.h:4262
static LRESULT DATETIME_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
Definition: datetime.c:1499
static LRESULT DATETIME_KeyDown(DATETIME_INFO *infoPtr, DWORD vkCode)
Definition: datetime.c:1126
#define DTHT_NONE
Definition: datetime.c:121
static BOOL DATETIME_SendDateTimeChangeNotify(const DATETIME_INFO *infoPtr)
Definition: datetime.c:1319
static LRESULT DATETIME_LButtonUp(DATETIME_INFO *infoPtr)
Definition: datetime.c:1004
#define DT_STRING
Definition: datetime.c:117
#define FULLDAY
Definition: datetime.c:96
static HDC
Definition: imagelist.c:92
#define DFCS_INACTIVE
Definition: winuser.h:502
#define FORMATCALLMASK
Definition: datetime.c:116
LONG top
Definition: windef.h:307
#define VK_ADD
Definition: winuser.h:2225
#define MONTHCAL_CLASSW
Definition: commctrl.h:4175
#define VK_LEFT
Definition: winuser.h:2199
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1499
#define UD_MINVAL
Definition: commctrl.h:2129
#define ZeroMemory
Definition: winbase.h:1664
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
#define TWOLETTERAMPM
Definition: datetime.c:110
#define GWL_EXSTYLE
Definition: winuser.h:845
GLuint buffer
Definition: glext.h:5915
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
int cbClsExtra
Definition: winuser.h:3153
HWND WINAPI SetFocus(_In_opt_ HWND)
HWND hwndNotify
Definition: datetime.c:54
static INT DATETIME_GetText(const DATETIME_INFO *infoPtr, INT count, LPWSTR dst)
Definition: datetime.c:1555
static int DATETIME_GetTextLength(const DATETIME_INFO *info)
Definition: datetime.c:1573
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
static BOOL DATETIME_SetFormatA(DATETIME_INFO *infoPtr, LPCSTR lpszFormat)
Definition: datetime.c:349
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_DOWN
Definition: winuser.h:2202
#define WS_CHILD
Definition: pedump.c:617
#define GetWindowLongPtrW
Definition: winuser.h:4804
static LRESULT DATETIME_SetFont(DATETIME_INFO *infoPtr, HFONT font, BOOL repaint)
Definition: datetime.c:1490
LONG left
Definition: windef.h:306
#define SWP_NOZORDER
Definition: winuser.h:1232
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
static void DATETIME_IncreaseField(DATETIME_INFO *infoPtr, int number, int delta)
Definition: datetime.c:500
LONG right
Definition: windef.h:308
HFONT hFont
Definition: datetime.c:69
#define MCM_SETRANGE
Definition: commctrl.h:4264
BOOL bCalDepressed
Definition: datetime.c:64
HWND hMonthCal
Definition: datetime.c:53
#define lstrlenW
Definition: compat.h:609
#define WM_NCCREATE
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
#define COLOR_WINDOW
Definition: winuser.h:908
int32_t INT
Definition: typedefs.h:58
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
int selection
Definition: ctm.c:92
int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace)
Definition: monthcal.c:470
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define WM_ENABLE
Definition: winuser.h:1597
#define WM_PRINTCLIENT
Definition: richedit.h:70
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION Free
Definition: exfuncs.h:814
RECT rcClient
Definition: datetime.c:60
#define DTM_GETMCFONT
Definition: commctrl.h:4352
#define DTM_SETMCFONT
Definition: commctrl.h:4350
UINT code
Definition: winuser.h:3134
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1098
COLORREF clrWindowText
Definition: comctl32.h:177
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define LOCALE_SDAYNAME1
Definition: winnls.h:77
#define ONEDIGITMONTH
Definition: datetime.c:103
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define DFCS_PUSHED
Definition: winuser.h:503
WORD wYear
Definition: winbase.h:899
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1034
WINE_DEFAULT_DEBUG_CHANNEL(datetime)
DWORD LCTYPE
Definition: winnls.h:517
#define VK_HOME
Definition: winuser.h:2198
#define MCM_GETCURSEL
Definition: commctrl.h:4184
#define LOCALE_SMONTHNAME1
Definition: winnls.h:91
COLORREF clrActiveCaption
Definition: comctl32.h:179
static LRESULT DATETIME_SetFocus(DATETIME_INFO *infoPtr, HWND lostFocus)
Definition: datetime.c:1290
#define VK_UP
Definition: winuser.h:2200
void DATETIME_Register(void)
Definition: datetime.c:1719
#define FULLYEAR
Definition: datetime.c:114
HWND hwndCheckbut
Definition: datetime.c:59
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ONEDIGIT24HOUR
Definition: datetime.c:99
long LONG
Definition: pedump.c:60
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define DTS_LONGDATEFORMAT
Definition: commctrl.h:4360
HWND WINAPI CreateUpDownControl(DWORD style, INT x, INT y, INT cx, INT cy, HWND parent, INT id, HINSTANCE inst, HWND buddy, INT maxVal, INT minVal, INT curVal)
Definition: commctrl.c:829
static size_t double number
Definition: printf.c:69
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
short SHORT
Definition: pedump.c:59
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
static void DATETIME_ApplySelectedField(DATETIME_INFO *infoPtr)
Definition: datetime.c:816
UINT_PTR idFrom
Definition: winuser.h:3133
#define debugstr_w
Definition: kernel32.h:32
static LRESULT DATETIME_Char(DATETIME_INFO *infoPtr, WPARAM vkCode)
Definition: datetime.c:1196
WNDPROC lpfnWndProc
Definition: winuser.h:3152
#define LOCALE_SLONGDATE
Definition: winnls.h:61
static void DATETIME_ReturnTxt(const DATETIME_INFO *infoPtr, int count, LPWSTR result, int resultSize)
Definition: datetime.c:367
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:111
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define DTHT_NODATEMASK
Definition: datetime.c:125
static int DATETIME_GetPrevDateField(const DATETIME_INFO *infoPtr, int i)
Definition: datetime.c:806
#define TRANSPARENT
Definition: wingdi.h:949
LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) DECLSPEC_HIDDEN
Definition: monthcal.c:305
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
WORD wMinute
Definition: winbase.h:904
#define WM_GETFONT
Definition: winuser.h:1633
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
#define SB_THUMBPOSITION
Definition: winuser.h:572
#define WM_KEYDOWN
Definition: winuser.h:1697
LPCWSTR lpszClassName
Definition: winuser.h:3160
LONG_PTR LPARAM
Definition: windef.h:208
#define BM_GETCHECK
Definition: winuser.h:1900
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:286
#define DTM_GETMCCOLOR
Definition: commctrl.h:4346
const char * LPCSTR
Definition: xmlstorage.h:183
#define DT_VCENTER
Definition: winuser.h:543
#define SW_SHOW
Definition: winuser.h:769
#define WM_SETTEXT
Definition: winuser.h:1599
#define DFCS_SCROLLDOWN
Definition: winuser.h:490
static void DATETIME_UseFormat(DATETIME_INFO *infoPtr, LPCWSTR formattxt)
Definition: datetime.c:249
#define CB_ERR
Definition: winuser.h:2410
int haveFocus
Definition: datetime.c:72
#define WM_DESTROY
Definition: winuser.h:1591
GLuint GLfloat * val
Definition: glext.h:7180
#define MCM_SETCURSEL
Definition: commctrl.h:4186
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define MCM_SETCOLOR
Definition: commctrl.h:4202
static BOOL DATETIME_SendSimpleNotify(const DATETIME_INFO *infoPtr, UINT code)
Definition: datetime.c:1336
static void DATETIME_SetSelectedField(DATETIME_INFO *infoPtr, int select)
Definition: datetime.c:915
const char * wine_dbgstr_point(const POINT *guid)
#define BM_SETCHECK
Definition: winuser.h:1903
#define TRACE(s)
Definition: solgame.cpp:4
#define WM_KILLFOCUS
Definition: winuser.h:1596
GLsizeiptr size
Definition: glext.h:5919
int cbWndExtra
Definition: winuser.h:3154
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WM_SIZE
Definition: winuser.h:1593
Definition: parser.c:43
#define TWODIGIT24HOUR
Definition: datetime.c:100
#define NM_SETFOCUS
Definition: commctrl.h:135
static DWORD DATETIME_GetSystemTime(const DATETIME_INFO *infoPtr, SYSTEMTIME *systime)
Definition: datetime.c:142
#define SWP_NOACTIVATE
Definition: winuser.h:1227
DWORD COLORREF
Definition: windef.h:300
static LRESULT DATETIME_Size(DATETIME_INFO *infoPtr, INT width, INT height)
Definition: datetime.c:1350
int MONTHCAL_MonthLength(int month, int year)
Definition: monthcal.c:217
int nCharsEntered
Definition: datetime.c:68
#define CS_GLOBALCLASS
Definition: winuser.h:647
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
PVOID Alloc(IN DWORD dwFlags, IN SIZE_T dwBytes)
Definition: main.c:63
unsigned short WORD
Definition: ntddk_ex.h:93
static LRESULT DATETIME_Destroy(DATETIME_INFO *infoPtr)
Definition: datetime.c:1537
#define BN_CLICKED
Definition: winuser.h:1907
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DTM_SETFORMATA
Definition: commctrl.h:4337
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
#define DTS_RIGHTALIGN
Definition: commctrl.h:4364
int nrFieldsAllocated
Definition: datetime.c:70
static BOOL DATETIME_SetSystemTime(DATETIME_INFO *infoPtr, DWORD flag, const SYSTEMTIME *systime)
Definition: datetime.c:194
#define DTS_SHORTDATECENTURYFORMAT
Definition: commctrl.h:4361
COMCTL32_SysColor comctl32_color
Definition: commctrl.c:82
WCHAR charsEntered[4]
Definition: datetime.c:67
#define DTM_GETSYSTEMTIME
Definition: commctrl.h:4329
#define DEFAULT_GUI_FONT
Definition: wingdi.h:908
WORD wSecond
Definition: winbase.h:905
#define WM_PAINT
Definition: winuser.h:1602
static LRESULT DATETIME_Notify(DATETIME_INFO *infoPtr, const NMHDR *lpnmh)
Definition: datetime.c:1100
WORD wMilliseconds
Definition: winbase.h:906
#define GDTR_MAX
Definition: commctrl.h:4457
#define DTM_GETMONTHCAL
Definition: commctrl.h:4348
#define UD_MAXVAL
Definition: commctrl.h:2128
#define DTM_SETSYSTEMTIME
Definition: commctrl.h:4331
static LRESULT DATETIME_LButtonDown(DATETIME_INFO *infoPtr, INT x, INT y)
Definition: datetime.c:924
static BOOL DATETIME_IsDateInValidRange(const DATETIME_INFO *infoPtr, const SYSTEMTIME *date)
Definition: datetime.c:167
HWND hUpdown
Definition: datetime.c:55
#define UDN_DELTAPOS
Definition: commctrl.h:2169
static const WCHAR L[]
Definition: oid.c:1250
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
HDC hdc
Definition: main.c:9
#define LOCALE_SSHORTDATE
Definition: winnls.h:60
#define GDTR_MIN
Definition: commctrl.h:4456
static int state
Definition: maze.c:121
static LRESULT WINAPI DATETIME_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: datetime.c:1589
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GDT_NONE
Definition: commctrl.h:4461
GLenum GLsizei len
Definition: glext.h:6722
#define WM_APP
Definition: eventvwr.h:70
#define TWODIGIT12HOUR
Definition: datetime.c:98
#define WM_COMMAND
Definition: winuser.h:1722
#define NM_UPDOWN
Definition: commctrl.h:2160
Definition: inflate.c:139
HWND hwndFrom
Definition: winuser.h:3132
static const WCHAR allowedformatchars[]
Definition: datetime.c:129
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define BST_UNCHECKED
Definition: winuser.h:199
int * buflen
Definition: datetime.c:75
#define WM_USER
Definition: winuser.h:1877
int code
Definition: main.c:75
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
#define ONEDIGIT12HOUR
Definition: datetime.c:97
GLenum GLint * range
Definition: glext.h:7539
#define VK_RIGHT
Definition: winuser.h:2201
#define TWODIGITMINUTE
Definition: datetime.c:102
#define INT_MIN
Definition: limits.h:39
int pendingUpdown
Definition: datetime.c:78
HCURSOR hCursor
Definition: winuser.h:3157
#define ERR(fmt,...)
Definition: debug.h:110
#define GWL_STYLE
Definition: winuser.h:846
#define ONEDIGITSECOND
Definition: datetime.c:107
RECT rcDraw
Definition: datetime.c:61
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:888
#define DTHT_MCPOPUP
Definition: datetime.c:123
WORD wDay
Definition: winbase.h:902
RECT checkbox
Definition: datetime.c:62
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define DT_SINGLELINE
Definition: winuser.h:540
COLORREF clrGrayText
Definition: comctl32.h:178
COLORREF clrBtnFace
Definition: comctl32.h:168
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define WS_BORDER
Definition: pedump.c:625
_In_ BOOL bEnable
Definition: winddi.h:3426
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define GDT_VALID
Definition: commctrl.h:4460
#define DATETIMEPICK_CLASSW
Definition: commctrl.h:4322
#define ONELETTERAMPM
Definition: datetime.c:109
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const int maxrepetition[]
Definition: datetime.c:130
#define ARRAY_SIZE(a)
Definition: main.h:24
__u16 date
Definition: mkdosfs.c:366
#define WC_BUTTONW
Definition: commctrl.h:4623
#define WM_CTLCOLOREDIT
Definition: winuser.h:1749
HBRUSH hbrBackground
Definition: winuser.h:3158
HWND hwndSelf
Definition: datetime.c:52
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DTHT_GOTFOCUS
Definition: datetime.c:124
#define WM_LBUTTONUP
Definition: winuser.h:1759
GLenum GLenum dst
Definition: glext.h:6340
WORD wHour
Definition: winbase.h:903
#define FORMATCALLBACK
Definition: datetime.c:115
#define DTS_SHOWNONE
Definition: commctrl.h:4358
DWORD styleNew
Definition: winuser.h:3668
#define min(a, b)
Definition: monoChain.cc:55
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
#define DFC_SCROLL
Definition: winuser.h:475
#define MultiByteToWideChar
Definition: compat.h:110
#define WM_SETFONT
Definition: winuser.h:1632
#define BST_CHECKED
Definition: winuser.h:197
static LRESULT DATETIME_VScroll(DATETIME_INFO *infoPtr, WORD wScroll)
Definition: datetime.c:1237
int nrFields
Definition: datetime.c:71
DWORD styleOld
Definition: winuser.h:3667
static INT DATETIME_HitTest(const DATETIME_INFO *infoPtr, POINT pt)
Definition: datetime.c:788
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static LRESULT DATETIME_KillFocus(DATETIME_INFO *infoPtr, HWND lostFocus)
Definition: datetime.c:1261
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define IDC_ARROW
Definition: winuser.h:682
#define DTN_CLOSEUP
Definition: commctrl.h:4454
_Out_opt_ int * cx
Definition: commctrl.h:585
#define GWLP_HINSTANCE
Definition: winuser.h:850
#define INVALIDFULLYEAR
Definition: datetime.c:113
static const SYSTEMTIME max_allowed_date
Definition: datetime.c:134
BOOL bDropdownEnabled
Definition: datetime.c:65
#define WM_CREATE
Definition: winuser.h:1590
static LRESULT DATETIME_Enable(DATETIME_INFO *infoPtr, BOOL bEnable)
Definition: datetime.c:1058
#define DTS_TIMEFORMAT
Definition: commctrl.h:4362
#define HIWORD(l)
Definition: typedefs.h:247
#define ONEDIGITYEAR
Definition: datetime.c:111
BOOL WINAPI IsWindowVisible(_In_ HWND)
SYSTEMTIME date
Definition: datetime.c:57
LONG bottom
Definition: windef.h:309
BOOL COMCTL32_IsReflectedMessage(UINT uMsg) DECLSPEC_HIDDEN
Definition: commctrl.c:1748
#define DT_CENTER
Definition: winuser.h:527
static LRESULT DATETIME_Paint(DATETIME_INFO *infoPtr, HDC hdc)
Definition: datetime.c:1016
#define MCM_GETCOLOR
Definition: commctrl.h:4204
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
static LRESULT DATETIME_StyleChanged(DATETIME_INFO *infoPtr, WPARAM wStyleType, const STYLESTRUCT *lpss)
Definition: datetime.c:1406
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SetWindowLongPtrW
Definition: winuser.h:5321
#define ss
Definition: i386-dis.c:434
#define DTM_SETMCCOLOR
Definition: commctrl.h:4344
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
#define TWODIGITSECOND
Definition: datetime.c:108
RECT * fieldRect
Definition: datetime.c:74
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define WM_SETFOCUS
Definition: winuser.h:1595
int month[12]
Definition: systime.c:13
struct DATETIME_INFO * LPDATETIME_INFO
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LONG_PTR LRESULT
Definition: windef.h:209
static LRESULT DATETIME_EraseBackground(const DATETIME_INFO *infoPtr, HDC hdc)
Definition: datetime.c:1073
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
#define DTHT_CHECKBOX
Definition: datetime.c:122
COLORREF clrWindow
Definition: comctl32.h:176
#define WS_VISIBLE
Definition: pedump.c:620
#define THREECHARMONTH
Definition: datetime.c:105
#define DTN_DATETIMECHANGE
Definition: commctrl.h:4366
#define DTS_UPDOWN
Definition: commctrl.h:4357
POINT monthcal_pos
Definition: datetime.c:77
LONG cy
Definition: windef.h:335
#define LOCALE_STIMEFORMAT
Definition: winnls.h:62
LPARAM lParam
Definition: combotst.c:139
#define DTM_GETIDEALSIZE
Definition: commctrl.h:4355
#define ONEDIGITMINUTE
Definition: datetime.c:101
int k
Definition: mpi.c:3369
#define LOWORD(l)
Definition: pedump.c:82
#define VK_END
Definition: winuser.h:2197
#define GWLP_ID
Definition: winuser.h:854
#define DLGC_WANTARROWS
Definition: winuser.h:2585
WCHAR textbuf[256]
Definition: datetime.c:76
static const SYSTEMTIME min_allowed_date
Definition: datetime.c:135
static LRESULT DATETIME_Command(DATETIME_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: datetime.c:1048
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
#define WM_NOTIFY
Definition: richedit.h:61
static int wrap(int val, int delta, int minVal, int maxVal)
Definition: datetime.c:491
#define DT_END_FORMAT
Definition: datetime.c:92
#define WM_VSCROLL
Definition: winuser.h:1726
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:17
#define ONEDIGITDAY
Definition: datetime.c:93
DWORD dwStyle
Definition: datetime.c:56
static void DATETIME_Refresh(DATETIME_INFO *infoPtr, HDC hdc)
Definition: datetime.c:714