Date Time control audit

Dimitrie O. Paun dpaun at rogers.com
Thu Oct 21 19:50:19 CDT 2004


ChangeLog
    Audit the Date Time Control. Unicodification.
    Type safe functions (pass infoPtr and type safe values around).
    Some cleanup and indentation fixes.


Index: dlls/comctl32/datetime.c
===================================================================
RCS file: /var/cvs/wine/dlls/comctl32/datetime.c,v
retrieving revision 1.45
diff -u -r1.45 datetime.c
--- dlls/comctl32/datetime.c	2 Sep 2004 23:00:53 -0000	1.45
+++ dlls/comctl32/datetime.c	22 Oct 2004 00:36:34 -0000
@@ -19,10 +19,27 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
+ * NOTE
+ * 
+ * This code was audited for completeness against the documented features
+ * of Comctl32.dll version 6.0 on Oct. 20, 2004, by Dimitrie O. Paun.
+ * 
+ * Unless otherwise noted, we believe this code to be complete, as per
+ * the specification mentioned above.
+ * If you discover missing features, or bugs, please note them below.
+ * 
  * TODO:
- *   - All messages.
- *   - All notifications.
- *
+ *    -- DTS_APPCANPARSE
+ *    -- DTS_SHORTDATECENTURYFORMAT
+ *    -- DTN_CLOSEUP
+ *    -- DTN_FORMAT
+ *    -- DTN_FORMATQUERY
+ *    -- DTN_USERSTRING
+ *    -- DTN_WMKEYDOWN
+ *    -- DTM_GETMCFONT, DTM_SETMCFONT
+ *    -- FORMATCALLBACK
+ *    -- fix formatting
+ *    -- GWL_STYLE handling
  */
 
 #include <math.h>
@@ -38,32 +55,34 @@
 #include "commctrl.h"
 #include "comctl32.h"
 #include "wine/debug.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(datetime);
 
 typedef struct
 {
-	HWND hMonthCal;
-	HWND hwndNotify;
-	HWND hUpdown;
-	SYSTEMTIME date;
-	BOOL dateValid;
-	HWND hwndCheckbut;
-	RECT rcClient; /* rect around the edge of the window */
-	RECT rcDraw; /* rect inside of the border */
-	RECT checkbox;  /* checkbox allowing the control to be enabled/disabled */
-	RECT calbutton; /* button that toggles the dropdown of the monthcal control */
-	BOOL bCalDepressed; /* TRUE = cal button is depressed */
-	int  select;
-	HFONT hFont;
-	int nrFieldsAllocated;
-	int nrFields;
-	int haveFocus;
-	int *fieldspec;
-	RECT *fieldRect;
-	int  *buflen;
-	char textbuf[256];
-        POINT monthcal_pos;
+    HWND hwndSelf;
+    HWND hMonthCal;
+    HWND hwndNotify;
+    HWND hUpdown;
+    SYSTEMTIME date;
+    BOOL dateValid;
+    HWND hwndCheckbut;
+    RECT rcClient; /* rect around the edge of the window */
+    RECT rcDraw; /* rect inside of the border */
+    RECT checkbox;  /* checkbox allowing the control to be enabled/disabled */
+    RECT calbutton; /* button that toggles the dropdown of the monthcal control */
+    BOOL bCalDepressed; /* TRUE = cal button is depressed */
+    int  select;
+    HFONT hFont;
+    int nrFieldsAllocated;
+    int nrFields;
+    int haveFocus;
+    int *fieldspec;
+    RECT *fieldRect;
+    int  *buflen;
+    WCHAR textbuf[256];
+    POINT monthcal_pos;
 } DATETIME_INFO, *LPDATETIME_INFO;
 
 /* in monthcal.c */
@@ -110,27 +129,22 @@
 #define DTHT_MCPOPUP  0x300     /* & DTHT_DATEFIELD 0 when DATETIME_KeyDown */
 #define DTHT_GOTFOCUS 0x400     /* tests for date-fields */
 
-#define DATETIME_GetInfoPtr(hwnd) ((DATETIME_INFO *)GetWindowLongPtrW (hwnd, 0))
-
-static BOOL DATETIME_SendSimpleNotify (HWND hwnd, UINT code);
-static BOOL DATETIME_SendDateTimeChangeNotify (HWND hwnd);
+static BOOL DATETIME_SendSimpleNotify (DATETIME_INFO *infoPtr, UINT code);
+static BOOL DATETIME_SendDateTimeChangeNotify (DATETIME_INFO *infoPtr);
 extern void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to);
-static const char *allowedformatchars = {"dhHmMstyX'"};
+static const WCHAR allowedformatchars[] = {'d', 'h', 'H', 'm', 'M', 's', 't', 'y', 'X', '\'', 0};
 static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1,-1};
 
 
-static LRESULT
-DATETIME_GetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
+static DWORD
+DATETIME_GetSystemTime (DATETIME_INFO *infoPtr, SYSTEMTIME *lprgSysTimeArray)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
+  DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
 
-  TRACE("%04x %08lx\n",wParam,lParam);
-  if (!lParam) return GDT_NONE;
+  if (!lprgSysTimeArray) return GDT_NONE;
 
   if ((dwStyle & DTS_SHOWNONE) &&
-       (SendMessageA (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0) == BST_UNCHECKED))
+       (SendMessageW (infoPtr->hwndCheckbut, BM_GETCHECK, 0, 0) == BST_UNCHECKED))
         return GDT_NONE;
 
   MONTHCAL_CopyTime (&infoPtr->date, lprgSysTimeArray);
@@ -139,360 +153,269 @@
 }
 
 
-static LRESULT
-DATETIME_SetSystemTime (HWND hwnd, WPARAM wParam, LPARAM lParam )
+static BOOL
+DATETIME_SetSystemTime (DATETIME_INFO *infoPtr, DWORD flag, SYSTEMTIME *lprgSysTimeArray)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
-
-  TRACE("%p %04x %08lx\n",hwnd, wParam, lParam);
-  if (!lParam) return 0;
+  if (!lprgSysTimeArray) return 0;
 
   TRACE("%04d/%02d/%02d %02d:%02d:%02d\n",
         lprgSysTimeArray->wYear, lprgSysTimeArray->wMonth, lprgSysTimeArray->wDay,
         lprgSysTimeArray->wHour, lprgSysTimeArray->wMinute, lprgSysTimeArray->wSecond);
 
-  if (wParam==GDT_VALID) {
+  if (flag == GDT_VALID) {
       infoPtr->dateValid = TRUE;
       MONTHCAL_CopyTime (lprgSysTimeArray, &infoPtr->date);
-	SendMessageA(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
-      SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
-  } else if (wParam==GDT_NONE) {
+      SendMessageW (infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
+      SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
+  } else if (flag == GDT_NONE) {
       infoPtr->dateValid = FALSE;
-      SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, BST_UNCHECKED, 0);
+      SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, BST_UNCHECKED, 0);
   }
-  InvalidateRect(hwnd, NULL, TRUE);
+  InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
   return 1;
 }
 
