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