-
-static LRESULT
-DATETIME_GetRange (HWND hwnd, LPARAM lParam )
+static DWORD
+DATETIME_GetRange (DATETIME_INFO *infoPtr, SYSTEMTIME *lprgSysTimeArray)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-  LRESULT ret;
+  DWORD ret;
 
-  TRACE("%08lx\n", lParam);
-  ret =  SendMessageA (infoPtr->hMonthCal, MCM_GETRANGE, 0, lParam);
+  ret = SendMessageW (infoPtr->hMonthCal, MCM_GETRANGE, 0, (LPARAM)lprgSysTimeArray);
   if (!ret) ret = 1; /* bug emulation... */
   return ret;
 }
 
-static LRESULT
-DATETIME_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam )
-{
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-  TRACE("%04x %08lx\n",wParam,lParam);
-
-  return SendMessageA (infoPtr->hMonthCal, MCM_SETRANGE, wParam, lParam);
-}
-
-static LRESULT
-DATETIME_GetMonthCalColor (HWND hwnd, WPARAM wParam)
-{
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-  TRACE("%04x\n",wParam);
-  return SendMessageA (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);
-}
-
-
-static LRESULT
-DATETIME_SetMonthCalColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-  TRACE("%04x %08lx\n",wParam,lParam);
-  return SendMessageA (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);
-}
-
-
-/* FIXME: need to get way to force font into monthcal structure */
-static LRESULT
-DATETIME_GetMonthCal (HWND hwnd)
-{
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-  TRACE("\n");
-  return (LRESULT)infoPtr->hMonthCal;
-}
-
-
-
-/* FIXME: need to get way to force font into monthcal structure */
-
-static LRESULT
-DATETIME_GetMonthCalFont (HWND hwnd)
-{
-
-  TRACE("\n");
-  return 0;
-}
-
-
-static LRESULT
-DATETIME_SetMonthCalFont (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-
-  TRACE("%04x %08lx\n",wParam,lParam);
-  return 0;
-}
-
-
-/*
-   Split up a formattxt in actions.
-   See ms documentation for the meaning of the letter codes/'specifiers'.
-
-   Notes:
-   *'dddddd' is handled as 'dddd' plus 'dd'.
-   *unrecognized formats are strings (here given the type DT_STRING;
-   start of the string is encoded in lower bits of DT_STRING.
-   Therefore, 'string' ends finally up as '<show seconds>tring'.
 
+/***
+ * Split up a formattxt in actions.
+ * See ms documentation for the meaning of the letter codes/'specifiers'.
+ *
+ * Notes:
+ * *'dddddd' is handled as 'dddd' plus 'dd'.
+ * *unrecognized formats are strings (here given the type DT_STRING;
+ * start of the string is encoded in lower bits of DT_STRING.
+ * Therefore, 'string' ends finally up as '<show seconds>tring'.
+ *
  */
-
-
 static void
-DATETIME_UseFormat (DATETIME_INFO *infoPtr, const char *formattxt)
+DATETIME_UseFormat (DATETIME_INFO *infoPtr, LPCWSTR formattxt)
 {
- unsigned int i;
- int j,k,len;
- int *nrFields=& infoPtr->nrFields;
-
- TRACE ("%s\n",formattxt);
-
-
- *nrFields=0;
- infoPtr->fieldspec[*nrFields]=0;
- len=strlen(allowedformatchars);
- k=0;
-
- for (i=0; formattxt[i]; i++)  {
-	TRACE ("\n%d %c:",i, formattxt[i]);
- 	for (j=0; j<len; j++) {
- 		if (allowedformatchars[j]==formattxt[i]) {
-			TRACE ("%c[%d,%x]",allowedformatchars[j], *nrFields,
-							 infoPtr->fieldspec[*nrFields]);
-			if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
-				infoPtr->fieldspec[*nrFields]=(j<<4) +1;
-				break;
-			}
-			if (infoPtr->fieldspec[*nrFields]>>4!=j) {
-				(*nrFields)++;
-				infoPtr->fieldspec[*nrFields]=(j<<4) +1;
-				break;
-			}
-			if ((infoPtr->fieldspec[*nrFields] & 0x0f)==maxrepetition[j]) {
-				(*nrFields)++;
-				infoPtr->fieldspec[*nrFields]=(j<<4) +1;
-				break;
-			}
-			infoPtr->fieldspec[*nrFields]++;
-			break;
-		}   /* if allowedformatchar */
-	 } /* for j */
-
-
-			/* char is not a specifier: handle char like a string */
-	if (j==len) {
+    unsigned int i;
+    int j, k, len;
+    int *nrFields = &infoPtr->nrFields;
+
+    *nrFields = 0;
+    infoPtr->fieldspec[*nrFields] = 0;
+    len = strlenW(allowedformatchars);
+    k = 0;
+
+    for (i = 0; formattxt[i]; i++)  {
+	TRACE ("\n%d %c:", i, formattxt[i]);
+ 	for (j = 0; j < len; j++) {
+ 	    if (allowedformatchars[j]==formattxt[i]) {
+		TRACE ("%c[%d,%x]", allowedformatchars[j], *nrFields, infoPtr->fieldspec[*nrFields]);
 		if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
-			infoPtr->fieldspec[*nrFields]=DT_STRING+k;
-			infoPtr->buflen[*nrFields]=0;
-        } else
-		if ((infoPtr->fieldspec[*nrFields] & DT_STRING)!=DT_STRING)  {
-			(*nrFields)++;
-			infoPtr->fieldspec[*nrFields]=DT_STRING+k;
-			infoPtr->buflen[*nrFields]=0;
+		    infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
+		    break;
+		}
+		if (infoPtr->fieldspec[*nrFields] >> 4 != j) {
+		    (*nrFields)++;
+		    infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
+		    break;
 		}
-		infoPtr->textbuf[k]=formattxt[i];
-		k++;
-		infoPtr->buflen[*nrFields]++;
+		if ((infoPtr->fieldspec[*nrFields] & 0x0f) == maxrepetition[j]) {
+		    (*nrFields)++;
+		    infoPtr->fieldspec[*nrFields] = (j<<4) + 1;
+		    break;
+		}
+		infoPtr->fieldspec[*nrFields]++;
+		break;
+	    }   /* if allowedformatchar */
+	} /* for j */
+
+	/* char is not a specifier: handle char like a string */
+	if (j == len) {
+	    if ((*nrFields==0) && (infoPtr->fieldspec[*nrFields]==0)) {
+		infoPtr->fieldspec[*nrFields] = DT_STRING + k;
+		infoPtr->buflen[*nrFields] = 0;
+            } else if ((infoPtr->fieldspec[*nrFields] & DT_STRING) != DT_STRING)  {
+		(*nrFields)++;
+		infoPtr->fieldspec[*nrFields] = DT_STRING + k;
+		infoPtr->buflen[*nrFields] = 0;
+	    }
+	    infoPtr->textbuf[k] = formattxt[i];
+	    k++;
+	    infoPtr->buflen[*nrFields]++;
 	}   /* if j=len */
 
-	if (*nrFields==infoPtr->nrFieldsAllocated) {
-		FIXME ("out of memory; should reallocate. crash ahead.\n");
+	if (*nrFields == infoPtr->nrFieldsAllocated) {
+	    FIXME ("out of memory; should reallocate. crash ahead.\n");
 	}
+    } /* for i */
 
-  } /* for i */
-
-  TRACE("\n");
+    TRACE("\n");
 
-  if (infoPtr->fieldspec[*nrFields]!=0) (*nrFields)++;
+    if (infoPtr->fieldspec[*nrFields] != 0) (*nrFields)++;
 }
 
 
-static LRESULT
-DATETIME_SetFormat (HWND hwnd, WPARAM wParam, LPARAM lParam)
+static BOOL
+DATETIME_SetFormatW (DATETIME_INFO *infoPtr, LPCWSTR lpszFormat)
 {
- DATETIME_INFO *infoPtr= DATETIME_GetInfoPtr (hwnd);
- char format_buf[80];
- DWORD format_item;
-
- TRACE("%04x %08lx\n",wParam,lParam);
- if (!lParam) {
-  	DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
+    if (!lpszFormat) {
+	WCHAR format_buf[80];
+	DWORD format_item;
+	DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
 
 	if (dwStyle & DTS_LONGDATEFORMAT)
-		format_item=LOCALE_SLONGDATE;
+	    format_item = LOCALE_SLONGDATE;
 	else if (dwStyle & DTS_TIMEFORMAT)
-		format_item=LOCALE_STIMEFORMAT;
+	    format_item = LOCALE_STIMEFORMAT;
         else /* DTS_SHORTDATEFORMAT */
-		format_item=LOCALE_SSHORTDATE;
-	GetLocaleInfoA( GetSystemDefaultLCID(), format_item,format_buf,sizeof(format_buf));
-	DATETIME_UseFormat (infoPtr, format_buf);
- }
- else
- 	DATETIME_UseFormat (infoPtr, (char *) lParam);
+	    format_item = LOCALE_SSHORTDATE;
+	GetLocaleInfoW( GetSystemDefaultLCID(), format_item, format_buf, sizeof(format_buf)/sizeof(format_buf[0]));
+	lpszFormat = format_buf;
+    }
 
- return infoPtr->nrFields;
-}
+    DATETIME_UseFormat (infoPtr, lpszFormat);
 
+    return infoPtr->nrFields;
+}
 
-static LRESULT
-DATETIME_SetFormatW (HWND hwnd, WPARAM wParam, LPARAM lParam)
 
+static BOOL
+DATETIME_SetFormatA (DATETIME_INFO *infoPtr, LPCSTR lpszFormat)
 {
- TRACE("%04x %08lx\n",wParam,lParam);
- if (lParam) {
-	LPSTR buf;
-	int retval;
-        int len = WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, NULL, 0, NULL, NULL );
-
- 	buf = (LPSTR) Alloc (len);
-        WideCharToMultiByte( CP_ACP, 0, (LPWSTR)lParam, -1, buf, len, NULL, NULL );
-	retval=DATETIME_SetFormat (hwnd, 0, (LPARAM) buf);
-	Free (buf);
+    if (lpszFormat) {
+	BOOL retval;
+	INT len = MultiByteToWideChar(CP_ACP, 0, lpszFormat, -1, NULL, 0);
+	LPWSTR wstr = Alloc(len * sizeof(WCHAR));
+	if (wstr) MultiByteToWideChar(CP_ACP, 0, lpszFormat, -1, wstr, len);
+	retval = DATETIME_SetFormatW (infoPtr, wstr);
+	Free (wstr);
 	return retval;
- }
- else
-	return DATETIME_SetFormat (hwnd, 0, 0);
+    }
+    else
+	return DATETIME_SetFormatW (infoPtr, 0);
 
 }
 
 
 static void
-DATETIME_ReturnTxt (DATETIME_INFO *infoPtr, int count, char *result, int resultSize)
+DATETIME_ReturnTxt (DATETIME_INFO *infoPtr, int count, LPWSTR result, int resultSize)
 {
- SYSTEMTIME date = infoPtr->date;
- int spec;
- char buffer[80];
-
- *result=0;
- TRACE ("%d,%d\n", infoPtr->nrFields, count);
- if ((count>infoPtr->nrFields) || (count<0)) {
+    static const WCHAR fmt_dW[] = { '%', 'd', 0 };
+    static const WCHAR fmt__2dW[] = { '%', '.', '2', 'd', 0 };
+    static const WCHAR fmt__3sW[] = { '%', '.', '3', 's', 0 };
+    SYSTEMTIME date = infoPtr->date;
+    int spec;
+    WCHAR buffer[80];
+
+    *result=0;
+    TRACE ("%d,%d\n", infoPtr->nrFields, count);
+    if (count>infoPtr->nrFields || count < 0) {
 	WARN ("buffer overrun, have %d want %d\n", infoPtr->nrFields, count);
 	return;
- }
+    }
 
- if (!infoPtr->fieldspec) return;
+    if (!infoPtr->fieldspec) return;
 
- spec=infoPtr->fieldspec[count];
- if (spec & DT_STRING) {
-	int txtlen=infoPtr->buflen[count];
+    spec = infoPtr->fieldspec[count];
+    if (spec & DT_STRING) {
+	int txtlen = infoPtr->buflen[count];
 
         if (txtlen > resultSize)
             txtlen = resultSize - 1;
-	memcpy (result, infoPtr->textbuf + (spec &~ DT_STRING), txtlen);
-	result[txtlen]=0;
-	TRACE ("arg%d=%x->[%s]\n",count,infoPtr->fieldspec[count],result);
+	memcpy (result, infoPtr->textbuf + (spec &~ DT_STRING), txtlen * sizeof(WCHAR));
+	result[txtlen] = 0;
+	TRACE ("arg%d=%x->[%s]\n", count, infoPtr->fieldspec[count], debugstr_w(result));
 	return;
- }
+    }
 
 
- switch (spec) {
+    switch (spec) {
 	case DT_END_FORMAT:
-		*result=0;
-		break;
+	    *result = 0;
+	    break;
 	case ONEDIGITDAY:
-		sprintf (result,"%d",date.wDay);
-	 	break;
+	    wsprintfW (result, fmt_dW, date.wDay);
+	    break;
 	case TWODIGITDAY:
-		sprintf (result,"%.2d",date.wDay);
-		break;
+	    wsprintfW (result, fmt__2dW, date.wDay);
+	    break;
 	case THREECHARDAY:
-	        GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1+(date.wDayOfWeek+6)%7,
-				result,4);
-		/*sprintf (result,"%.3s",days[date.wDayOfWeek]);*/
-		break;
+	    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SABBREVDAYNAME1+(date.wDayOfWeek+6)%7, result, 4);
+	    /*wsprintfW (result,"%.3s",days[date.wDayOfWeek]);*/
+	    break;
 	case FULLDAY:
-	        GetLocaleInfoA( LOCALE_USER_DEFAULT,LOCALE_SDAYNAME1+ (date.wDayOfWeek+6)%7,
-                               result, resultSize);
-		break;
+	    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDAYNAME1+(date.wDayOfWeek+6)%7, result, resultSize);
+	    break;
 	case ONEDIGIT12HOUR:
-		if (date.wHour>12)
-			sprintf (result,"%d",date.wHour-12);
-		else
-			sprintf (result,"%d",date.wHour);
-		break;
+	    wsprintfW (result, fmt_dW, date.wHour - (date.wHour > 12 ? 12 : 0));
+	    break;
 	case TWODIGIT12HOUR:
-		if (date.wHour>12)
-			sprintf (result,"%.2d",date.wHour-12);
-		else
-			sprintf (result,"%.2d",date.wHour);
-		break;
+	    wsprintfW (result, fmt__2dW, date.wHour - (date.wHour > 12 ? 12 : 0));
+	    break;
 	case ONEDIGIT24HOUR:
-		sprintf (result,"%d",date.wHour);
-		break;
+	    wsprintfW (result, fmt_dW, date.wHour);
+	    break;
 	case TWODIGIT24HOUR:
-		sprintf (result,"%.2d",date.wHour);
-		break;
+	    wsprintfW (result, fmt__2dW, date.wHour);
+	    break;
 	case ONEDIGITSECOND:
-		sprintf (result,"%d",date.wSecond);
-		break;
+	    wsprintfW (result, fmt_dW, date.wSecond);
+	    break;
 	case TWODIGITSECOND:
-		sprintf (result,"%.2d",date.wSecond);
-		break;
+	    wsprintfW (result, fmt__2dW, date.wSecond);
+	    break;
 	case ONEDIGITMINUTE:
-		sprintf (result,"%d",date.wMinute);
-		break;
+	    wsprintfW (result, fmt_dW, date.wMinute);
+	    break;
 	case TWODIGITMINUTE:
-		sprintf (result,"%.2d",date.wMinute);
-		break;
+	    wsprintfW (result, fmt__2dW, date.wMinute);
+	    break;
 	case ONEDIGITMONTH:
-		sprintf (result,"%d",date.wMonth);
-	 	break;
+	    wsprintfW (result, fmt_dW, date.wMonth);
+	    break;
 	case TWODIGITMONTH:
-		sprintf (result,"%.2d",date.wMonth);
-		break;
+	    wsprintfW (result, fmt__2dW, date.wMonth);
+	    break;
 	case THREECHARMONTH:
-		GetLocaleInfoA( GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1,
-                               buffer,sizeof(buffer));
-		sprintf (result,"%.3s",buffer);
-		break;
+	    GetLocaleInfoW(GetSystemDefaultLCID(), LOCALE_SMONTHNAME1+date.wMonth -1, 
+			   buffer, sizeof(buffer)/sizeof(buffer[0]));
+	    wsprintfW (result, fmt__3sW, buffer);
+	    break;
 	case FULLMONTH:
-		GetLocaleInfoA( GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1,
-                               result, resultSize);
-		break;
+	    GetLocaleInfoW(GetSystemDefaultLCID(),LOCALE_SMONTHNAME1+date.wMonth -1,
+                           result, resultSize);
+	    break;
 	case ONELETTERAMPM:
-		if (date.wHour<12)
-			strcpy (result,"A");
-		else
-			strcpy (result,"P");
-		break;
+	    result[0] = (date.wHour < 12 ? 'A' : 'P');
+	    result[1] = 0;
+	    break;
 	case TWOLETTERAMPM:
-		if (date.wHour<12)
-			strcpy (result,"AM");
-		else
-			strcpy (result,"PM");
-		break;
+	    result[0] = (date.wHour < 12 ? 'A' : 'P');
+	    result[1] = 'M';
+	    result[2] = 0;
+	    break;
 	case FORMATCALLBACK:
-		FIXME ("Not implemented\n");
-		strcpy (result,"xxx");
-		break;
+	    FIXME ("Not implemented\n");
+	    result[0] = 'x';
+	    result[1] = 0;
+	    break;
 	case ONEDIGITYEAR:
-		sprintf (result,"%d",date.wYear-10* (int) floor(date.wYear/10));
-	 	break;
+	    wsprintfW (result, fmt_dW, date.wYear-10* (int) floor(date.wYear/10));
+	    break;
 	case TWODIGITYEAR:
-		sprintf (result,"%.2d",date.wYear-100* (int) floor(date.wYear/100));
-		break;
+	    wsprintfW (result, fmt__2dW, date.wYear-100* (int) floor(date.wYear/100));
+	    break;
         case INVALIDFULLYEAR:
 	case FULLYEAR:
-		sprintf (result,"%d",date.wYear);
-		break;
+	    wsprintfW (result, fmt_dW, date.wYear);
+	    break;
     }
 
-	TRACE ("arg%d=%x->[%s]\n",count,infoPtr->fieldspec[count],result);
+    TRACE ("arg%d=%x->[%s]\n", count, infoPtr->fieldspec[count], debugstr_w(result));
 }
 
 
@@ -755,13 +678,12 @@
 }
 
 
-static void DATETIME_Refresh (HWND hwnd, HDC hdc)
-
+static void 
+DATETIME_Refresh (DATETIME_INFO *infoPtr, HDC hdc)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
   int i,prevright;
   RECT *field;
-  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
+  DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
   RECT *rcDraw = &infoPtr->rcDraw;
   RECT *rcClient = &infoPtr->rcClient;
   RECT *calbutton = &infoPtr->calbutton;
@@ -778,12 +700,12 @@
   DeleteObject(hbr);
 
   if (infoPtr->dateValid) {
-    char txt[80];
+    WCHAR txt[80];
     HFONT oldFont;
     oldFont = SelectObject (hdc, infoPtr->hFont);
 
-    DATETIME_ReturnTxt (infoPtr, 0, txt, sizeof(txt));
-    GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
+    DATETIME_ReturnTxt (infoPtr, 0, txt, sizeof(txt)/sizeof(txt[0]));
+    GetTextExtentPoint32W (hdc, txt, strlenW(txt), &size);
     rcDraw->bottom = size.cy+2;
 
     if (dwStyle & DTS_SHOWNONE)
@@ -793,8 +715,8 @@
     prevright = checkbox->right;
 
     for (i=0; i<infoPtr->nrFields; i++) {
-      DATETIME_ReturnTxt (infoPtr, i, txt, sizeof(txt));
-      GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
+      DATETIME_ReturnTxt (infoPtr, i, txt, sizeof(txt)/sizeof(txt[0]));
+      GetTextExtentPoint32W (hdc, txt, strlenW(txt), &size);
       field = & infoPtr->fieldRect[i];
       field->left  = prevright;
       field->right = prevright+size.cx;
@@ -808,13 +730,13 @@
         oldBk = SetBkColor (hdc, GetSysColor(COLOR_ACTIVECAPTION));
         oldTextColor = SetTextColor (hdc, GetSysColor(COLOR_WINDOW));
         DeleteObject (hbr);
-        DrawTextA ( hdc, txt, strlen(txt), field,
+        DrawTextW ( hdc, txt, strlenW(txt), field,
               DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
         SetBkColor (hdc, oldBk);
 		SetTextColor (hdc, oldTextColor);
       }
       else
-        DrawTextA ( hdc, txt, strlen(txt), field,
+        DrawTextW ( hdc, txt, strlenW(txt), field,
                          DT_RIGHT | DT_VCENTER | DT_SINGLELINE );
     }
 
@@ -829,48 +751,34 @@
 }
 
 
-static LRESULT
-DATETIME_HitTest (HWND hwnd, DATETIME_INFO *infoPtr, POINT pt)
+static INT
+DATETIME_HitTest (DATETIME_INFO *infoPtr, POINT pt)
 {
-  int i, retval;
+    int i;
+
+    TRACE ("%ld, %ld\n", pt.x, pt.y);
 
-  TRACE ("%ld, %ld\n",pt.x,pt.y);
+    if (PtInRect (&infoPtr->calbutton, pt)) return DTHT_MCPOPUP;
+    if (PtInRect (&infoPtr->checkbox, pt)) return DTHT_CHECKBOX;
 
-  retval = DTHT_NONE;
-  if (PtInRect (&infoPtr->calbutton, pt))
-    {retval = DTHT_MCPOPUP; TRACE("Hit in calbutton(DTHT_MCPOPUP)\n"); goto done; }
-  if (PtInRect (&infoPtr->checkbox, pt))
-    {retval = DTHT_CHECKBOX; TRACE("Hit in checkbox(DTHT_CHECKBOX)\n"); goto done; }
-
-  for (i=0; i<infoPtr->nrFields; i++) {
-    if (PtInRect (&infoPtr->fieldRect[i], pt)) {
-      retval = i;
-      TRACE("Hit in date text in field %d\n", i);
-      break;
+    for (i=0; i < infoPtr->nrFields; i++) {
+        if (PtInRect (&infoPtr->fieldRect[i], pt)) return i;
     }
- }
 
-done:
-  return retval;
+    return DTHT_NONE;
 }
 
 
 static LRESULT
-DATETIME_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_LButtonDown (DATETIME_INFO *infoPtr, WORD wKey, POINTS pts)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-  int old, new;
-  POINT pt;
+  DWORD dwStyle = GetWindowLongW (infoPtr->hwndSelf, GWL_STYLE);
+  POINT pt = { pts.x, pts.y };
+  int old = infoPtr->select;
+  int new = DATETIME_HitTest (infoPtr, pt);
 
   TRACE ("\n");
 
-  old = infoPtr->select;
-  pt.x = (INT)LOWORD(lParam);
-  pt.y = (INT)HIWORD(lParam);
-
-  new = DATETIME_HitTest (hwnd, infoPtr, pt);
-
   /* FIXME: might be conditions where we don't want to update infoPtr->select */
   infoPtr->select = new;
 
@@ -891,7 +799,7 @@
       infoPtr->monthcal_pos.x = 8;
 
     infoPtr->monthcal_pos.y = infoPtr->rcClient.bottom;
-    ClientToScreen (hwnd, &(infoPtr->monthcal_pos));
+    ClientToScreen (infoPtr->hwndSelf, &(infoPtr->monthcal_pos));
     /* FIXME My Windoze has cx=about 200, but it probably depends on font size etc */
     SetWindowPos(infoPtr->hMonthCal, 0, infoPtr->monthcal_pos.x,
         infoPtr->monthcal_pos.y, 200, 150, 0);
@@ -902,133 +810,96 @@
       SYSTEMTIME *lprgSysTimeArray = &infoPtr->date;
       TRACE("update calendar %04d/%02d/%02d\n", 
         lprgSysTimeArray->wYear, lprgSysTimeArray->wMonth, lprgSysTimeArray->wDay);
-      SendMessageA(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
+      SendMessageW(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
       ShowWindow(infoPtr->hMonthCal, SW_SHOW);
     }
 
     TRACE ("dt:%p mc:%p mc parent:%p, desktop:%p\n",
-           hwnd, infoPtr->hMonthCal, infoPtr->hwndNotify, GetDesktopWindow ());
-    DATETIME_SendSimpleNotify (hwnd, DTN_DROPDOWN);
+           infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hwndNotify, GetDesktopWindow ());
+    DATETIME_SendSimpleNotify (infoPtr, DTN_DROPDOWN);
   }
 
-  InvalidateRect(hwnd, NULL, FALSE);
+  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
 
   return 0;
 }
 
 
 static LRESULT
-DATETIME_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_LButtonUp (DATETIME_INFO *infoPtr, WORD wKey, POINTS pts)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-  TRACE("\n");
-
-  if(infoPtr->bCalDepressed == TRUE) {
-    infoPtr->bCalDepressed = FALSE;
-    InvalidateRect(hwnd, &(infoPtr->calbutton), TRUE);
-  }
+    if(infoPtr->bCalDepressed == TRUE) {
+        infoPtr->bCalDepressed = FALSE;
+        InvalidateRect(infoPtr->hwndSelf, &(infoPtr->calbutton), TRUE);
+    }
 
-  return 0;
+    return 0;
 }
 
 
 static LRESULT
-DATETIME_Paint (HWND hwnd, WPARAM wParam)
+DATETIME_Paint (DATETIME_INFO *infoPtr, HDC hdc)
 {
-    HDC hdc;
-    PAINTSTRUCT ps;
-
-    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
-    DATETIME_Refresh (hwnd, hdc);
-    if(!wParam)
-    EndPaint (hwnd, &ps);
+    if (!hdc) {
+	PAINTSTRUCT ps;
+        hdc = BeginPaint (infoPtr->hwndSelf, &ps);
+        DATETIME_Refresh (infoPtr, hdc);
+        EndPaint (infoPtr->hwndSelf, &ps);
+    } else {
+        DATETIME_Refresh (infoPtr, hdc);
+    }
     return 0;
 }
 
 
 static LRESULT
-DATETIME_Button_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_Button_Command (DATETIME_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr(hwnd);
-
-    switch(HIWORD(wParam)) {
-    case BN_CLICKED:
-    {
-        DWORD state = SendMessageA((HWND)lParam, BM_GETCHECK, 0, 0);
-        if(state == BST_CHECKED)
-            infoPtr->dateValid = TRUE;
-        else
-            infoPtr->dateValid = FALSE;
-        InvalidateRect(hwnd, NULL, TRUE);
-        return 0;
-    }
-    default:
-        return 0;
+    if( HIWORD(wParam) == BN_CLICKED) {
+        DWORD state = SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0);
+        infoPtr->dateValid = (state == BST_CHECKED);
+        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
     }
+    return 0;
 }
           
         
         
 static LRESULT
-DATETIME_Command (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_Command (DATETIME_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
-    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr(hwnd);
-
-    TRACE("%08x %08lx\n", wParam, lParam);
     TRACE("hwndbutton = %p\n", infoPtr->hwndCheckbut);
     if(infoPtr->hwndCheckbut == (HWND)lParam)
-        return DATETIME_Button_Command(hwnd, wParam, lParam);
+        return DATETIME_Button_Command(infoPtr, wParam, lParam);
     return 0;
 }
 
-static LRESULT
-DATETIME_ParentNotify (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
- DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
- LPNMHDR lpnmh = (LPNMHDR) lParam;
-
- TRACE ("%x,%lx\n",wParam, lParam);
- TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom);
- TRACE ("info: %p %p %p\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
- return 0;
-}
-
 
 static LRESULT
-DATETIME_Notify (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
+DATETIME_Notify (DATETIME_INFO *infoPtr, int idCtrl, LPNMHDR lpnmh)
 {
- DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
- LPNMHDR lpnmh = (LPNMHDR) lParam;
+    TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom);
+    TRACE ("info: %p %p %p\n", infoPtr->hwndSelf, infoPtr->hMonthCal, infoPtr->hUpdown);
 
- TRACE ("%x,%lx\n",wParam, lParam);
- TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom);
- TRACE ("info: %p %p %p\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
-
- if (lpnmh->code==MCN_SELECT) {
-   ShowWindow(infoPtr->hMonthCal, SW_HIDE);
-   infoPtr->dateValid = TRUE;
-   SendMessageA (infoPtr->hMonthCal, MCM_GETCURSEL, 0, (LPARAM)&infoPtr->date);
-   TRACE("got from calendar %04d/%02d/%02d\n", 
-      infoPtr->date.wYear, infoPtr->date.wMonth, infoPtr->date.wDay);
-   SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
-   InvalidateRect(hwnd, NULL, TRUE);
-   DATETIME_SendDateTimeChangeNotify (hwnd);
- }
- return 0;
+    if (lpnmh->code == MCN_SELECT) {
+        ShowWindow(infoPtr->hMonthCal, SW_HIDE);
+        infoPtr->dateValid = TRUE;
+        SendMessageW (infoPtr->hMonthCal, MCM_GETCURSEL, 0, (LPARAM)&infoPtr->date);
+        TRACE("got from calendar %04d/%02d/%02d\n", 
+        infoPtr->date.wYear, infoPtr->date.wMonth, infoPtr->date.wDay);
+        SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
+        InvalidateRect(infoPtr->hwndSelf, NULL, TRUE);
+        DATETIME_SendDateTimeChangeNotify (infoPtr);
+    }
+    return 0;
 }
 
 
 static LRESULT
-DATETIME_KeyDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_KeyDown (DATETIME_INFO *infoPtr, DWORD vkCode, LPARAM flags)
 {
- DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
- int FieldNum,wrap=0;
-
- TRACE("%x %lx %x\n",wParam, lParam, infoPtr->select);
-
- FieldNum = infoPtr->select & DTHT_DATEFIELD;
+ int FieldNum = infoPtr->select & DTHT_DATEFIELD;
+ int wrap=0;
 
  if (!(infoPtr->haveFocus)) return 0;
  if ((FieldNum==0) && (infoPtr->select)) return 0;
@@ -1037,24 +908,24 @@
 	FIXME ("Callbacks not implemented yet\n");
  }
 
- switch (wParam) {
+ switch (vkCode) {
 	case VK_ADD:
     	case VK_UP:
 		DATETIME_IncreaseField (infoPtr,FieldNum);
-		DATETIME_SendDateTimeChangeNotify (hwnd);
+		DATETIME_SendDateTimeChangeNotify (infoPtr);
 		break;
 	case VK_SUBTRACT:
 	case VK_DOWN:
 		DATETIME_DecreaseField (infoPtr,FieldNum);
-		DATETIME_SendDateTimeChangeNotify (hwnd);
+		DATETIME_SendDateTimeChangeNotify (infoPtr);
 		break;
 	case VK_HOME:
 		DATETIME_ResetFieldDown (infoPtr,FieldNum);
-		DATETIME_SendDateTimeChangeNotify (hwnd);
+		DATETIME_SendDateTimeChangeNotify (infoPtr);
 		break;
 	case VK_END:
 		DATETIME_ResetFieldUp(infoPtr,FieldNum);
-		DATETIME_SendDateTimeChangeNotify (hwnd);
+		DATETIME_SendDateTimeChangeNotify (infoPtr);
 		break;
 	case VK_LEFT:
 		do {
@@ -1078,95 +949,80 @@
 		break;
 	}
 
-  InvalidateRect(hwnd, NULL, FALSE);
+  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
 
   return 0;
 }
 
 
 static LRESULT
-DATETIME_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_KillFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
 {
-    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-    TRACE ("\n");
-
     if (infoPtr->haveFocus) {
-	DATETIME_SendSimpleNotify (hwnd, NM_KILLFOCUS);
+	DATETIME_SendSimpleNotify (infoPtr, NM_KILLFOCUS);
 	infoPtr->haveFocus = 0;
     }
 
-    InvalidateRect (hwnd, NULL, TRUE);
+    InvalidateRect (infoPtr->hwndSelf, NULL, TRUE);
 
     return 0;
 }
 
 
 static LRESULT
-DATETIME_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_SetFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
 {
-    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-    TRACE ("\n");
-
-    if (infoPtr->haveFocus==0) {
-	DATETIME_SendSimpleNotify (hwnd, NM_SETFOCUS);
+    if (infoPtr->haveFocus == 0) {
+	DATETIME_SendSimpleNotify (infoPtr, NM_SETFOCUS);
 	infoPtr->haveFocus = DTHT_GOTFOCUS;
     }
 
-    InvalidateRect(hwnd, NULL, FALSE);
+    InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
 
     return 0;
 }
 
 
 static BOOL
-DATETIME_SendDateTimeChangeNotify (HWND hwnd)
-
+DATETIME_SendDateTimeChangeNotify (DATETIME_INFO *infoPtr)
 {
- DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
- NMDATETIMECHANGE dtdtc;
+    DWORD dwStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
+    NMDATETIMECHANGE dtdtc;
 
- TRACE ("\n");
- dtdtc.nmhdr.hwndFrom = hwnd;
- dtdtc.nmhdr.idFrom   = GetWindowLongPtrW(hwnd, GWLP_ID);
- dtdtc.nmhdr.code     = DTN_DATETIMECHANGE;
+    dtdtc.nmhdr.hwndFrom = infoPtr->hwndSelf;
+    dtdtc.nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
+    dtdtc.nmhdr.code     = DTN_DATETIMECHANGE;
 
- if ((GetWindowLongA (hwnd, GWL_STYLE) & DTS_SHOWNONE))
-   dtdtc.dwFlags = GDT_NONE;
- else
-   dtdtc.dwFlags = GDT_VALID;
+    dtdtc.dwFlags = (dwStyle & DTS_SHOWNONE) ? GDT_NONE : GDT_VALID;
 
- MONTHCAL_CopyTime (&infoPtr->date, &dtdtc.st);
- return (BOOL) SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
-                              (WPARAM)dtdtc.nmhdr.idFrom, (LPARAM)&dtdtc);
+    MONTHCAL_CopyTime (&infoPtr->date, &dtdtc.st);
+    return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
+                                (WPARAM)dtdtc.nmhdr.idFrom, (LPARAM)&dtdtc);
 }
 
 
 static BOOL
-DATETIME_SendSimpleNotify (HWND hwnd, UINT code)
+DATETIME_SendSimpleNotify (DATETIME_INFO *infoPtr, UINT code)
 {
-    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
     NMHDR nmhdr;
 
-    TRACE("%x\n",code);
-    nmhdr.hwndFrom = hwnd;
-    nmhdr.idFrom   = GetWindowLongPtrW(hwnd, GWLP_ID);
+    TRACE("%x\n", code);
+    nmhdr.hwndFrom = infoPtr->hwndSelf;
+    nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
     nmhdr.code     = code;
 
-    return (BOOL) SendMessageA (infoPtr->hwndNotify, WM_NOTIFY,
+    return (BOOL) SendMessageW (infoPtr->hwndNotify, WM_NOTIFY,
                                 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
 }
 
 static LRESULT
-DATETIME_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_Size (DATETIME_INFO *infoPtr, WORD flags, INT width, INT height)
 {
-  DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr(hwnd);
-  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
+  DWORD dwStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
 
   /* set size */
-  infoPtr->rcClient.bottom = HIWORD(lParam);
-  infoPtr->rcClient.right = LOWORD(lParam);
+  infoPtr->rcClient.bottom = height;
+  infoPtr->rcClient.right = width;
 
   TRACE("Height=%ld, Width=%ld\n", infoPtr->rcClient.bottom, infoPtr->rcClient.right);
 
@@ -1197,40 +1053,38 @@
     infoPtr->monthcal_pos.x = 8;
 
   infoPtr->monthcal_pos.y = infoPtr->rcClient.bottom;
-  ClientToScreen (hwnd, &(infoPtr->monthcal_pos));
+  ClientToScreen (infoPtr->hwndSelf, &(infoPtr->monthcal_pos));
   SetWindowPos(infoPtr->hMonthCal, 0, infoPtr->monthcal_pos.x,
     infoPtr->monthcal_pos.y,
     145, 150, 0);
 
-  InvalidateRect(hwnd, NULL, FALSE);
+  InvalidateRect(infoPtr->hwndSelf, NULL, FALSE);
 
   return 0;
 }
 
 
 static LRESULT
-DATETIME_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_Create (HWND hwnd, LPCREATESTRUCTW lpcs)
 {
+  static const WCHAR buttonW[] = { 'b', 'u', 't', 't', 'o', 'n', 0 };
+  static const WCHAR SysMonthCal32W[] = { 'S', 'y', 's', 'M', 'o', 'n', 't', 'h', 'C', 'a', 'l', '3', '2', 0 };
   DATETIME_INFO *infoPtr;
-  DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
+  DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
 
   /* allocate memory for info structure */
-  TRACE("%04x %08lx\n",wParam,lParam);
   infoPtr = (DATETIME_INFO *)Alloc (sizeof(DATETIME_INFO));
-  if (infoPtr == NULL) {
-    ERR("could not allocate info memory!\n");
-    return 0;
-  }
+  if (!infoPtr) return -1;
 
-  SetWindowLongPtrA (hwnd, 0, (DWORD_PTR)infoPtr);
+  infoPtr->hwndSelf = hwnd;
 
   if (dwStyle & DTS_SHOWNONE) {
-    infoPtr->hwndCheckbut=CreateWindowExA (0,"button", 0,
+    infoPtr->hwndCheckbut=CreateWindowExW (0, buttonW, 0,
          WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
          2,2,13,13,
          hwnd,
          0, (HINSTANCE)GetWindowLongPtrW (hwnd, GWLP_HINSTANCE), 0);
-         SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0);
+         SendMessageW (infoPtr->hwndCheckbut, BM_SETCHECK, 1, 0);
   }
 
   if (dwStyle & DTS_UPDOWN) {
@@ -1241,16 +1095,16 @@
         UD_MAXVAL, UD_MINVAL, 0);
   }
 
-  infoPtr->fieldspec = (int *) Alloc (32*sizeof(int));
-  infoPtr->fieldRect = (RECT *) Alloc (32*sizeof(RECT));
-  infoPtr->buflen = (int *) Alloc (32*sizeof(int));
   infoPtr->nrFieldsAllocated = 32;
-  infoPtr->hwndNotify = ((LPCREATESTRUCTA)lParam)->hwndParent;
+  infoPtr->fieldspec = (int *) Alloc (infoPtr->nrFieldsAllocated * sizeof(int));
+  infoPtr->fieldRect = (RECT *) Alloc (infoPtr->nrFieldsAllocated * sizeof(RECT));
+  infoPtr->buflen = (int *) Alloc (infoPtr->nrFieldsAllocated * sizeof(int));
+  infoPtr->hwndNotify = lpcs->hwndParent;
 
-  DATETIME_SetFormat (hwnd, 0, 0);
+  DATETIME_SetFormatW (infoPtr, 0);
 
   /* create the monthcal control */
-    infoPtr->hMonthCal = CreateWindowExA (0,"SysMonthCal32", 0,
+    infoPtr->hMonthCal = CreateWindowExW (0, SysMonthCal32W, 0,
 	WS_BORDER | WS_POPUP | WS_CLIPSIBLINGS,
 	0, 0, 0, 0,
 	hwnd,
@@ -1260,24 +1114,20 @@
   GetSystemTime (&infoPtr->date);
   infoPtr->dateValid = TRUE;
   infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
+
+  SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
+
   return 0;
 }
 
 
 static LRESULT
-DATETIME_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
+DATETIME_Destroy (DATETIME_INFO *infoPtr)
 {
-    DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
-
-    TRACE("\n");
-    if (infoPtr->hMonthCal) {
-	/* FIXME I don't completely understand why doesn't it
-	 *   happen automatically, WS_POPUP maybe? */
+    if (infoPtr->hMonthCal) 
         DestroyWindow(infoPtr->hMonthCal);
-	infoPtr->hMonthCal = NULL;
-    }
+    SetWindowLongPtrW( infoPtr->hwndSelf, 0, 0 ); /* clear infoPtr */
     Free (infoPtr);
-    SetWindowLongPtrA( hwnd, 0, 0 ); /* clear infoPtr */
     return 0;
 }
 
@@ -1285,116 +1135,117 @@
 static LRESULT WINAPI
 DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    if (!DATETIME_GetInfoPtr(hwnd) && (uMsg != WM_CREATE))
-	return DefWindowProcA( hwnd, uMsg, wParam, lParam );
+    DATETIME_INFO *infoPtr = ((DATETIME_INFO *)GetWindowLongPtrW (hwnd, 0));
+
+    TRACE ("%x, %x, %lx\n", uMsg, wParam, lParam);
+
+    if (!infoPtr && (uMsg != WM_CREATE))
+	return DefWindowProcW( hwnd, uMsg, wParam, lParam );
 
     switch (uMsg)
     {
 
     case DTM_GETSYSTEMTIME:
-        return DATETIME_GetSystemTime (hwnd, wParam, lParam);
+        return DATETIME_GetSystemTime (infoPtr, (SYSTEMTIME *) lParam);
 
     case DTM_SETSYSTEMTIME:
-	return DATETIME_SetSystemTime (hwnd, wParam, lParam);
+	return DATETIME_SetSystemTime (infoPtr, wParam, (SYSTEMTIME *) lParam);
 
     case DTM_GETRANGE:
-        return DATETIME_GetRange(hwnd, lParam);
+        return DATETIME_GetRange(infoPtr, (SYSTEMTIME *) lParam);
 
     case DTM_SETRANGE:
-        return DATETIME_SetRange(hwnd, wParam, lParam);
+	return SendMessageW (infoPtr->hMonthCal, MCM_SETRANGE, wParam, lParam);
 
     case DTM_SETFORMATA:
-        return DATETIME_SetFormat (hwnd, wParam, lParam);
+        return DATETIME_SetFormatA (infoPtr, (LPCSTR)lParam);
 
     case DTM_SETFORMATW:
-        return DATETIME_SetFormatW (hwnd, wParam, lParam);
+        return DATETIME_SetFormatW (infoPtr, (LPCWSTR)lParam);
 
     case DTM_SETMCCOLOR:
-        return DATETIME_SetMonthCalColor (hwnd, wParam, lParam);
+	return SendMessageW (infoPtr->hMonthCal, MCM_SETCOLOR, wParam, lParam);
 
     case DTM_GETMCCOLOR:
-        return DATETIME_GetMonthCalColor (hwnd, wParam);
+        return SendMessageW (infoPtr->hMonthCal, MCM_GETCOLOR, wParam, 0);
 
     case DTM_GETMONTHCAL:
-        return DATETIME_GetMonthCal (hwnd);
+	return (LRESULT)infoPtr->hMonthCal;
 
     case DTM_SETMCFONT:
-        return DATETIME_SetMonthCalFont (hwnd, wParam, lParam);
+	FIXME("DTM_SETMCFONT: stub\n");
+	return 0;
 
     case DTM_GETMCFONT:
-        return DATETIME_GetMonthCalFont (hwnd);
-
-    case WM_PARENTNOTIFY:
-	return DATETIME_ParentNotify (hwnd, wParam, lParam);
+	FIXME("DTM_GETMCFONT: stub\n");
+	return 0;
 
     case WM_NOTIFY:
-	return DATETIME_Notify (hwnd, wParam, lParam);
+	return DATETIME_Notify (infoPtr, (int)wParam, (LPNMHDR)lParam);
 
     case WM_GETDLGCODE:
         return DLGC_WANTARROWS | DLGC_WANTCHARS;
 
     case WM_PAINT:
-        return DATETIME_Paint (hwnd, wParam);
+        return DATETIME_Paint (infoPtr, (HDC)wParam);
 
     case WM_KEYDOWN:
-        return DATETIME_KeyDown (hwnd, wParam, lParam);
+        return DATETIME_KeyDown (infoPtr, wParam, lParam);
 
     case WM_KILLFOCUS:
-        return DATETIME_KillFocus (hwnd, wParam, lParam);
+        return DATETIME_KillFocus (infoPtr, (HWND)wParam);
 
     case WM_SETFOCUS:
-        return DATETIME_SetFocus (hwnd, wParam, lParam);
+        return DATETIME_SetFocus (infoPtr, (HWND)wParam);
 
     case WM_SIZE:
-        return DATETIME_Size (hwnd, wParam, lParam);
+        return DATETIME_Size (infoPtr, wParam, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
 
     case WM_LBUTTONDOWN:
-        return DATETIME_LButtonDown (hwnd, wParam, lParam);
+        return DATETIME_LButtonDown (infoPtr, (WORD)wParam, MAKEPOINTS(lParam));
 
     case WM_LBUTTONUP:
-        return DATETIME_LButtonUp (hwnd, wParam, lParam);
+        return DATETIME_LButtonUp (infoPtr, (WORD)wParam, MAKEPOINTS(lParam));
 
     case WM_CREATE:
-	return DATETIME_Create (hwnd, wParam, lParam);
+	return DATETIME_Create (hwnd, (LPCREATESTRUCTW)lParam);
 
     case WM_DESTROY:
-	return DATETIME_Destroy (hwnd, wParam, lParam);
+	return DATETIME_Destroy (infoPtr);
 
     case WM_COMMAND:
-        return DATETIME_Command (hwnd, wParam, lParam);
+        return DATETIME_Command (infoPtr, wParam, lParam);
 
     default:
 	if ((uMsg >= WM_USER) && (uMsg < WM_APP))
 		ERR("unknown msg %04x wp=%08x lp=%08lx\n",
 		     uMsg, wParam, lParam);
-	return DefWindowProcA (hwnd, uMsg, wParam, lParam);
+	return DefWindowProcW (hwnd, uMsg, wParam, lParam);
     }
     return 0;
 }
 
 
-VOID
+void
 DATETIME_Register (void)
 {
-    WNDCLASSA wndClass;
+    WNDCLASSW wndClass;
 
-    TRACE("\n");
-    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
+    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
     wndClass.style         = CS_GLOBALCLASS;
     wndClass.lpfnWndProc   = (WNDPROC)DATETIME_WindowProc;
     wndClass.cbClsExtra    = 0;
     wndClass.cbWndExtra    = sizeof(DATETIME_INFO *);
-    wndClass.hCursor       = LoadCursorA (0, (LPSTR)IDC_ARROW);
+    wndClass.hCursor       = LoadCursorW (0, (LPCWSTR)IDC_ARROW);
     wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    wndClass.lpszClassName = DATETIMEPICK_CLASSA;
+    wndClass.lpszClassName = DATETIMEPICK_CLASSW;
 
-    RegisterClassA (&wndClass);
+    RegisterClassW (&wndClass);
 }
 
 
-VOID
+void
 DATETIME_Unregister (void)
 {
-    TRACE("\n");
-    UnregisterClassA (DATETIMEPICK_CLASSA, NULL);
+    UnregisterClassW (DATETIMEPICK_CLASSW, NULL);
 }



More information about the wine-patches mailing list