Index: trunk/src/comctl32/comctl32.c
===================================================================
--- trunk/src/comctl32/comctl32.c	(revision 2631)
+++ trunk/src/comctl32/comctl32.c	(revision 2635)
@@ -1,3 +1,3 @@
-/* $Id: comctl32.c,v 1.12 2000-01-26 18:04:29 cbratschi Exp $ */
+/* $Id: comctl32.c,v 1.13 2000-02-04 17:02:06 cbratschi Exp $ */
 /*
  * Win32 common controls implementation
@@ -12,5 +12,5 @@
  */
 
-/* WINE 990923 level (commctrl.c) */
+/* WINE 20000130 level (commctrl.c) */
 
 #include "comctl32.h"
@@ -837,2 +837,103 @@
 }
 
+static int iTrackMax = 0;
+static HWND TrackingList[10];
+static UINT timer;
+
+static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT idEvent, DWORD dwTime) {
+        int i = 0;
+        POINT pos;
+        HWND hwnd;
+        BOOL keepTracking = FALSE;
+        GetCursorPos(&pos);
+        hwnd = WindowFromPoint(pos);
+        /* Loop through the list of windows waiting on mouse exit */
+        while (i < iTrackMax) {
+                if (TrackingList[i] != hwnd)
+                        PostMessageA(TrackingList[i], WM_MOUSELEAVE, 0, 0);
+                else
+                        keepTracking = TRUE;
+
+
+                i++;
+        }
+
+        if (keepTracking) {
+                iTrackMax = 1;
+                TrackingList[0] = hwnd;
+        }
+        else
+                KillTimer(0, timer);
+}
+
+/***********************************************************************
+ * _TrackMouseEvent [COMCTL32.25]
+ *
+ * Requests notification of mouse events
+ *
+ * PARAMS
+ *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
+ *
+ * RETURNS
+ *     Success: non-zero
+ *     Failure: zero
+ *
+ */
+
+BOOL WINAPI
+_TrackMouseEvent (TRACKMOUSEEVENT *ptme)
+{
+    DWORD flags = 0;
+        int i;
+        BOOL cancel = 0, hover = 0, leave = 0, query = 0;
+        if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
+        //WARN("wrong TRACKMOUSEEVENT size from app");
+        return E_INVALIDARG;
+    }
+
+    //TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
+
+        flags = ptme->dwFlags;
+    if ( flags & TME_CANCEL ) {
+                cancel = 1;
+                flags &= ~ TME_CANCEL;
+        }
+    if ( flags & TME_HOVER  ) {
+                hover = 1;
+                flags &= ~ TME_HOVER;
+                //FIXME("TME_HOVER unimplemented\n" );
+        }
+    if ( flags & TME_LEAVE ) {
+                leave = 1;
+                flags &= ~ TME_LEAVE;
+        }
+    if ( flags & TME_QUERY ) {
+                query = 1;
+                flags &= ~ TME_QUERY;
+                //FIXME("TME_QUERY unimplemented\n" );
+        }
+
+        //if ( flags )
+        //      FIXME("Unknown flag(s) %ld\n", flags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_QUERY) );
+
+        if (leave) {
+                if (cancel) {
+                        for (i = 0; i < iTrackMax; i++)
+                                if (TrackingList[i] == ptme->hwndTrack)
+                                        TrackingList[i] = TrackingList[--iTrackMax];
+                }
+                else {
+                        if (iTrackMax == sizeof (TrackingList) / sizeof *TrackingList)
+                                return FALSE;
+
+                        /* Add hwndTrack to the track list */
+                        TrackingList[iTrackMax++] = ptme->hwndTrack;
+                        if (!timer)
+                                timer = SetTimer(0, 0, 50, TrackMouseEventProc);
+                }
+        }
+
+        return TRUE;
+}
+
+
Index: trunk/src/comctl32/comctl32undoc.c
===================================================================
--- trunk/src/comctl32/comctl32undoc.c	(revision 2631)
+++ trunk/src/comctl32/comctl32undoc.c	(revision 2635)
@@ -1,3 +1,3 @@
-/* $Id: comctl32undoc.c,v 1.16 1999-12-18 20:56:58 achimha Exp $ */
+/* $Id: comctl32undoc.c,v 1.17 2000-02-04 17:02:06 cbratschi Exp $ */
 /*
  * Undocumented functions from COMCTL32.DLL
@@ -12,5 +12,5 @@
  */
 
-/* WINE 991212 level */
+/* WINE 20000130 level */
 
 /* CB: todo
@@ -25,4 +25,7 @@
 #include <stdlib.h>
 #include <ctype.h>
+#include <wchar.h>
+#include <wcstr.h>
+#include <wctype.h>
 
 extern HANDLE COMCTL32_hHeap; /* handle to the private heap */
@@ -295,5 +298,5 @@
 HANDLE WINAPI
 CreateMRUListLazyA (LPCREATEMRULIST lpcml, DWORD dwParam2,
-		    DWORD dwParam3, DWORD dwParam4);
+                    DWORD dwParam3, DWORD dwParam4);
 
 
@@ -323,11 +326,11 @@
 FreeMRUListA (HANDLE hMRUList)
 {
-    FIXME("(%08x) empty stub!\n", hMRUList);
+    //FIXME("(%08x) empty stub!\n", hMRUList);
 
 #if 0
     if (!(hmru->dwParam1 & 1001)) {
-	RegSetValueExA (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
-			  hmru->lpszMRUString,
-			  lstrlenA (hmru->lpszMRUString));
+        RegSetValueExA (hmru->hKeyMRU, "MRUList", 0, REG_SZ,
+                          hmru->lpszMRUString,
+                          lstrlenA (hmru->lpszMRUString));
     }
 
@@ -343,5 +346,5 @@
 /**************************************************************************
  *              AddMRUData [COMCTL32.167]
- * 
+ *
  * Add item to MRU binary list.  If item already exists in list them it is
  * simply moved up to the top of the list and not added again.  If list is
@@ -360,5 +363,5 @@
 AddMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData)
 {
-    FIXME("(%08x, %p, %ld) empty stub!\n", hList, lpData, cbData);
+    //FIXME("(%08x, %p, %ld) empty stub!\n", hList, lpData, cbData);
 
     return 0;
@@ -367,5 +370,5 @@
 /**************************************************************************
  *              AddMRUStringA [COMCTL32.153]
- * 
+ *
  * Add item to MRU string list.  If item already exists in list them it is
  * simply moved up to the top of the list and not added again.  If list is
@@ -383,5 +386,5 @@
 AddMRUStringA(HANDLE hList, LPCSTR lpszString)
 {
-    FIXME("(%08x, %s) empty stub!\n", hList, debugstr_a(lpszString));
+    //FIXME("(%08x, %s) empty stub!\n", hList, debugstr_a(lpszString));
 
     return 0;
@@ -403,5 +406,5 @@
 DelMRUString(HANDLE hList, INT nItemPos)
 {
-    FIXME("(%08x, %d): stub\n", hList, nItemPos);
+    //FIXME("(%08x, %d): stub\n", hList, nItemPos);
     return TRUE;
 }
@@ -409,5 +412,5 @@
 /**************************************************************************
  *                  FindMRUData [COMCTL32.169]
- * 
+ *
  * Searches binary list for item that matches lpData of length cbData.
  * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
@@ -426,6 +429,6 @@
 FindMRUData (HANDLE hList, LPCVOID lpData, DWORD cbData, LPINT lpRegNum)
 {
-    FIXME("(%08x, %p, %ld, %p) empty stub!\n",
-	   hList, lpData, cbData, lpRegNum);
+    //FIXME("(%08x, %p, %ld, %p) empty stub!\n",
+    //       hList, lpData, cbData, lpRegNum);
 
     return 0;
@@ -434,5 +437,5 @@
 /**************************************************************************
  *                  FindMRUStringA [COMCTL32.155]
- * 
+ *
  * Searches string list for item that matches lpszString.
  * Returns position in list order 0 -> MRU and if lpRegNum != NULL then value
@@ -450,6 +453,6 @@
 FindMRUStringA (HANDLE hList, LPCSTR lpszString, LPINT lpRegNum)
 {
-    FIXME("(%08x, %s, %p) empty stub!\n", hList, debugstr_a(lpszString),
-	  lpRegNum);
+    //FIXME("(%08x, %s, %p) empty stub!\n", hList, debugstr_a(lpszString),
+    //      lpRegNum);
 
     return 0;
@@ -471,20 +474,20 @@
     LPVOID ptr;
 
-    FIXME("(%p) empty stub!\n", lpcml);
+    //FIXME("(%p) empty stub!\n", lpcml);
 
     if (lpcml == NULL)
-	return 0;
+        return 0;
 
     if (lpcml->cbSize < sizeof(CREATEMRULIST))
-	return 0;
-
-    FIXME("(%lu %lu %lx %lx \"%s\" %p)\n",
-	  lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags,
-	  (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare);
+        return 0;
+
+    //FIXME("(%lu %lu %lx %lx \"%s\" %p)\n",
+    //      lpcml->cbSize, lpcml->nMaxItems, lpcml->dwFlags,
+    //      (DWORD)lpcml->hKey, lpcml->lpszSubKey, lpcml->lpfnCompare);
 
     /* dummy pointer creation */
     ptr = COMCTL32_Alloc (32);
 
-    FIXME("-- ret = %p\n", ptr);
+    //FIXME("-- ret = %p\n", ptr);
 
     return (HANDLE)ptr;
@@ -493,5 +496,5 @@
 /**************************************************************************
  *                EnumMRUListA [COMCTL32.154]
- * 
+ *
  * Enumerate item in a list
  *
@@ -507,11 +510,11 @@
  *    of list returns -1.
  *    If lpBuffer == NULL or nItemPos is -ve return value is no. of items in
- *    the list. 
+ *    the list.
  */
 INT WINAPI EnumMRUListA(HANDLE hList, INT nItemPos, LPVOID lpBuffer,
 DWORD nBufferSize)
 {
-    FIXME("(%08x, %d, %p, %ld): stub\n", hList, nItemPos, lpBuffer,
-	  nBufferSize);
+    //FIXME("(%08x, %d, %p, %ld): stub\n", hList, nItemPos, lpBuffer,
+    //      nBufferSize);
     return 0;
 }
@@ -832,5 +835,5 @@
             /* resize the block of memory */
             nNewItems =
-		hdsa->nGrow * ((INT)(((nIndex + 1) - 1) / hdsa->nGrow) + 1);
+                hdsa->nGrow * ((INT)(((nIndex + 1) - 1) / hdsa->nGrow) + 1);
             nSize = hdsa->nItemSize * nNewItems;
 
@@ -1338,5 +1341,5 @@
             /* resize the block of memory */
             INT nNewItems =
-		hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1);
+                hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1);
             INT nSize = nNewItems * sizeof(LPVOID);
 
@@ -1477,6 +1480,6 @@
     v = lpPtrs[(int)(l+r)/2];
     do {
-	while ((pfnCompare)(lpPtrs[i], v, lParam) < 0) i++;
-	while ((pfnCompare)(lpPtrs[j], v, lParam) > 0) j--;
+        while ((pfnCompare)(lpPtrs[i], v, lParam) < 0) i++;
+        while ((pfnCompare)(lpPtrs[j], v, lParam) > 0) j--;
         if (i <= j)
         {
@@ -2017,5 +2020,5 @@
 
 /***********************************************************************
- *           ChrCmpA   
+ *           ChrCmpA
  * This fuction returns FALSE if both words match, TRUE otherwise...
  */
@@ -2039,8 +2042,8 @@
   if (!lpEnd) lpEnd = lpStart + strlen(lpStart);
 
-  for(; lpStart < lpEnd; lpStart = CharNextA(lpStart)) 
-    if (!ChrCmpA( GET_WORD(lpStart), wMatch)) 
+  for(; lpStart < lpEnd; lpStart = CharNextA(lpStart))
+    if (!ChrCmpA( GET_WORD(lpStart), wMatch))
       lpGotIt = lpStart;
-    
+
   return ((LPSTR)lpGotIt);
 
@@ -2049,5 +2052,5 @@
 
 /***********************************************************************
- *           ChrCmpW   
+ *           ChrCmpW
  * This fuction returns FALSE if both words match, TRUE otherwise...
  */
@@ -2067,8 +2070,8 @@
   if (!lpEnd) lpEnd = lpStart + lstrlenW(lpStart);
 
-  for(; lpStart < lpEnd; lpStart = CharNextW(lpStart)) 
-    if (!ChrCmpW( GET_WORD(lpStart), wMatch)) 
+  for(; lpStart < lpEnd; lpStart = CharNextW(lpStart))
+    if (!ChrCmpW( GET_WORD(lpStart), wMatch))
       lpGotIt = lpStart;
-    
+
   return (LPWSTR)lpGotIt;
 }
@@ -2119,5 +2122,5 @@
 BOOL WINAPI comctl32_410( HWND hw, DWORD b, DWORD c, DWORD d) {
 
-   FIXME("(%x, %lx, %lx, %lx): stub!\n", hw, b, c, d);
+   //FIXME("(%x, %lx, %lx, %lx): stub!\n", hw, b, c, d);
 
    return TRUE;
@@ -2133,5 +2136,5 @@
 BOOL WINAPI comctl32_411( HWND hw, DWORD b, DWORD c) {
 
-   FIXME("(%x, %lx, %lx): stub!\n", hw, b, c);
+   //FIXME("(%x, %lx, %lx): stub!\n", hw, b, c);
 
    return TRUE;
@@ -2147,11 +2150,11 @@
 BOOL WINAPI comctl32_412( HWND hwnd, DWORD b, DWORD c)
 {
-    FIXME("(%x, %lx, %lx): stub!\n", hwnd, b, c);
+    //FIXME("(%x, %lx, %lx): stub!\n", hwnd, b, c);
 
     if (IsWindow (hwnd) == FALSE)
-	return FALSE;
+        return FALSE;
 
     if (b == 0)
-	return FALSE;
+        return FALSE;
 
 
@@ -2168,5 +2171,5 @@
 BOOL WINAPI comctl32_413( HWND hw, DWORD b, DWORD c, DWORD d) {
 
-   FIXME("(%x, %lx, %lx, %lx): stub!\n", hw, b, c, d);
+   //FIXME("(%x, %lx, %lx, %lx): stub!\n", hw, b, c, d);
 
    return TRUE;
@@ -2182,5 +2185,5 @@
 BOOL WINAPI InitMUILanguage( LANGID uiLang) {
 
-   FIXME("(%04x): stub!\n", uiLang);
+   //FIXME("(%04x): stub!\n", uiLang);
 
    return TRUE;
Index: trunk/src/comctl32/datetime.c
===================================================================
--- trunk/src/comctl32/datetime.c	(revision 2631)
+++ trunk/src/comctl32/datetime.c	(revision 2635)
@@ -1,3 +1,3 @@
-/* $Id: datetime.c,v 1.6 1999-12-18 20:56:58 achimha Exp $ */
+/* $Id: datetime.c,v 1.7 2000-02-04 17:02:07 cbratschi Exp $ */
 /*
  * Date and time picker control
@@ -15,5 +15,5 @@
  */
 
-/* WINE 991212 level */
+/* WINE 20000130 level */
 
 #include "winbase.h"
Index: trunk/src/comctl32/imagelist.c
===================================================================
--- trunk/src/comctl32/imagelist.c	(revision 2631)
+++ trunk/src/comctl32/imagelist.c	(revision 2635)
@@ -1,8 +1,9 @@
-/* $Id: imagelist.c,v 1.10 1999-12-18 20:56:58 achimha Exp $ */
+/* $Id: imagelist.c,v 1.11 2000-02-04 17:02:07 cbratschi Exp $ */
 /*
  *  ImageList implementation
  *
  *  Copyright 1998 Eric Kohl
- * Copyright 1999 Achim Hasenmueller
+ *  Copyright 1999 Achim Hasenmueller
+ *  Copyright 2000 Christoph Bratschi
  *
  *  TODO:
@@ -10,5 +11,5 @@
  *    - Fix ImageList_GetIcon.
  *    - Fix drag functions.
- *    - Fix ImageList_Read and ImageList_Write.
+ *    - Fix ImageList_Write.
  *    - Fix ImageList_SetFilter (undocumented).
  *      BTW does anybody know anything about this function???
@@ -26,9 +27,8 @@
 
 /* CB: todo
-  - ImageList_Read
   - ImageList_Write
 */
 
-/* WINE 991212 level */
+/* WINE 20000130 level */
 
 /* This must be defined because the HIMAGELIST type is just a pointer
@@ -38,4 +38,7 @@
  */
 #define __WINE_IMAGELIST_C
+
+#include "wine/obj_base.h"
+#include "wine/obj_storage.h"
 
 #include "imagelist.h"
@@ -169,4 +172,5 @@
     HDC hImageDC;
     HBITMAP hOldBitmap;
+
     hImageDC = CreateCompatibleDC(0);
     hOldBitmap = SelectObject(hImageDC, pimldp->himl->hbmImage);
@@ -223,5 +227,5 @@
     */
     if( bUseCustomBackground && (pimldp->fStyle == ILD_NORMAL
-          || pimldp->fStyle & ILD_IMAGE
+          || (pimldp->fStyle & ILD_IMAGE)
           || bBlendFlag))
     {
@@ -238,5 +242,5 @@
     */
     if(pimldp->fStyle == ILD_NORMAL
-        || pimldp->fStyle & ILD_TRANSPARENT
+        || (pimldp->fStyle & ILD_TRANSPARENT)
         || ((pimldp->fStyle & ILD_IMAGE) && bUseCustomBackground)
         || bBlendFlag)
@@ -265,5 +269,5 @@
     /* Draw the image when no Background is specified
     */
-    else if(pimldp->fStyle & ILD_IMAGE && !bUseCustomBackground)
+    else if((pimldp->fStyle & ILD_IMAGE) && !bUseCustomBackground)
     {
         BitBlt(pimldp->hdcDst,
@@ -1339,4 +1343,7 @@
         DeleteDC (hdcDst);
         DeleteDC (hdcSrc);
+
+	himlDst->cCurImage = himlSrc->cCurImage;
+	himlDst->cMaxImage = himlSrc->cMaxImage;
     }
 
@@ -1888,4 +1895,111 @@
 
 
+/* helper for _read_bitmap currently unused */
+static int may_use_dibsection(HDC hdc) {
+    int bitspixel = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
+    if (bitspixel>8)
+	return TRUE;
+    if (bitspixel<=4)
+	return FALSE;
+    return GetDeviceCaps(hdc,94) & 0x10;
+}
+
+/* helper for ImageList_Read, see comments below */
+static HBITMAP _read_bitmap(LPSTREAM pstm,int ilcFlag,int cx,int cy) {
+    HDC			xdc = 0;
+    BITMAPFILEHEADER	bmfh;
+    BITMAPINFOHEADER	bmih;
+    int			bitsperpixel,palspace,longsperline,width,height;
+    LPBITMAPINFOHEADER	bmihc = NULL;
+    int			result = 0;
+    HBITMAP		hbitmap = 0;
+    LPBYTE		bits = NULL,nbits = NULL;
+    int			nbytesperline,bytesperline;
+
+    if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL))	||
+    	(bmfh.bfType != (('M'<<8)|'B'))					||
+    	!SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL))	||
+    	(bmih.biSize != sizeof(bmih))
+    )
+	return 0;
+
+    bitsperpixel = bmih.biPlanes * bmih.biBitCount;
+    if (bitsperpixel<=8)
+    	palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
+    else
+    	palspace = 0;
+    width = bmih.biWidth;
+    height = bmih.biHeight;
+    bmihc = (LPBITMAPINFOHEADER)LocalAlloc(LMEM_ZEROINIT,sizeof(bmih)+palspace);
+    memcpy(bmihc,&bmih,sizeof(bmih));
+    longsperline	= ((width*bitsperpixel+31)&~0x1f)>>5;
+    bmihc->biSizeImage	= (longsperline*height)<<2;
+
+    /* read the palette right after the end of the bitmapinfoheader */
+    if (palspace)
+	if (!SUCCEEDED(IStream_Read ( pstm, bmihc+1, palspace, NULL)))
+	    goto ret1;
+
+    xdc = GetDC(0);
+#if 0 /* Magic for NxM -> 1x(N*M) not implemented for DIB Sections */
+    if ((bitsperpixel>1) &&
+	((ilcFlag!=ILC_COLORDDB) && (!ilcFlag || may_use_dibsection(xdc)))
+     ) {
+	hbitmap = CreateDIBSection(xdc,(BITMAPINFO*)bmihc,0,(LPVOID*)&bits,0,0);
+	if (!hbitmap)
+	    goto ret1;
+	if (!SUCCEEDED(IStream_Read( pstm, bits, bmihc->biSizeImage, NULL)))
+	    goto ret1;
+	result = 1;
+    } else
+#endif
+    {
+	int i,nwidth,nheight;
+
+	nwidth	= width*(height/cy);
+	nheight	= cy;
+
+	if (bitsperpixel==1)
+	    hbitmap = CreateBitmap(nwidth,nheight,1,1,NULL);
+	else
+	    hbitmap = CreateCompatibleBitmap(xdc,nwidth,nheight);
+
+	/* Might be a bit excessive memory use here */
+	bits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage);
+	nbits = (LPBYTE)LocalAlloc(LMEM_ZEROINIT,bmihc->biSizeImage);
+	if (!SUCCEEDED(IStream_Read ( pstm, bits, bmihc->biSizeImage, NULL)))
+		goto ret1;
+
+	/* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
+	/* Do not forget that windows bitmaps are bottom->top */
+	bytesperline	= longsperline*4;
+	nbytesperline	= (height/cy)*bytesperline;
+	for (i=0;i<height;i++) {
+	    memcpy(
+		nbits+((height-i)%cy)*nbytesperline+(i/cy)*bytesperline,
+		bits+bytesperline*(height-i),
+		bytesperline
+	    );
+	}
+	bmihc->biWidth	= nwidth;
+	bmihc->biHeight	= nheight;
+	if (!SetDIBits(xdc,hbitmap,0,nheight,nbits,(BITMAPINFO*)bmihc,0))
+		goto ret1;
+	LocalFree((HLOCAL)nbits);
+	LocalFree((HLOCAL)bits);
+	result = 1;
+    }
+ret1:
+    if (xdc)	ReleaseDC(0,xdc);
+    if (bmihc)	LocalFree((HLOCAL)bmihc);
+    if (!result) {
+	if (hbitmap) {
+	    DeleteObject(hbitmap);
+	    hbitmap = 0;
+	}
+    }
+    return hbitmap;
+}
+
 /*************************************************************************
  * ImageList_Read [COMCTL32.66]
@@ -1900,33 +2014,85 @@
  *     Failure: NULL
  *
- * NOTES
- *     This function can not be implemented yet, because
- *     IStream32::Read is not implemented yet.
- *
- * BUGS
- *     empty stub.
- */
-
-//HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
-HIMAGELIST WINAPI ImageList_Read (PVOID pstm)
-{
-//    HRESULT errCode;
-//    ULONG ulRead;
-//    ILHEAD ilHead;
-//    HIMAGELIST himl;
-
-
-    dprintf(("ImageList_Read empty stub!\n"));
-
-//    errCode = IStream_Read (pstm, &ilHead, sizeof(ILHEAD), &ulRead);
-//    if (errCode != S_OK)
-//    return NULL;
-
-    FIXME("Magic: 0x%x\n", ilHead.usMagic);
-
-//    himl = ImageList_Create (32, 32, ILD_NORMAL, 2, 2);
-
-//    return himl;
-  return 0;
+ * The format is like this:
+ * 	ILHEAD 			ilheadstruct;
+ *
+ * for the color image part:
+ * 	BITMAPFILEHEADER	bmfh;
+ * 	BITMAPINFOHEADER	bmih;
+ * only if it has a palette:
+ *	RGBQUAD		rgbs[nr_of_paletted_colors];
+ *
+ *	BYTE			colorbits[imagesize];
+ *
+ * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
+ *	BITMAPFILEHEADER	bmfh_mask;
+ *	BITMAPINFOHEADER	bmih_mask;
+ * only if it has a palette (it usually does not):
+ *	RGBQUAD		rgbs[nr_of_paletted_colors];
+ *
+ *	BYTE			maskbits[imagesize];
+ *
+ * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect.
+ *         _read_bitmap needs to convert them.
+ */
+HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
+{
+    ILHEAD	ilHead;
+    HIMAGELIST	himl;
+    HBITMAP	hbmColor=0,hbmMask=0;
+    int		i;
+
+    if (!SUCCEEDED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
+    	return NULL;
+    if (ilHead.usMagic != (('L' << 8) | 'I'))
+	return NULL;
+    if (ilHead.usVersion != 0x101) /* probably version? */
+	return NULL;
+
+#if 0
+    FIXME("	ilHead.cCurImage = %d\n",ilHead.cCurImage);
+    FIXME("	ilHead.cMaxImage = %d\n",ilHead.cMaxImage);
+    FIXME("	ilHead.cGrow = %d\n",ilHead.cGrow);
+    FIXME("	ilHead.cx = %d\n",ilHead.cx);
+    FIXME("	ilHead.cy = %d\n",ilHead.cy);
+    FIXME("	ilHead.flags = %x\n",ilHead.flags);
+    FIXME("	ilHead.ovls[0] = %d\n",ilHead.ovls[0]);
+    FIXME("	ilHead.ovls[1] = %d\n",ilHead.ovls[1]);
+    FIXME("	ilHead.ovls[2] = %d\n",ilHead.ovls[2]);
+    FIXME("	ilHead.ovls[3] = %d\n",ilHead.ovls[3]);
+#endif
+
+    hbmColor = _read_bitmap(pstm,ilHead.flags & ~ILC_MASK,ilHead.cx,ilHead.cy);
+    if (!hbmColor)
+	return NULL;
+    if (ilHead.flags & ILC_MASK) {
+	hbmMask = _read_bitmap(pstm,0,ilHead.cx,ilHead.cy);
+	if (!hbmMask) {
+	    DeleteObject(hbmColor);
+	    return NULL;
+	}
+    }
+
+    himl = ImageList_Create (
+		    ilHead.cx,
+		    ilHead.cy,
+		    ilHead.flags,
+		    1,		/* initial */
+		    ilHead.cGrow
+    );
+    if (!himl) {
+	DeleteObject(hbmColor);
+	DeleteObject(hbmMask);
+	return NULL;
+    }
+    himl->hbmImage = hbmColor;
+    himl->hbmMask = hbmMask;
+    himl->cCurImage = ilHead.cCurImage;
+    himl->cMaxImage = ilHead.cMaxImage;
+
+    ImageList_SetBkColor(himl,ilHead.bkcolor);
+    for (i=0;i<4;i++)
+    	ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
+    return himl;
 }
 
@@ -2484,7 +2650,6 @@
     if ((iOverlay < 1) || (iOverlay > MAX_OVERLAYIMAGE))
         return FALSE;
-    if ((iImage < 0) || (iImage > himl->cCurImage))
-        return FALSE;
-
+    if ((iImage != -1) && ((iImage < 0) || (iImage > himl->cCurImage)))
+        return FALSE;
     himl->nOvlIdx[iOverlay - 1] = iImage;
     return TRUE;
Index: trunk/src/comctl32/listview.c
===================================================================
--- trunk/src/comctl32/listview.c	(revision 2631)
+++ trunk/src/comctl32/listview.c	(revision 2635)
@@ -1,3 +1,3 @@
-/*$Id: listview.c,v 1.20 1999-12-26 17:32:12 cbratschi Exp $*/
+/*$Id: listview.c,v 1.21 2000-02-04 17:02:07 cbratschi Exp $*/
 /*
  * Listview control
@@ -45,5 +45,5 @@
  */
 
-/* WINE 991212 level */
+/* WINE 20000130 level */
 
 #include <string.h>
@@ -59,5 +59,5 @@
 
 /* maximum size of a label */
-#define DISP_TEXT_SIZE 128
+#define DISP_TEXT_SIZE 512
 
 /* padding for items in list and small icon display modes */
@@ -105,4 +105,5 @@
  * forward declarations
  */
+static LRESULT LISTVIEW_GetItemA(HWND hwnd, LPLVITEMA lpLVItem, BOOL internal);
 static INT LISTVIEW_HitTestItem(HWND, LPLVHITTESTINFO);
 static INT LISTVIEW_GetCountPerRow(HWND);
@@ -1783,5 +1784,5 @@
   lvItem.cchTextMax = DISP_TEXT_SIZE;
   lvItem.pszText = szDispText;
-  ListView_GetItemA(hwnd, &lvItem);
+  LISTVIEW_GetItemA(hwnd,&lvItem,TRUE);
 
   /* set item colors */
@@ -1827,5 +1828,5 @@
   lvItem.cchTextMax = DISP_TEXT_SIZE;
   lvItem.pszText = szDispText;
-  ListView_GetItemA(hwnd, &lvItem);
+  LISTVIEW_GetItemA(hwnd,&lvItem,TRUE);
 
   /* state icons */
@@ -1948,5 +1949,5 @@
   lvItem.cchTextMax = DISP_TEXT_SIZE;
   lvItem.pszText = szDispText;
-  ListView_GetItemA(hwnd, &lvItem);
+  LISTVIEW_GetItemA(hwnd, &lvItem,TRUE);
 
   if (lvItem.state & LVIS_SELECTED)
@@ -2740,5 +2741,5 @@
  *   FAILURE : 0
  */
-static LRESULT LISTVIEW_GetEditControl(hwnd)
+static LRESULT LISTVIEW_GetEditControl(HWND hwnd)
 {
   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
@@ -3158,5 +3159,5 @@
         lvItem.iItem = nItem;
         lvItem.iSubItem = 0;
-        if (ListView_GetItemA(hwnd, &lvItem) != FALSE)
+        if (LISTVIEW_GetItemA(hwnd, &lvItem,TRUE) != FALSE)
         {
           if (lvItem.mask & LVIF_TEXT)
@@ -3529,4 +3530,6 @@
  * [I] HWND : window handle
  * [IO] LPLVITEMA : item info
+ * [I] internal : if true then we will use tricks that avoid copies
+ *               but are not compatible with the regular interface
  *
  * RETURN:
@@ -3534,189 +3537,129 @@
  *   FAILURE : FALSE
  */
-static LRESULT LISTVIEW_GetItemA(HWND hwnd, LPLVITEMA lpLVItem)
+static LRESULT LISTVIEW_GetItemA(HWND hwnd, LPLVITEMA lpLVItem, BOOL internal)
 {
   LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongA(hwnd, 0);
   LONG lCtrlId = GetWindowLongA(hwnd, GWL_ID);
-  BOOL bResult = FALSE;
   NMLVDISPINFOA dispInfo;
   LISTVIEW_SUBITEM *lpSubItem;
   LISTVIEW_ITEM *lpItem;
+  INT* piImage;
+  LPSTR* ppszText;
   HDPA hdpaSubItems;
 
-//  TRACE("(hwnd=%x, lpLVItem=%p)\n", hwnd, lpLVItem);
-
-  if (lpLVItem != NULL)
-  {
-    if ((lpLVItem->iItem >= 0) && (lpLVItem->iItem < GETITEMCOUNT(infoPtr)))
-    {
-      ZeroMemory(&dispInfo, sizeof(NMLVDISPINFOA));
-      hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
-      if (hdpaSubItems != NULL)
-      {
-        lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
-        if (lpItem != NULL)
-        {
-          bResult = TRUE;
-          if (lpLVItem->iSubItem == 0)
-          {
-            if ((lpItem->iImage == I_IMAGECALLBACK) &&
-                (lpLVItem->mask & LVIF_IMAGE))
-            {
-              dispInfo.item.mask |= LVIF_IMAGE;
-            }
-
-            if ((lpItem->pszText == LPSTR_TEXTCALLBACKA) &&
-                (lpLVItem->mask & LVIF_TEXT))
-            {
-              dispInfo.item.mask |= LVIF_TEXT;
-              ZeroMemory(lpLVItem->pszText, sizeof(CHAR)*lpLVItem->cchTextMax);
-              dispInfo.item.pszText = lpLVItem->pszText;
-              dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
-            }
-
-            if ((infoPtr->uCallbackMask != 0) && (lpLVItem->mask & LVIF_STATE))
-            {
-              dispInfo.item.mask |= LVIF_STATE;
-              dispInfo.item.stateMask = infoPtr->uCallbackMask;
-            }
-
-            if (dispInfo.item.mask != 0)
-            {
-              dispInfo.hdr.hwndFrom = hwnd;
-              dispInfo.hdr.idFrom = lCtrlId;
-              dispInfo.hdr.code = LVN_GETDISPINFOA;
-              dispInfo.item.iItem = lpLVItem->iItem;
-              dispInfo.item.iSubItem = 0;
-              dispInfo.item.lParam = lpItem->lParam;
-              ListView_Notify(GetParent(hwnd), lCtrlId, &dispInfo);
-            }
-
-            if (dispInfo.item.mask & LVIF_IMAGE)
-            {
-              lpLVItem->iImage = dispInfo.item.iImage;
-            }
-            else if (lpLVItem->mask & LVIF_IMAGE)
-            {
-              lpLVItem->iImage = lpItem->iImage;
-            }
-
-            if (dispInfo.item.mask & LVIF_TEXT)
-            {
-              if (dispInfo.item.mask & LVIF_DI_SETITEM)
-              {
-                Str_SetPtrA(&lpItem->pszText, dispInfo.item.pszText);
-              }
-              strncpy(lpLVItem->pszText, dispInfo.item.pszText, lpLVItem->cchTextMax);
-              lpLVItem->pszText[lpLVItem->cchTextMax-1]='\0';
-            }
-            else if (lpLVItem->mask & LVIF_TEXT)
-            {
-              strncpy(lpLVItem->pszText, lpItem->pszText, lpLVItem->cchTextMax);
-              lpLVItem->pszText[lpLVItem->cchTextMax-1]='\0';
-            }
-
-            if (dispInfo.item.mask & LVIF_STATE)
-            {
-              lpLVItem->state = lpItem->state;
-              lpLVItem->state &= ~dispInfo.item.stateMask;
-              lpLVItem->state |= (dispInfo.item.state &
-                                  dispInfo.item.stateMask);
-            }
-            else if (lpLVItem->mask & LVIF_STATE)
-            {
-              lpLVItem->state = lpItem->state & lpLVItem->stateMask;
-            }
-
-            if (lpLVItem->mask & LVIF_PARAM)
-            {
-              lpLVItem->lParam = lpItem->lParam;
-            }
-
-            if (lpLVItem->mask & LVIF_INDENT)
-            {
-              lpLVItem->iIndent = lpItem->iIndent;
-            }
-          }
-          else
-          {
-            lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems,
-                                               lpLVItem->iSubItem);
-            if (lpSubItem != NULL)
-            {
-              if ((lpSubItem->iImage == I_IMAGECALLBACK) &&
-                  (lpLVItem->mask & LVIF_IMAGE))
-              {
-                dispInfo.item.mask |= LVIF_IMAGE;
-              }
-
-              if ((lpSubItem->pszText == LPSTR_TEXTCALLBACKA) &&
-                  (lpLVItem->mask & LVIF_TEXT))
-              {
-                dispInfo.item.mask |= LVIF_TEXT;
-                ZeroMemory(lpLVItem->pszText,
-                           sizeof(CHAR)*lpLVItem->cchTextMax);
-                dispInfo.item.pszText = lpLVItem->pszText;
-                dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
-              }
-            }
-            else
-            {
-              if (lpLVItem->mask & LVIF_IMAGE)
-              {
-                dispInfo.item.mask |= LVIF_IMAGE;
-              }
-
-              if (lpLVItem->mask & LVIF_TEXT)
-              {
-                dispInfo.item.mask |= LVIF_TEXT;
-                ZeroMemory(lpLVItem->pszText,
-                           sizeof(CHAR)*lpLVItem->cchTextMax);
-                dispInfo.item.pszText = lpLVItem->pszText;
-                dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
-              }
-            }
-
-            if (dispInfo.item.mask != 0)
-            {
-              dispInfo.hdr.hwndFrom = hwnd;
-              dispInfo.hdr.idFrom = lCtrlId;
-              dispInfo.hdr.code = LVN_GETDISPINFOA;
-              dispInfo.item.iItem = lpLVItem->iItem;
-              dispInfo.item.iSubItem = lpLVItem->iSubItem;
-              dispInfo.item.lParam = lpItem->lParam;
-              ListView_Notify(GetParent(hwnd), lCtrlId, &dispInfo);
-            }
-
-            if (dispInfo.item.mask & LVIF_IMAGE)
-            {
-              lpLVItem->iImage = dispInfo.item.iImage;
-            }
-            else if (lpLVItem->mask & LVIF_IMAGE)
-            {
-              lpLVItem->iImage = lpItem->iImage;
-            }
-
-            if (dispInfo.item.mask & LVIF_TEXT)
-            {
-              if (dispInfo.item.mask & LVIF_DI_SETITEM)
-              {
-                if (lpSubItem)
-                   Str_SetPtrA(&lpSubItem->pszText, dispInfo.item.pszText);
-              }
-              strncpy(lpLVItem->pszText, dispInfo.item.pszText, lpLVItem->cchTextMax);
-              lpLVItem->pszText[lpLVItem->cchTextMax-1]='\0';
-            }
-            else if (lpLVItem->mask & LVIF_TEXT)
-            {
-              strncpy(lpLVItem->pszText, lpSubItem->pszText, lpLVItem->cchTextMax);
-              lpLVItem->pszText[lpLVItem->cchTextMax-1]='\0';
-            }
-          }
-        }
-      }
-    }
-  }
-
-  return bResult;
+  /* In the following:
+   * lpLVItem describes the information requested by the user
+   * lpItem/lpSubItem is what we have
+   * dispInfo is a structure we use to request the missing
+   *     information from the application
+   */
+
+  //TRACE("(hwnd=%x, lpLVItem=%p)\n", hwnd, lpLVItem);
+  if ((lpLVItem == NULL) ||
+      (lpLVItem->iItem < 0) ||
+      (lpLVItem->iItem >= GETITEMCOUNT(infoPtr))
+     )
+    return FALSE;
+  hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
+  if (hdpaSubItems == NULL)
+    return FALSE;
+  lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
+  if (lpItem == NULL)
+    return FALSE;
+  ZeroMemory(&dispInfo, sizeof(NMLVDISPINFOA));
+  if (lpLVItem->iSubItem == 0)
+  {
+    piImage=&lpItem->iImage;
+    ppszText=&lpItem->pszText;
+    if ((infoPtr->uCallbackMask != 0) && (lpLVItem->mask & LVIF_STATE))
+    {
+      dispInfo.item.mask |= LVIF_STATE;
+      dispInfo.item.stateMask = infoPtr->uCallbackMask;
+    }
+  }
+  else
+  {
+    lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, lpLVItem->iSubItem);
+    if (lpSubItem != NULL)
+    {
+      piImage=&lpItem->iImage;
+      ppszText=&lpItem->pszText;
+    }
+    else
+    {
+      piImage=NULL;
+      ppszText=NULL;
+    }
+  }
+  if ((lpLVItem->mask & LVIF_IMAGE) &&
+      ((piImage==NULL) || (*piImage == I_IMAGECALLBACK)))
+  {
+    dispInfo.item.mask |= LVIF_IMAGE;
+  }
+  if ((lpLVItem->mask & LVIF_TEXT) &&
+      ((ppszText==NULL) || (*ppszText == LPSTR_TEXTCALLBACKA)))
+  {
+    dispInfo.item.mask |= LVIF_TEXT;
+    dispInfo.item.pszText = lpLVItem->pszText;
+    dispInfo.item.cchTextMax = lpLVItem->cchTextMax;
+  }
+  if (dispInfo.item.mask != 0)
+  {
+    /* We don't have all the requested info, query the application */
+    dispInfo.hdr.hwndFrom = hwnd;
+    dispInfo.hdr.idFrom = lCtrlId;
+    dispInfo.hdr.code = LVN_GETDISPINFOA;
+    dispInfo.item.iItem = lpLVItem->iItem;
+    dispInfo.item.iSubItem = lpLVItem->iSubItem;
+    dispInfo.item.lParam = lpItem->lParam;
+    ListView_Notify(GetParent(hwnd), lCtrlId, &dispInfo);
+  }
+  if (dispInfo.item.mask & LVIF_IMAGE)
+  {
+    lpLVItem->iImage = dispInfo.item.iImage;
+  }
+  else if (lpLVItem->mask & LVIF_IMAGE)
+  {
+    lpLVItem->iImage = *piImage;
+  }
+  if (dispInfo.item.mask & LVIF_TEXT)
+  {
+    if ((dispInfo.item.mask & LVIF_DI_SETITEM) && (ppszText != NULL))
+    {
+      Str_SetPtrA(ppszText, dispInfo.item.pszText);
+    }
+    /* Here lpLVItem->pszText==dispInfo.item.pszText so a copy is unnecessary */
+  }
+  else if (lpLVItem->mask & LVIF_TEXT)
+  {
+    if (internal==TRUE)
+    {
+      lpLVItem->pszText=*ppszText;
+    } else {
+      lstrcpynA(lpLVItem->pszText, *ppszText, lpLVItem->cchTextMax);
+    }
+  }
+  if (lpLVItem->iSubItem == 0)
+  {
+    if (dispInfo.item.mask & LVIF_STATE)
+    {
+      lpLVItem->state = lpItem->state;
+      lpLVItem->state &= ~dispInfo.item.stateMask;
+      lpLVItem->state |= (dispInfo.item.state & dispInfo.item.stateMask);
+    }
+    else if (lpLVItem->mask & LVIF_STATE)
+    {
+      lpLVItem->state = lpItem->state & lpLVItem->stateMask;
+    }
+    if (lpLVItem->mask & LVIF_PARAM)
+    {
+      lpLVItem->lParam = lpItem->lParam;
+    }
+    if (lpLVItem->mask & LVIF_INDENT)
+    {
+      lpLVItem->iIndent = lpItem->iIndent;
+    }
+  }
+  return TRUE;
 }
 
@@ -4195,5 +4138,5 @@
   lvItem.cchTextMax = DISP_TEXT_SIZE;
   lvItem.pszText = szDispText;
-  if (ListView_GetItemA(hwnd, &lvItem) != FALSE)
+  if (LISTVIEW_GetItemA(hwnd, &lvItem,TRUE) != FALSE)
   {
     nLabelWidth = ListView_GetStringWidthA(hwnd, lvItem.pszText);
@@ -4256,5 +4199,5 @@
     lvItem.stateMask = uMask;
     lvItem.mask = LVIF_STATE;
-    if (ListView_GetItemA(hwnd, &lvItem) != FALSE)
+    if (LISTVIEW_GetItemA(hwnd, &lvItem,TRUE) != FALSE)
     {
       uState = lvItem.state;
@@ -4289,5 +4232,5 @@
       lpLVItem->mask = LVIF_TEXT;
       lpLVItem->iItem = nItem;
-      if (ListView_GetItemA(hwnd, lpLVItem) != FALSE)
+      if (LISTVIEW_GetItemA(hwnd, lpLVItem,FALSE) != FALSE)
       {
         nLength = lstrlenA(lpLVItem->pszText);
@@ -7064,5 +7007,5 @@
 
   case LVM_GETITEMA:
-    return LISTVIEW_GetItemA(hwnd, (LPLVITEMA)lParam);
+    return LISTVIEW_GetItemA(hwnd, (LPLVITEMA)lParam,FALSE);
 
 /*      case LVM_GETITEMW: */
Index: trunk/src/comctl32/monthcal.c
===================================================================
--- trunk/src/comctl32/monthcal.c	(revision 2631)
+++ trunk/src/comctl32/monthcal.c	(revision 2635)
@@ -1,10 +1,10 @@
-/* $Id: monthcal.c,v 1.6 1999-11-17 17:06:22 cbratschi Exp $ */
+/* $Id: */
 /* Month calendar control
-
-
  *
  * Copyright 1998, 1999 Eric Kohl (ekohl@abo.rhein-zeitung.de)
- * Copyright 1999  Alex Priem (alexp@sci.kun.nl)
- * Copyright 1999 Christoph Bratschi
+ * Copyright 1999 Alex Priem (alexp@sci.kun.nl)
+ * Copyright 1999 Chris Morgan <cmorgan@wpi.edu> and
+ *                James Abbatiello <abbeyj@wpi.edu>
+ * Copyright 2000 Christoph Bratschi
  *
  * TODO:
@@ -13,9 +13,10 @@
  *
  *  FIXME: refresh should ask for rect of required length. (?)
- *  FIXME: we refresh to often; especially in LButtonDown/MouseMove.
  *  FIXME: handle resources better (doesn't work now); also take care
            of internationalization.
  *  FIXME: keyboard handling.
  */
+
+/* WINE 20000130 level */
 
 #include "winbase.h"
@@ -35,46 +36,60 @@
  * defined here */
 
-#define MONTHCAL_GetInfoPtr(hwnd) ((MONTHCAL_INFO *)GetWindowLongA (hwnd, 0))
-
-/* helper functions
- * MONTHCAL_ValidateTime: is time a valid date/time combo?
- */
-
-int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
-
-int DayOfWeekTable[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
-
-static char *daytxt[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
-
-static char *monthtxt[] = {"January", "February", "March", "April", "May",
-                           "June", "July", "August", "September", "October",
-                           "November", "December"};
-
-/* CHECKME: all these validations OK? */
-
-static int MONTHCAL_ValidateTime (SYSTEMTIME time)
-
-{
- if (time.wMonth > 12) return FALSE;
- if (time.wDayOfWeek > 6) return FALSE;
- if (time.wDay > mdays[time.wMonth]) return FALSE;
- if (time.wMonth > 23) return FALSE;
- if (time.wMinute > 60) return FALSE;
- if (time.wSecond > 60) return FALSE;
- if (time.wMilliseconds > 100) return FALSE;
- return TRUE;
-}
-
-void MONTHCAL_CopyTime (const SYSTEMTIME *from, SYSTEMTIME *to)
-
-{
- to->wYear=from->wYear;
- to->wMonth=from->wMonth;
- to->wDayOfWeek=from->wDayOfWeek;
- to->wDay=from->wDay;
- to->wHour=from->wHour;
- to->wMinute=from->wMinute;
- to->wSecond=from->wSecond;
- to->wMilliseconds=from->wMilliseconds;
+static const int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0};
+
+const char * const monthtxt[] = {"January", "February", "March", "April", "May",
+                      "June", "July", "August", "September", "October",
+                      "November", "December"};
+const char * const daytxt[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+static const int DayOfWeekTable[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
+
+
+#define MONTHCAL_GetInfoPtr(hwnd) ((MONTHCAL_INFO *)GetWindowLongA(hwnd, 0))
+
+/* helper functions  */
+
+/* returns the number of days in any given month */
+/* january is 1, december is 12 */
+static int MONTHCAL_MonthLength(int month, int year)
+{
+  /* if we have a leap year add 1 day to February */
+  /* a leap year is a year either divisible by 400 */
+  /* or divisible by 4 and not by 100 */
+  if(month == 2) { /* February */
+    return mdays[month - 1] + ((year%400 == 0) ? 1 : ((year%100 != 0) &&
+     (year%4 == 0)) ? 1 : 0);
+  }
+  else {
+    return mdays[month - 1];
+  }
+}
+
+
+/* make sure that time is valid */
+static int MONTHCAL_ValidateTime(SYSTEMTIME time)
+{
+  if(time.wMonth > 12) return FALSE;
+  if(time.wDayOfWeek > 6) return FALSE;
+  if(time.wDay > MONTHCAL_MonthLength(time.wMonth, time.wYear))
+          return FALSE;
+  if(time.wHour > 23) return FALSE;
+  if(time.wMinute > 59) return FALSE;
+  if(time.wSecond > 59) return FALSE;
+  if(time.wMilliseconds > 999) return FALSE;
+
+  return TRUE;
+}
+
+
+void MONTHCAL_CopyTime(const SYSTEMTIME *from, SYSTEMTIME *to)
+{
+  to->wYear = from->wYear;
+  to->wMonth = from->wMonth;
+  to->wDayOfWeek = from->wDayOfWeek;
+  to->wDay = from->wDay;
+  to->wHour = from->wHour;
+  to->wMinute = from->wMinute;
+  to->wSecond = from->wSecond;
+  to->wMilliseconds = from->wMilliseconds;
 }
 
@@ -83,88 +98,102 @@
    Need to find out if we're on a DST place & adjust the clock accordingly.
    Above function assumes we have a valid data.
-   Valid for year>1752;  d <= 1 <= 31, 1 <= m <= 12.
-   0=Monday.
+   Valid for year>1752;  1 <= d <= 31, 1 <= m <= 12.
+   0 = Monday.
 */
 
-
-int MONTHCAL_CalculateDayOfWeek (DWORD day, DWORD month, DWORD year)
-
-{
- year -= month < 3;
- return (year + year/4 - year/100 + year/400 +
-         DayOfWeekTable[month-1] + day - 1 ) % 7;
-}
-
-
-static int MONTHCAL_CalcDayFromPos (MONTHCAL_INFO *infoPtr, int x, int y)
-
-{
-    int daypos,weekpos,retval,firstDay;
-
-    daypos=(x - infoPtr->prevmonth.left) / infoPtr->textWidth ;
-    weekpos=(y - infoPtr->days.bottom - infoPtr->rcClient.top) /
-                     (infoPtr->textHeight*1.25);
-        firstDay=MONTHCAL_CalculateDayOfWeek (1,infoPtr->currentMonth,infoPtr->currentYear);
-    retval=daypos + 7*weekpos - firstDay;
-        //TRACE ("%d %d %d\n",daypos,weekpos,retval);
-        return retval;
-}
-
-
-static void MONTHCAL_CalcDayXY (MONTHCAL_INFO *infoPtr, int day, int month,
+/* returns the day in the week(0 == sunday, 6 == saturday) */
+/* day(1 == 1st, 2 == 2nd... etc), year is the  year value */
+int MONTHCAL_CalculateDayOfWeek(DWORD day, DWORD month, DWORD year)
+{
+  year-=(month < 3);
+
+  return((year + year/4 - year/100 + year/400 +
+         DayOfWeekTable[month-1] + day - 1 ) % 7);
+}
+
+
+static int MONTHCAL_CalcDayFromPos(MONTHCAL_INFO *infoPtr, int x, int y)
+{
+  int daypos, weekpos, retval, firstDay;
+
+  /* if the point is outside the x bounds of the window put
+  it at the boundry */
+  if(x > (infoPtr->width_increment * 7.0)) {
+    x = infoPtr->rcClient.right - infoPtr->rcClient.left - infoPtr->left_offset;
+  }
+
+  daypos = (x -(infoPtr->prevmonth.left + infoPtr->left_offset)) / infoPtr->width_increment;
+  weekpos = (y - infoPtr->days.bottom - infoPtr->rcClient.top) / infoPtr->height_increment;
+
+  firstDay = MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear);
+  retval = daypos + (7 * weekpos) - firstDay;
+  //TRACE("%d %d %d\n", daypos, weekpos, retval);
+  return retval;
+}
+
+/* day is the day of the month, 1 == 1st day of the month */
+/* sets x and y to be the position of the day */
+/* x == day, y == week where(0,0) == sunday, 1st week */
+static void MONTHCAL_CalcDayXY(MONTHCAL_INFO *infoPtr, int day, int month,
                                  int *x, int *y)
-
-{
-  int firstDay,prevMonth;
-
-  firstDay=MONTHCAL_CalculateDayOfWeek (1,infoPtr->currentMonth,infoPtr->currentYear);
-
-  if (month==infoPtr->currentMonth) {
-        *x=(day+firstDay) & 7;
-        *y=(day+firstDay-*x) / 7;
-                return;
-        }
-  if (month < infoPtr->currentMonth) {
-                prevMonth=month - 1;
-                if (prevMonth==0) prevMonth=11;
-        *x=(mdays[prevMonth]-firstDay) & 7;
-                *y=0;
-        }
-
-  *y=mdays[month] / 7;
-  *x=(day+firstDay+mdays[month]) & 7;
-}
-
-
-static void MONTHCAL_CalcDayRect (MONTHCAL_INFO *infoPtr, RECT *r, int x, int y)
-{
-  r->left   = infoPtr->prevmonth.left + x * infoPtr->textWidth;
-  r->right  = r->left + infoPtr->textWidth;
-  r->top    = infoPtr->rcClient.top + y * 1.25 * infoPtr->textHeight
-                                   + infoPtr->days.bottom;
+{
+  int firstDay, prevMonth;
+
+  firstDay = MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear);
+
+  if(month==infoPtr->currentMonth) {
+    *x = (day + firstDay) % 7;
+    *y = (day + firstDay - *x) / 7;
+    return;
+  }
+  if(month < infoPtr->currentMonth) {
+    prevMonth = month - 1;
+    if(prevMonth==0)
+       prevMonth = 12;
+
+    *x = (MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) - firstDay) % 7;
+    *y = 0;
+    return;
+  }
+
+  *y = MONTHCAL_MonthLength(month, infoPtr->currentYear - 1) / 7;
+  *x = (day + firstDay + MONTHCAL_MonthLength(month,
+       infoPtr->currentYear)) % 7;
+}
+
+
+/* x: column(day), y: row(week) */
+static void MONTHCAL_CalcDayRect(MONTHCAL_INFO *infoPtr, RECT *r, int x, int y)
+{
+  r->left = infoPtr->prevmonth.left + x * infoPtr->width_increment + infoPtr->left_offset;
+  r->right = r->left + infoPtr->width_increment;
+  r->top = infoPtr->height_increment * y  + infoPtr->days.bottom + infoPtr->top_offset;
   r->bottom = r->top + infoPtr->textHeight;
-
-}
-
-static void MONTHCAL_CalcPosFromDay (MONTHCAL_INFO *infoPtr,
-                                            int day, int month, RECT *r)
-
-{
-  int x,y;
-
-  MONTHCAL_CalcDayXY (infoPtr, day, month, &x, &y);
-  MONTHCAL_CalcDayRect (infoPtr, r, x, y);
-}
-
-
-
-
-static void MONTHCAL_CircleDay (HDC hdc, MONTHCAL_INFO *infoPtr, int i, int j)
-
-{
-        HPEN hRedPen = CreatePen(PS_SOLID, 2, RGB (255,0,0) );
-    HPEN hOldPen2 = SelectObject( hdc, hRedPen );
-        POINT points[7];
-        int x,y;
+}
+
+
+/* sets the RECT struct r to the rectangle around the day and month */
+/* day is the day value of the month(1 == 1st), month is the month */
+/* value(january == 1, december == 12) */
+static void MONTHCAL_CalcPosFromDay(MONTHCAL_INFO *infoPtr,
+                                    int day, int month, RECT *r)
+{
+  int x, y;
+
+  MONTHCAL_CalcDayXY(infoPtr, day, month, &x, &y);
+  MONTHCAL_CalcDayRect(infoPtr, r, x, y);
+}
+
+
+/* day is the day in the month(1 == 1st of the month) */
+/* month is the month value(1 == january, 12 == december) */
+static void MONTHCAL_CircleDay(HDC hdc, MONTHCAL_INFO *infoPtr, int day,
+int month)
+{
+  HPEN hRedPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
+  HPEN hOldPen2 = SelectObject(hdc, hRedPen);
+  POINT points[13];
+  int x, y;
+  RECT day_rect;
 
  /* use prevmonth to calculate position because it contains the extra width
@@ -172,44 +201,58 @@
   */
 
-        x=infoPtr->prevmonth.left + (i+0.5)*infoPtr->textWidth;
-        y=infoPtr->rcClient.top + 1.25*(j+0.5)*infoPtr->textHeight + infoPtr->days.bottom;
-        points[0].x = x;
-        points[0].y = y-0.25*infoPtr->textHeight;
-        points[1].x = x-1.0*infoPtr->textWidth;
-        points[1].y = y;
-        points[2].x = x;
-        points[2].y = y+0.6*infoPtr->textHeight;
-        points[3].x = x+0.5*infoPtr->textWidth;
-        points[3].y = y;
-        points[4].x = x+0.3*infoPtr->textWidth;
-        points[4].y = y-0.5*infoPtr->textHeight;
-        points[5].x = x-0.25*infoPtr->textWidth;
-        points[5].y = y-0.5*infoPtr->textHeight;
-        points[6].x = x-0.5*infoPtr->textWidth;
-        points[6].y = y-0.45*infoPtr->textHeight;
-
-        PolyBezier (hdc,points,4);
-        PolyBezier (hdc,points+3,4);
-    DeleteObject (hRedPen);
-        SelectObject (hdc, hOldPen2);
-}
-
-
-
-
-
-static void MONTHCAL_DrawDay (HDC hdc, MONTHCAL_INFO *infoPtr,
+  MONTHCAL_CalcPosFromDay(infoPtr, day, month, &day_rect);
+
+  x = day_rect.left;
+  y = day_rect.top;
+
+  points[0].x = x;
+  points[0].y = y - 1;
+  points[1].x = x + 0.8 * infoPtr->width_increment;
+  points[1].y = y - 1;
+  points[2].x = x + 0.9 * infoPtr->width_increment;
+  points[2].y = y;
+  points[3].x = x + infoPtr->width_increment;
+  points[3].y = y + 0.5 * infoPtr->textHeight;
+
+  points[4].x = x + infoPtr->width_increment;
+  points[4].y = y + 0.9 * infoPtr->textHeight;
+  points[5].x = x + 0.6 * infoPtr->width_increment;
+  points[5].y = y + 0.9 * infoPtr->textHeight;
+  points[6].x = x + 0.5 * infoPtr->width_increment;
+  points[6].y = y + 0.9 * infoPtr->textHeight; /* bring the bottom up just
+                                a hair to fit inside the day rectangle */
+
+  points[7].x = x + 0.2 * infoPtr->width_increment;
+  points[7].y = y + 0.8 * infoPtr->textHeight;
+  points[8].x = x + 0.1 * infoPtr->width_increment;
+  points[8].y = y + 0.8 * infoPtr->textHeight;
+  points[9].x = x;
+  points[9].y = y + 0.5 * infoPtr->textHeight;
+
+  points[10].x = x + 0.1 * infoPtr->width_increment;
+  points[10].y = y + 0.2 * infoPtr->textHeight;
+  points[11].x = x + 0.2 * infoPtr->width_increment;
+  points[11].y = y + 0.3 * infoPtr->textHeight;
+  points[12].x = x + 0.5 * infoPtr->width_increment;
+  points[12].y = y + 0.3 * infoPtr->textHeight;
+
+  PolyBezier(hdc, points, 13);
+  DeleteObject(hRedPen);
+  SelectObject(hdc, hOldPen2);
+}
+
+
+static void MONTHCAL_DrawDay(HDC hdc, MONTHCAL_INFO *infoPtr,
                                                         int day, int month, int x, int y, int bold)
-
 {
   char buf[10];
   RECT r;
-  static int haveBoldFont,haveSelectedDay=FALSE;
+  static int haveBoldFont, haveSelectedDay = FALSE;
   HBRUSH hbr;
-  COLORREF oldCol,oldBk;
-
-  sprintf (buf,"%d",day);
-
-
+  HPEN hNewPen, hOldPen = 0;
+  COLORREF oldCol = 0;
+  COLORREF oldBk = 0;
+
+  sprintf(buf, "%d", day);
 
 /* No need to check styles: when selection is not valid, it is set to zero.
@@ -217,63 +260,56 @@
  */
 
-  MONTHCAL_CalcDayRect (infoPtr, &r, x, y);
-
-  if ((day>=infoPtr->minSel.wDay) && (day<=infoPtr->maxSel.wDay)
-      && (month==infoPtr->currentMonth)) {
-                HRGN hrgn;
-                RECT r2;
-
-                //TRACE ("%d %d %d\n",day,infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
-                //TRACE ("%d %d %d %d\n", r.left, r.top, r.right, r.bottom);
-                oldCol=SetTextColor (hdc, infoPtr->monthbk);
-                oldBk=SetBkColor (hdc,infoPtr->trailingtxt);
-                hbr= GetSysColorBrush (COLOR_GRAYTEXT);
-                hrgn=CreateEllipticRgn (r.left,r.top, r.right,r.bottom);
-                FillRgn (hdc,hrgn,hbr);
-
-                r2.left   = r.left-0.25*infoPtr->textWidth;
-                r2.top    = r.top;
-                r2.right  = r.left+0.5*infoPtr->textWidth;
-                r2.bottom = r.bottom;
-                if (haveSelectedDay) FillRect (hdc,&r2,hbr);
-                haveSelectedDay=TRUE;
-        } else {
-                haveSelectedDay=FALSE;
-        }
-
-
-
-/* need to add some code for multiple selections */
-
-  if ((bold) && (!haveBoldFont)) {
-        SelectObject (hdc, infoPtr->hBoldFont);
-                haveBoldFont=TRUE;
-        }
-  if ((!bold) && (haveBoldFont)) {
-        SelectObject (hdc, infoPtr->hFont);
-                haveBoldFont=FALSE;
-        }
-
-
-
-  DrawTextA ( hdc, buf, lstrlenA(buf), &r,
+  MONTHCAL_CalcDayRect(infoPtr, &r, x, y);
+
+  if((day>=infoPtr->minSel.wDay) && (day<=infoPtr->maxSel.wDay)
+       && (month==infoPtr->currentMonth)) {
+    HRGN hrgn;
+    RECT r2;
+
+    //TRACE("%d %d %d\n",day, infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
+    //TRACE("%d %d %d %d\n", r.left, r.top, r.right, r.bottom);
+    oldCol = SetTextColor(hdc, infoPtr->monthbk);
+    oldBk = SetBkColor(hdc, infoPtr->trailingtxt);
+    hbr = GetSysColorBrush(COLOR_GRAYTEXT);
+    hrgn = CreateEllipticRgn(r.left, r.top, r.right, r.bottom);
+    FillRgn(hdc, hrgn, hbr);
+
+    /* FIXME: this may need to be changed now b/c of the other
+        drawing changes 11/3/99 CMM */
+    r2.left   = r.left - 0.25 * infoPtr->textWidth;
+    r2.top    = r.top;
+    r2.right  = r.left + 0.5 * infoPtr->textWidth;
+    r2.bottom = r.bottom;
+    if(haveSelectedDay) FillRect(hdc, &r2, hbr);
+      haveSelectedDay = TRUE;
+  } else {
+    haveSelectedDay = FALSE;
+  }
+
+  /* need to add some code for multiple selections */
+
+  if((bold) &&(!haveBoldFont)) {
+    SelectObject(hdc, infoPtr->hBoldFont);
+    haveBoldFont = TRUE;
+  }
+  if((!bold) &&(haveBoldFont)) {
+    SelectObject(hdc, infoPtr->hFont);
+    haveBoldFont = FALSE;
+  }
+
+  if(haveSelectedDay) {
+    SetTextColor(hdc, oldCol);
+    SetBkColor(hdc, oldBk);
+  }
+
+  DrawTextA(hdc, buf, lstrlenA(buf), &r,
                          DT_CENTER | DT_VCENTER | DT_SINGLELINE );
-  if (haveSelectedDay) {
-                SetTextColor(hdc, oldCol);
-                SetBkColor (hdc, oldBk);
-        }
-
-  if ((day==infoPtr->curSelDay) && (month==infoPtr->currentMonth)) {
-                HPEN hNewPen, hOldPen;
-
-                hNewPen = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
-                hbr= GetSysColorBrush (COLOR_WINDOWTEXT);
-                hOldPen = SelectObject( hdc, hNewPen );
-                r.left+=2;
-                r.right-=2;
-                r.top-=1;
-                r.bottom+=1;
-                FrameRect (hdc, &r, hbr);
-                SelectObject( hdc, hOldPen );
+
+  /* draw a rectangle around the currently selected days text */
+  if((day==infoPtr->curSelDay) && (month==infoPtr->currentMonth)) {
+    hNewPen = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT) );
+    hbr = GetSysColorBrush(COLOR_WINDOWTEXT);
+    FrameRect(hdc, &r, hbr);
+    SelectObject(hdc, hOldPen);
   }
 }
@@ -281,214 +317,196 @@
 
 /* CHECKME: For `todays date', do we need to check the locale?*/
-/* CHECKME: For `todays date', how do is Y2K handled?*/
-/* FIXME:  todays date circle */
-
-static void MONTHCAL_Refresh (HWND hwnd, HDC hdc)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-        RECT *rcClient=&infoPtr->rcClient;
-        RECT *title=&infoPtr->title;
-        RECT *prev=&infoPtr->titlebtnprev;
-        RECT *next=&infoPtr->titlebtnnext;
-        RECT *titlemonth=&infoPtr->titlemonth;
-        RECT *titleyear=&infoPtr->titleyear;
-        RECT *prevmonth=&infoPtr->prevmonth;
-        RECT *nextmonth=&infoPtr->nextmonth;
-        RECT *days=&infoPtr->days;
-        RECT *weeknums=&infoPtr->weeknums;
-        RECT *rtoday=&infoPtr->today;
-    int i,j,m,mask,day,firstDay, weeknum,prevMonth;
-    int textHeight,textWidth;
-        SIZE size;
-        HBRUSH hbr;
-    HFONT currentFont;
-        TEXTMETRICA tm;
-/*    LOGFONTA logFont; */
-        char buf[20],*thisMonthtxt;
-    COLORREF oldTextColor,oldBkColor;
-    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-        BOOL prssed;
-
-
-    oldTextColor = SetTextColor(hdc, GetSysColor( COLOR_WINDOWTEXT));
-
-    currentFont = SelectObject (hdc, infoPtr->hFont);
-
-        /* FIXME: need a way to determine current font, without setting it */
-/*
-        if (infoPtr->hFont!=currentFont) {
-        SelectObject (hdc, currentFont);
-                infoPtr->hFont=currentFont;
-                GetObjectA (currentFont, sizeof (LOGFONTA), &logFont);
-        logFont.lfWeight=FW_BOLD;
-        infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
-        }
-*/
-
-        GetTextMetricsA (hdc, &tm);
-        infoPtr->textHeight=textHeight=tm.tmHeight + tm.tmExternalLeading;
-    GetTextExtentPoint32A (hdc, "Sun",3, &size);
-        infoPtr->textWidth=textWidth=size.cx+2;
-
-    GetClientRect (hwnd, rcClient);
-    hbr =  CreateSolidBrush (RGB(255,255,255));
-    DrawEdge (hdc, rcClient, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
-    FillRect (hdc, rcClient, hbr);
-    DeleteObject (hbr);
-
-/* calculate whole client area & title area */
-
-        infoPtr->rcClient.right=7*infoPtr->textWidth;
-        if (dwStyle & MCS_WEEKNUMBERS)
-          infoPtr->rcClient.right+=infoPtr->textWidth;
-
-        title->top    = rcClient->top + 1;
-        title->bottom = title->top + 2*textHeight + 4;
-        title->left   = rcClient->left + 1;
-        title->right  = rcClient->right - 1;
-        infoPtr->rcClient.bottom=title->bottom + 6*textHeight;
-
-
-/* draw header */
-
-    hbr =  CreateSolidBrush (infoPtr->titlebk);
-    FillRect (hdc, title, hbr);
-
-        prev->top                 = next->top        = title->top + 6;
-        prev->bottom      = next->bottom     = title->top + 2*textHeight - 3;
-        prev->right       = title->left  + 28;
-        prev->left        = title->left  + 4;
-        next->left        = title->right - 28;
-        next->right       = title->right - 4;
-        titlemonth->bottom= titleyear->bottom = prev->top + 2*textHeight - 3;
-        titlemonth->top   = titleyear->top    = title->top + 6;
-        titlemonth->left  = title->left;
-        titlemonth->right = title->right;
-        prssed=FALSE;
-
-        if (!(infoPtr->status & MC_PREVPRESSED))
-           DrawFrameControl(hdc, prev, DFC_SCROLL,
-                        DFCS_SCROLLLEFT | (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
-
-        if (!(infoPtr->status & MC_NEXTPRESSED))
-        DrawFrameControl(hdc, next, DFC_SCROLL,
-                DFCS_SCROLLRIGHT | (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
-
-    oldBkColor=SetBkColor (hdc,infoPtr->titlebk);
-    SetTextColor(hdc, infoPtr->titletxt);
-        SelectObject (hdc, infoPtr->hBoldFont);
-
-        thisMonthtxt=monthtxt[infoPtr->currentMonth - 1];
-        sprintf (buf,"%s %ld",thisMonthtxt,infoPtr->currentYear);
-    DrawTextA ( hdc, buf, strlen(buf), titlemonth,
-                        DT_CENTER | DT_VCENTER | DT_SINGLELINE );
-        SelectObject (hdc, infoPtr->hFont);
-
- /* titlemonth left/right contained rect for whole titletxt ('June  1999')
+static void MONTHCAL_Refresh(HWND hwnd, HDC hdc)
+{
+  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
+  RECT *rcClient=&infoPtr->rcClient;
+  RECT *rcDraw=&infoPtr->rcDraw;
+  RECT *title=&infoPtr->title;
+  RECT *prev=&infoPtr->titlebtnprev;
+  RECT *next=&infoPtr->titlebtnnext;
+  RECT *titlemonth=&infoPtr->titlemonth;
+  RECT *titleyear=&infoPtr->titleyear;
+  RECT *prevmonth=&infoPtr->prevmonth;
+  RECT *nextmonth=&infoPtr->nextmonth;
+  RECT dayrect;
+  RECT *days=&dayrect;
+  RECT *weeknums=&infoPtr->weeknums;
+  RECT *rtoday=&infoPtr->today;
+  int i, j, m, mask, day, firstDay, weeknum, prevMonth;
+  int textHeight = infoPtr->textHeight, textWidth = infoPtr->textWidth;
+  SIZE size;
+  HBRUSH hbr;
+  HFONT currentFont;
+  /* LOGFONTA logFont; */
+  char buf[20];
+  const char *thisMonthtxt;
+  COLORREF oldTextColor, oldBkColor;
+  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
+  BOOL prssed;
+
+  oldTextColor = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
+
+  /* draw control edge */
+  hbr =  CreateSolidBrush(RGB(255, 255, 255));
+  FillRect(hdc, rcClient, hbr);
+  DrawEdge(hdc, rcClient, EDGE_SUNKEN, BF_RECT);
+  DeleteObject(hbr);
+  prssed = FALSE;
+
+  /* draw header */
+  hbr =  CreateSolidBrush(infoPtr->titlebk);
+  FillRect(hdc, title, hbr);
+
+  /* if the previous button is pressed draw it depressed */
+  if((infoPtr->status & MC_PREVPRESSED))
+      DrawFrameControl(hdc, prev, DFC_SCROLL,
+           DFCS_SCROLLLEFT | DFCS_PUSHED |
+        (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
+  else /* if the previous button is pressed draw it depressed */
+    DrawFrameControl(hdc, prev, DFC_SCROLL,
+           DFCS_SCROLLLEFT |(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
+
+  /* if next button is depressed draw it depressed */
+  if((infoPtr->status & MC_NEXTPRESSED))
+    DrawFrameControl(hdc, next, DFC_SCROLL,
+           DFCS_SCROLLRIGHT | DFCS_PUSHED |
+        (dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
+  else /* if the next button is pressed draw it depressed */
+    DrawFrameControl(hdc, next, DFC_SCROLL,
+           DFCS_SCROLLRIGHT |(dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0));
+
+  oldBkColor = SetBkColor(hdc, infoPtr->titlebk);
+  SetTextColor(hdc, infoPtr->titletxt);
+  currentFont = SelectObject(hdc, infoPtr->hBoldFont);
+
+  /* titlemonth->left and right are set in MONTHCAL_UpdateSize */
+  titlemonth->left   = title->left;
+  titlemonth->right  = title->right;
+
+  thisMonthtxt = monthtxt[infoPtr->currentMonth - 1];
+  sprintf(buf, "%s %ld", thisMonthtxt, infoPtr->currentYear);
+  DrawTextA(hdc, buf, strlen(buf), titlemonth,
+                        DT_CENTER | DT_VCENTER | DT_SINGLELINE);
+  SelectObject(hdc, infoPtr->hFont);
+
+/* titlemonth left/right contained rect for whole titletxt('June  1999')
   * MCM_HitTestInfo wants month & year rects, so prepare these now.
-  * (no, we can't draw them separately; the whole text is centered)
+  *(no, we can't draw them separately; the whole text is centered)
   */
-
-    GetTextExtentPoint32A (hdc, buf,lstrlenA (buf), &size);
-        titlemonth->left = title->right/2 - size.cx/2;
-        titleyear->right = title->right/2 + size.cx/2;
-    GetTextExtentPoint32A (hdc, thisMonthtxt,lstrlenA (thisMonthtxt), &size);
-    titlemonth->right= titlemonth->left+size.cx;
-    titleyear->right = titlemonth->right;
+  GetTextExtentPoint32A(hdc, buf, lstrlenA(buf), &size);
+  titlemonth->left = title->right / 2 - size.cx / 2;
+  titleyear->right = title->right / 2 + size.cx / 2;
+  GetTextExtentPoint32A(hdc, thisMonthtxt, lstrlenA(thisMonthtxt), &size);
+  titlemonth->right = titlemonth->left + size.cx;
+  titleyear->right = titlemonth->right;
+
 
 /* draw line under day abbreviatons */
 
-         if (dwStyle & MCS_WEEKNUMBERS)
-                MoveToEx (hdc, rcClient->left+textWidth+3,
-                       title->bottom + textHeight + 2, NULL);
-         else
-                MoveToEx (hdc, rcClient->left+3, title->bottom + textHeight + 2, NULL);
-     LineTo   (hdc, rcClient->right-3, title->bottom + textHeight + 2);
+   if(dwStyle & MCS_WEEKNUMBERS)
+     MoveToEx(hdc, rcDraw->left + textWidth + 3, title->bottom + textHeight + 2, NULL);
+   else
+     MoveToEx(hdc, rcDraw->left + 3, title->bottom + textHeight + 2, NULL);
+
+  LineTo(hdc, rcDraw->right - 3, title->bottom + textHeight + 2);
 
 /* draw day abbreviations */
 
-    SetBkColor (hdc, infoPtr->monthbk);
-    SetTextColor(hdc, infoPtr->trailingtxt);
-
-        days->left   = rcClient->left;
-        if (dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
-    days->right  = days->left + textWidth;
-    days->top    = title->bottom + 2;
-    days->bottom = title->bottom + textHeight + 2;
-        i=infoPtr->firstDay;
-
-        for (j=0; j<7; j++) {
-            DrawTextA ( hdc, daytxt[i], strlen(daytxt[i]), days,
+  SetBkColor(hdc, infoPtr->monthbk);
+  SetTextColor(hdc, infoPtr->trailingtxt);
+
+  /* copy this rect so we can change the values without changing */
+  /* the original version */
+  days->left = infoPtr->days.left;
+  days->right = infoPtr->days.right;
+  days->top = infoPtr->days.top;
+  days->bottom = infoPtr->days.bottom;
+
+  i = infoPtr->firstDay;
+
+  for(j=0; j<7; j++) {
+    DrawTextA(hdc, daytxt[i], strlen(daytxt[i]), days,
                          DT_CENTER | DT_VCENTER | DT_SINGLELINE );
-                        i++;
-                        if (i>7) i-=7;
-                        days->left+=textWidth;
-                        days->right+=textWidth;
-        }
-
-        days->left   = rcClient->left + j;
-        if (dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
-    days->right  = rcClient->left + (j+1)*textWidth-2;
+    i = (i + 1) % 7;
+    days->left+=infoPtr->width_increment;
+    days->right+=infoPtr->width_increment;
+  }
+
+  days->left = rcDraw->left + j;
+  if(dwStyle & MCS_WEEKNUMBERS) days->left+=textWidth;
+  /* FIXME: this may need to be changed now 11/10/99 CMM */
+  days->right = rcDraw->left + (j+1) * textWidth - 2;
 
 /* draw day numbers; first, the previous month */
 
-        prevmonth->left=0;
-        if (dwStyle & MCS_WEEKNUMBERS) prevmonth->left=textWidth;
-
-        firstDay=MONTHCAL_CalculateDayOfWeek (1,infoPtr->currentMonth,infoPtr->currentYear);
-        prevMonth=infoPtr->currentMonth-1;
-        if (prevMonth==0) prevMonth=11;
-        day=mdays[prevMonth]-firstDay;
-        mask=1<<(day-1);
-
-        i=0;
-        m=0;
-        while (day<=mdays[prevMonth]) {
-                        MONTHCAL_DrawDay (hdc, infoPtr, day, prevMonth, i, 0,
-                                                infoPtr->monthdayState[m] & mask);
-                        mask<<=1;
-                        day++;
-                        i++;
-        }
-
-        prevmonth->right = prevmonth->left+i*textWidth;
-        prevmonth->top   = days->bottom;
-        prevmonth->bottom= prevmonth->top + textHeight;
+  firstDay = MONTHCAL_CalculateDayOfWeek(1, infoPtr->currentMonth, infoPtr->currentYear);
+
+  prevMonth = infoPtr->currentMonth - 1;
+  if(prevMonth == 0) /* if currentMonth is january(1) prevMonth is */
+    prevMonth = 12;    /* december(12) of the previous year */
+
+  day = MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear) - firstDay;
+  mask = 1<<(day-1);
+
+  i = 0;
+  m = 0;
+  while(day <= MONTHCAL_MonthLength(prevMonth, infoPtr->currentYear)) {
+    MONTHCAL_DrawDay(hdc, infoPtr, day, prevMonth, i, 0,
+          infoPtr->monthdayState[m] & mask);
+    mask<<=1;
+    day++;
+    i++;
+  }
+
+  prevmonth->left = 0;
+  if(dwStyle & MCS_WEEKNUMBERS) prevmonth->left = textWidth;
+  prevmonth->right  = prevmonth->left + i * textWidth;
+  prevmonth->top    = days->bottom;
+  prevmonth->bottom = prevmonth->top + textHeight;
 
 /* draw `current' month  */
 
-        day=1;
-        infoPtr->firstDayplace=i;
-    SetTextColor(hdc, infoPtr->txt);
-        m++;
-        mask=1;
-        while (i<7) {
-                        MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth, i, 0,
-                                                infoPtr->monthdayState[m] & mask);
-                        if ((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
-                (day==infoPtr->todaysDate.wDay))
-                                        MONTHCAL_CircleDay (hdc, infoPtr, i,j);
-                        mask<<=1;
-                        day++;
-                        i++;
-                }
-
-        j=1;
-        i=0;
-        while (day<=mdays[infoPtr->currentMonth]) {
-                        MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth, i, j,
-                                                infoPtr->monthdayState[m] & mask);
-                        if ((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
-                (day==infoPtr->todaysDate.wDay))
-                                        MONTHCAL_CircleDay (hdc, infoPtr, i,j);
-                        mask<<=1;
-                        day++;
-                        i++;
-                        if (i>6) {
-                                i=0;
-                                j++;
-                        }
-        }
+  day = 1; /* start at the beginning of the current month */
+
+  infoPtr->firstDayplace = i;
+  SetTextColor(hdc, infoPtr->txt);
+  m++;
+  mask = 1;
+
+  /* draw the first week of the current month */
+  while(i<7) {
+    MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth, i, 0,
+        infoPtr->monthdayState[m] & mask);
+
+    if((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
+        (day==infoPtr->todaysDate.wDay) &&
+        (infoPtr->currentYear == infoPtr->todaysDate.wYear)) {
+      MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth);
+    }
+
+    mask<<=1;
+    day++;
+    i++;
+  }
+
+  j = 1; /* move to the 2nd week of the current month */
+  i = 0; /* move back to sunday */
+  while(day <= MONTHCAL_MonthLength(infoPtr->currentMonth, infoPtr->currentYear)) {
+    MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth, i, j,
+          infoPtr->monthdayState[m] & mask);
+
+    if((infoPtr->currentMonth==infoPtr->todaysDate.wMonth) &&
+    (day==infoPtr->todaysDate.wDay) &&
+    (infoPtr->currentYear == infoPtr->todaysDate.wYear))
+      MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth);
+
+    mask<<=1;
+    day++;
+    i++;
+    if(i>6) { /* past saturday, goto the next weeks sunday */
+      i = 0;
+      j++;
+    }
+  }
 
 /*  draw `next' month */
@@ -499,250 +517,244 @@
  * this rect -- HitTest knows about this.*/
 
-
-
-        nextmonth->left   = prevmonth->left+i*textWidth;
-        nextmonth->right  = rcClient->right;
-        nextmonth->top    = days->bottom+(j+1)*textHeight;
-        nextmonth->bottom = nextmonth->top + textHeight;
-
-        day=1;
-        m++;
-        mask=1;
-    SetTextColor(hdc, infoPtr->trailingtxt);
-        while ((i<7) && (j<6)) {
-                        MONTHCAL_DrawDay (hdc, infoPtr, day, infoPtr->currentMonth+1, i, j,
-                                                infoPtr->monthdayState[m] & mask);
-                        mask<<=1;
-                        day++;
-                        i++;
-                        if (i==7) {
-                                i=0;
-                                j++;
-                        }
-        }
-    SetTextColor(hdc, infoPtr->txt);
-
+  nextmonth->left   = prevmonth->left + i * textWidth;
+  nextmonth->right  = rcDraw->right;
+  nextmonth->top    = days->bottom + (j+1) * textHeight;
+  nextmonth->bottom = nextmonth->top + textHeight;
+
+  day = 1; /* start at the first day of the next month */
+  m++;
+  mask = 1;
+
+  SetTextColor(hdc, infoPtr->trailingtxt);
+  while((i<7) &&(j<6)) {
+    MONTHCAL_DrawDay(hdc, infoPtr, day, infoPtr->currentMonth + 1, i, j,
+                infoPtr->monthdayState[m] & mask);
+
+    mask<<=1;
+    day++;
+    i++;
+    if(i==7) { /* past saturday, go to next week's sunday */
+      i = 0;
+      j++;
+    }
+  }
+  SetTextColor(hdc, infoPtr->txt);
 
 
 /* draw `today' date if style allows it, and draw a circle before today's
- * date if necessairy */
-
-        if (!( dwStyle & MCS_NOTODAY))  {
-        int offset=0;
-        if (!( dwStyle & MCS_NOTODAYCIRCLE))  {
-                        MONTHCAL_CircleDay (hdc, infoPtr, 0, 6);
-                        offset+=textWidth;
-                }
-
-                MONTHCAL_CalcDayRect (infoPtr, rtoday, offset==textWidth, 6);
-                sprintf (buf,"Today: %d/%d/%d",infoPtr->todaysDate.wMonth,
-                        infoPtr->todaysDate.wDay, infoPtr->todaysDate.wYear-1900);
-                rtoday->right  = rcClient->right;
-        SelectObject (hdc, infoPtr->hBoldFont);
-            DrawTextA ( hdc, buf, lstrlenA(buf), rtoday,
-                         DT_LEFT | DT_VCENTER | DT_SINGLELINE );
-        SelectObject (hdc, infoPtr->hFont);
-        }
-
-        if (dwStyle & MCS_WEEKNUMBERS)  {
-                        /* display weeknumbers*/
-
-                weeknums->left   = 0;
-                weeknums->right  = textWidth;
-                weeknums->top    = days->bottom + 2;
-                weeknums->bottom = days->bottom + 2 + textHeight;
-
-                weeknum=0;
-                for (i=0; i<infoPtr->currentMonth-1; i++)
-                        weeknum+=mdays[i];
-
-                weeknum/=7;
-                for (i=0; i<6; i++) {
-                        sprintf (buf,"%d",weeknum+i);
-                DrawTextA ( hdc, buf, lstrlenA(buf), weeknums,
+ * date if necessary */
+
+  if(!(dwStyle & MCS_NOTODAY))  {
+    int offset = 0;
+    if(!(dwStyle & MCS_NOTODAYCIRCLE))  {
+      MONTHCAL_CircleDay(hdc, infoPtr, day, infoPtr->currentMonth + 1);
+      offset+=textWidth;
+    }
+    MONTHCAL_CalcDayRect(infoPtr, rtoday, offset==textWidth, 6);
+    sprintf(buf, "Today: %d/%d/%d", infoPtr->todaysDate.wMonth,
+             infoPtr->todaysDate.wDay, infoPtr->todaysDate.wYear % 100);
+    rtoday->right = rcDraw->right;
+    SelectObject(hdc, infoPtr->hBoldFont);
+    DrawTextA(hdc, buf, lstrlenA(buf), rtoday,
+                         DT_LEFT | DT_VCENTER | DT_SINGLELINE);
+    SelectObject(hdc, infoPtr->hFont);
+  }
+
+  if(dwStyle & MCS_WEEKNUMBERS)  {
+    /* display weeknumbers*/
+    weeknums->left   = 0;
+    weeknums->right  = textWidth;
+    weeknums->top    = days->bottom + 2;
+    weeknums->bottom = days->bottom + 2 + textHeight;
+
+    weeknum = 0;
+    for(i=0; i<infoPtr->currentMonth-1; i++)
+      weeknum+=MONTHCAL_MonthLength(i, infoPtr->currentYear);
+
+    weeknum/=7;
+    for(i=0; i<6; i++) {
+      sprintf(buf, "%d", weeknum + i);
+      DrawTextA(hdc, buf, lstrlenA(buf), weeknums,
                          DT_CENTER | DT_BOTTOM | DT_SINGLELINE );
-                        weeknums->top+=textHeight*1.25;
-                        weeknums->bottom+=textHeight*1.25;
-                }
-
-            MoveToEx (hdc, weeknums->right, days->bottom+5 , NULL);
-        LineTo   (hdc, weeknums->right, weeknums->bottom-1.25*textHeight-5);
-
-        }
-
-                                 /* currentFont was font at entering Refresh */
-
-    SetBkColor (hdc, oldBkColor);
-    SelectObject (hdc, currentFont);
-    SetTextColor (hdc, oldTextColor);
-}
-
-
-static LRESULT
-MONTHCAL_GetMinReqRect (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-        LPRECT lpRect=(LPRECT) lParam;
-        //TRACE ("%x %lx\n",wParam,lParam);
+      weeknums->top+=textHeight * 1.25;
+      weeknums->bottom+=textHeight * 1.25;
+    }
+
+    MoveToEx(hdc, weeknums->right, days->bottom + 5 , NULL);
+    LineTo(hdc, weeknums->right, weeknums->bottom - 1.25 * textHeight - 5);
+
+  }
+
+  /* currentFont was font at entering Refresh */
+
+  SetBkColor(hdc, oldBkColor);
+  SelectObject(hdc, currentFont);
+  SetTextColor(hdc, oldTextColor);
+}
+
+
+static LRESULT
+MONTHCAL_GetMinReqRect(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  LPRECT lpRect = (LPRECT) lParam;
+  //TRACE("%x %lx\n", wParam, lParam);
 
   /* validate parameters */
 
-    if ( (infoPtr==NULL) || (lpRect == NULL) ) return FALSE;
-
-        lpRect->left=infoPtr->rcClient.left;
-        lpRect->right=infoPtr->rcClient.right;
-        lpRect->top=infoPtr->rcClient.top;
-        lpRect->bottom=infoPtr->rcClient.bottom;
-        return TRUE;
-}
-
-static LRESULT
-MONTHCAL_GetColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
-        //TRACE ("%x %lx\n",wParam,lParam);
-
-        switch ((int)wParam) {
-                case MCSC_BACKGROUND:
-                        return infoPtr->bk;
-                case MCSC_TEXT:
-                        return infoPtr->txt;
-                case MCSC_TITLEBK:
-                        return infoPtr->titlebk;
-                case MCSC_TITLETEXT:
-                        return infoPtr->titletxt;
-                case MCSC_MONTHBK:
-                        return infoPtr->monthbk;
-                case MCSC_TRAILINGTEXT:
-                        return infoPtr->trailingtxt;
-        }
-
- return -1;
-}
-
-static LRESULT
-MONTHCAL_SetColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-        int prev=-1;
-
-        //TRACE ("%x %lx\n",wParam,lParam);
-
-        switch ((int)wParam) {
-                case MCSC_BACKGROUND:
-                        prev=infoPtr->bk;
-                        infoPtr->bk=(COLORREF) lParam;
-                        break;
-                case MCSC_TEXT:
-                        prev=infoPtr->txt;
-                        infoPtr->txt=(COLORREF) lParam;
-                        break;
-                case MCSC_TITLEBK:
-                        prev=infoPtr->titlebk;
-                        infoPtr->titlebk=(COLORREF) lParam;
-                        break;
-                case MCSC_TITLETEXT:
-                        prev=infoPtr->titletxt;
-                        infoPtr->titletxt=(COLORREF) lParam;
-                        break;
-                case MCSC_MONTHBK:
-                        prev=infoPtr->monthbk;
-                        infoPtr->monthbk=(COLORREF) lParam;
-                        break;
-                case MCSC_TRAILINGTEXT:
-                        prev=infoPtr->trailingtxt;
-                        infoPtr->trailingtxt=(COLORREF) lParam;
-                        break;
-        }
-
- return prev;
-}
-
-static LRESULT
-MONTHCAL_GetMonthDelta (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
-        //TRACE ("%x %lx\n",wParam,lParam);
-
-        if (infoPtr->delta) return infoPtr->delta;
-        else return infoPtr->visible;
-}
-
-static LRESULT
-MONTHCAL_SetMonthDelta (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-    int prev=infoPtr->delta;
-
-        //TRACE ("%x %lx\n",wParam,lParam);
-
-        infoPtr->delta=(int) wParam;
-        return prev;
-}
-
-
-
-static LRESULT
-MONTHCAL_GetFirstDayOfWeek (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
-        return infoPtr->firstDay;
-}
-
+  if((infoPtr==NULL) ||(lpRect == NULL) ) return FALSE;
+
+  lpRect->left = infoPtr->rcClient.left;
+  lpRect->right = infoPtr->rcClient.right;
+  lpRect->top = infoPtr->rcClient.top;
+  lpRect->bottom = infoPtr->rcClient.bottom;
+  return TRUE;
+}
+
+static LRESULT
+MONTHCAL_GetColor(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  switch((int)wParam) {
+    case MCSC_BACKGROUND:
+      return infoPtr->bk;
+    case MCSC_TEXT:
+      return infoPtr->txt;
+    case MCSC_TITLEBK:
+      return infoPtr->titlebk;
+    case MCSC_TITLETEXT:
+      return infoPtr->titletxt;
+    case MCSC_MONTHBK:
+      return infoPtr->monthbk;
+    case MCSC_TRAILINGTEXT:
+      return infoPtr->trailingtxt;
+  }
+
+  return -1;
+}
+
+static LRESULT
+MONTHCAL_SetColor(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  int prev = -1;
+
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  switch((int)wParam) {
+    case MCSC_BACKGROUND:
+      prev = infoPtr->bk;
+      infoPtr->bk = (COLORREF)lParam;
+      break;
+    case MCSC_TEXT:
+      prev = infoPtr->txt;
+      infoPtr->txt = (COLORREF)lParam;
+      break;
+    case MCSC_TITLEBK:
+      prev = infoPtr->titlebk;
+      infoPtr->titlebk = (COLORREF)lParam;
+      break;
+    case MCSC_TITLETEXT:
+      prev=infoPtr->titletxt;
+      infoPtr->titletxt = (COLORREF)lParam;
+      break;
+    case MCSC_MONTHBK:
+      prev = infoPtr->monthbk;
+      infoPtr->monthbk = (COLORREF)lParam;
+      break;
+    case MCSC_TRAILINGTEXT:
+      prev = infoPtr->trailingtxt;
+      infoPtr->trailingtxt = (COLORREF)lParam;
+      break;
+  }
+
+  return prev;
+}
+
+static LRESULT
+MONTHCAL_GetMonthDelta(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  if(infoPtr->delta)
+    return infoPtr->delta;
+  else
+    return infoPtr->visible;
+}
+
+static LRESULT
+MONTHCAL_SetMonthDelta(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  int prev = infoPtr->delta;
+
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  infoPtr->delta = (int)wParam;
+  return prev;
+}
+
+
+static LRESULT
+MONTHCAL_GetFirstDayOfWeek(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  return infoPtr->firstDay;
+}
+
+
+/* sets the first day of the week that will appear in the control */
+/* 0 == Monday, 6 == Sunday */
+/* FIXME: this needs to be implemented properly in MONTHCAL_Refresh() */
 /* FIXME: we need more error checking here */
-
-static LRESULT
-MONTHCAL_SetFirstDayOfWeek (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-    int prev=infoPtr->firstDay;
-        char buf[40];
-        int day;
-
-        //TRACE ("%x %lx\n",wParam,lParam);
-
-        if ((lParam>=0) && (lParam<7)) {
-                        infoPtr->firstDay=(int) lParam;
-                        GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK,
+static LRESULT
+MONTHCAL_SetFirstDayOfWeek(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  int prev = infoPtr->firstDay;
+  char buf[40];
+  int day;
+
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  if((lParam >= 0) && (lParam < 7)) {
+    infoPtr->firstDay = (int)lParam;
+    GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_IFIRSTDAYOFWEEK,
                 buf, sizeof(buf));
-                //TRACE ("%s %d\n",buf,strlen(buf));
-            if ((sscanf(buf,"%d",&day)==1) && (infoPtr->firstDay!=day))
-                                infoPtr->firstDay|=HIWORD(TRUE);
-
-        }
-    return prev;
-}
-
+    //TRACE("%s %d\n", buf, strlen(buf));
+    if((sscanf(buf, "%d", &day) == 1) &&(infoPtr->firstDay != day))
+      infoPtr->firstDay = day;
+  }
+  return prev;
+}
 
 
 /* FIXME: fill this in */
-
-static LRESULT
-MONTHCAL_GetMonthRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
-  //TRACE ("%x %lx\n",wParam,lParam);
+static LRESULT
+MONTHCAL_GetMonthRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  //TRACE("%x %lx\n", wParam, lParam);
+  //FIXME("stub\n");
 
   return infoPtr->monthRange;
 }
 
-static LRESULT
-MONTHCAL_GetMaxTodayWidth (HWND hwnd)
-
-{
- MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
- return (infoPtr->today.right-infoPtr->today.left);
-}
+
+static LRESULT
+MONTHCAL_GetMaxTodayWidth(HWND hwnd)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  return(infoPtr->today.right - infoPtr->today.left);
+}
+
 
 /* FIXME: are validated times taken from current date/time or simply
@@ -753,36 +765,38 @@
 
 static LRESULT
-MONTHCAL_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
+MONTHCAL_SetRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
   SYSTEMTIME lprgSysTimeArray[1];
   int prev;
 
-  //TRACE ("%x %lx\n",wParam,lParam);
-
-  if (wParam & GDTR_MAX) {
-                if (MONTHCAL_ValidateTime(lprgSysTimeArray[1])){
-                        MONTHCAL_CopyTime (&lprgSysTimeArray[1],&infoPtr->maxDate);
-                        infoPtr->rangeValid|=GDTR_MAX;
-                } else  {
-                        GetSystemTime (&infoPtr->todaysDate);
-                        MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
-                        }
-                }
-  if (wParam & GDTR_MIN) {
-                if (MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
-                        MONTHCAL_CopyTime (&lprgSysTimeArray[0],&infoPtr->maxDate);
-                        infoPtr->rangeValid|=GDTR_MIN;
-                } else {
-                        GetSystemTime (&infoPtr->todaysDate);
-                        MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
-                        }
-            }
-
-  prev=infoPtr->monthRange;
-  infoPtr->monthRange=infoPtr->maxDate.wMonth-infoPtr->minDate.wMonth;
-  if (infoPtr->monthRange!=prev)
-        COMCTL32_ReAlloc (infoPtr->monthdayState,
-                infoPtr->monthRange*sizeof(MONTHDAYSTATE));
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  if(wParam & GDTR_MAX) {
+    if(MONTHCAL_ValidateTime(lprgSysTimeArray[1])){
+      MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxDate);
+      infoPtr->rangeValid|=GDTR_MAX;
+    } else  {
+      GetSystemTime(&infoPtr->todaysDate);
+      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
+    }
+  }
+  if(wParam & GDTR_MIN) {
+    if(MONTHCAL_ValidateTime(lprgSysTimeArray[0])) {
+      MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->maxDate);
+      infoPtr->rangeValid|=GDTR_MIN;
+    } else {
+      GetSystemTime(&infoPtr->todaysDate);
+      MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
+    }
+  }
+
+  prev = infoPtr->monthRange;
+  infoPtr->monthRange = infoPtr->maxDate.wMonth - infoPtr->minDate.wMonth;
+
+  if(infoPtr->monthRange!=prev) {
+        COMCTL32_ReAlloc(infoPtr->monthdayState,
+                infoPtr->monthRange * sizeof(MONTHDAYSTATE));
+  }
 
   return 1;
@@ -796,46 +810,48 @@
 
 static LRESULT
-MONTHCAL_GetRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
+MONTHCAL_GetRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *)lParam;
 
   /* validate parameters */
 
-  if ( (infoPtr==NULL) || (lprgSysTimeArray==NULL) ) return FALSE;
-
-  MONTHCAL_CopyTime (&infoPtr->maxDate,&lprgSysTimeArray[1]);
-  MONTHCAL_CopyTime (&infoPtr->minDate,&lprgSysTimeArray[0]);
+  if((infoPtr==NULL) || (lprgSysTimeArray==NULL)) return FALSE;
+
+  MONTHCAL_CopyTime(&infoPtr->maxDate, &lprgSysTimeArray[1]);
+  MONTHCAL_CopyTime(&infoPtr->minDate, &lprgSysTimeArray[0]);
 
   return infoPtr->rangeValid;
 }
 
-static LRESULT
-MONTHCAL_SetDayState (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  int i,iMonths=(int) wParam;
-  MONTHDAYSTATE *dayStates=(LPMONTHDAYSTATE) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
-  if (iMonths!=infoPtr->monthRange) return 0;
-
-  for (i=0; i<iMonths; i++)
-                infoPtr->monthdayState[i]=dayStates[i];
+
+static LRESULT
+MONTHCAL_SetDayState(HWND hwnd, WPARAM wParam, LPARAM lParam)
+
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  int i, iMonths = (int)wParam;
+  MONTHDAYSTATE *dayStates = (LPMONTHDAYSTATE)lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
+  if(iMonths!=infoPtr->monthRange) return 0;
+
+  for(i=0; i<iMonths; i++)
+    infoPtr->monthdayState[i] = dayStates[i];
   return 1;
 }
 
-static LRESULT
-MONTHCAL_GetCurSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lpSel=(SYSTEMTIME *) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
-  if ( (infoPtr==NULL) || (lpSel==NULL) ) return FALSE;
-  if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;
-
-  MONTHCAL_CopyTime (&infoPtr->minSel,lpSel);
+
+static LRESULT
+MONTHCAL_GetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lpSel = (SYSTEMTIME *) lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
+  if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
+  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;
+
+  MONTHCAL_CopyTime(&infoPtr->minSel, lpSel);
   return TRUE;
 }
@@ -844,40 +860,41 @@
 /* FIXME: if the specified date is not visible, make it visible */
 /* FIXME: redraw? */
-
-static LRESULT
-MONTHCAL_SetCurSel (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lpSel=(SYSTEMTIME *) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
-  if ( (infoPtr==NULL) || (lpSel==NULL) ) return FALSE;
-  if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;
-
-  //TRACE ("%d %d\n",lpSel->wMonth,lpSel->wDay);
-
-  MONTHCAL_CopyTime (lpSel,&infoPtr->minSel);
-  MONTHCAL_CopyTime (lpSel,&infoPtr->maxSel);
+static LRESULT
+MONTHCAL_SetCurSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lpSel = (SYSTEMTIME *)lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
+  if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
+  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;
+
+  //TRACE("%d %d\n", lpSel->wMonth, lpSel->wDay);
+
+  MONTHCAL_CopyTime(lpSel, &infoPtr->minSel);
+  MONTHCAL_CopyTime(lpSel, &infoPtr->maxSel);
 
   return TRUE;
 }
 
-static LRESULT
-MONTHCAL_GetMaxSelCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
-  //TRACE ("%x %lx\n",wParam,lParam);
+
+static LRESULT
+MONTHCAL_GetMaxSelCount(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  //TRACE("%x %lx\n", wParam, lParam);
   return infoPtr->maxSelCount;
 }
 
-static LRESULT
-MONTHCAL_SetMaxSelCount (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-
-  //TRACE ("%x %lx\n",wParam,lParam);
-  if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
-                infoPtr->maxSelCount=wParam;
+
+static LRESULT
+MONTHCAL_SetMaxSelCount(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  //TRACE("%x %lx\n", wParam, lParam);
+  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
+    infoPtr->maxSelCount = wParam;
   }
 
@@ -887,20 +904,21 @@
 
 static LRESULT
-MONTHCAL_GetSelRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
+MONTHCAL_GetSelRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
 
   /* validate parameters */
 
-  if ( (infoPtr==NULL) || (lprgSysTimeArray==NULL) ) return FALSE;
-
-  if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
-                MONTHCAL_CopyTime (&infoPtr->maxSel,&lprgSysTimeArray[1]);
-        MONTHCAL_CopyTime (&infoPtr->minSel,&lprgSysTimeArray[0]);
-                //TRACE ("[min,max]=[%d %d]\n",infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
-        return TRUE;
+  if((infoPtr==NULL) ||(lprgSysTimeArray==NULL)) return FALSE;
+
+  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT)
+  {
+    MONTHCAL_CopyTime(&infoPtr->maxSel, &lprgSysTimeArray[1]);
+    MONTHCAL_CopyTime(&infoPtr->minSel, &lprgSysTimeArray[0]);
+    //TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
+    return TRUE;
   }
 
@@ -908,21 +926,23 @@
 }
 
-static LRESULT
-MONTHCAL_SetSelRange (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
+
+static LRESULT
+MONTHCAL_SetSelRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lprgSysTimeArray = (SYSTEMTIME *) lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
 
   /* validate parameters */
 
-  if ( (infoPtr==NULL) || (lprgSysTimeArray==NULL) ) return FALSE;
-
-  if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
-                MONTHCAL_CopyTime (&lprgSysTimeArray[1],&infoPtr->maxSel);
-        MONTHCAL_CopyTime (&lprgSysTimeArray[0],&infoPtr->minSel);
-                //TRACE ("[min,max]=[%d %d]\n",infoPtr->minSel.wDay,infoPtr->maxSel.wDay);
-        return TRUE;
+  if((infoPtr==NULL) ||(lprgSysTimeArray==NULL)) return FALSE;
+
+  if(GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT)
+  {
+    MONTHCAL_CopyTime(&lprgSysTimeArray[1], &infoPtr->maxSel);
+    MONTHCAL_CopyTime(&lprgSysTimeArray[0], &infoPtr->minSel);
+    //TRACE("[min,max]=[%d %d]\n", infoPtr->minSel.wDay, infoPtr->maxSel.wDay);
+    return TRUE;
   }
 
@@ -931,18 +951,16 @@
 
 
-
-
-static LRESULT
-MONTHCAL_GetToday (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lpToday=(SYSTEMTIME *) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
+static LRESULT
+MONTHCAL_GetToday(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
 
   /* validate parameters */
 
-  if ( (infoPtr==NULL) || (lpToday==NULL) ) return FALSE;
-  MONTHCAL_CopyTime (&infoPtr->todaysDate,lpToday);
+  if((infoPtr==NULL) || (lpToday==NULL)) return FALSE;
+  MONTHCAL_CopyTime(&infoPtr->todaysDate, lpToday);
   return TRUE;
 }
@@ -950,85 +968,83 @@
 
 static LRESULT
-MONTHCAL_SetToday (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-  MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
-  SYSTEMTIME *lpToday=(SYSTEMTIME *) lParam;
-
-  //TRACE ("%x %lx\n",wParam,lParam);
+MONTHCAL_SetToday(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  SYSTEMTIME *lpToday = (SYSTEMTIME *) lParam;
+
+  //TRACE("%x %lx\n", wParam, lParam);
 
   /* validate parameters */
 
-  if ( (infoPtr==NULL) || (lpToday==NULL) ) return FALSE;
-  MONTHCAL_CopyTime (lpToday, &infoPtr->todaysDate);
+  if((infoPtr==NULL) ||(lpToday==NULL)) return FALSE;
+  MONTHCAL_CopyTime(lpToday, &infoPtr->todaysDate);
   return TRUE;
 }
 
 
-
-
-static LRESULT
-MONTHCAL_HitTest (HWND hwnd, LPARAM lParam)
-{
- MONTHCAL_INFO *infoPtr=MONTHCAL_GetInfoPtr(hwnd);
- PMCHITTESTINFO lpht=(PMCHITTESTINFO) lParam;
+static LRESULT
+MONTHCAL_HitTest(HWND hwnd, LPARAM lParam)
+{
+ MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+ PMCHITTESTINFO lpht = (PMCHITTESTINFO)lParam;
  UINT x,y;
  DWORD retval;
 
- x=lpht->pt.x;
- y=lpht->pt.y;
- retval=MCHT_NOWHERE;
-
-
-        /* are we in the header? */
-
- if (PtInRect (&infoPtr->title, lpht->pt)) {
-
-                if (PtInRect (&infoPtr->titlebtnprev, lpht->pt)) {
-                        retval=MCHT_TITLEBTNPREV;
-                        goto done;
-                }
-                if (PtInRect (&infoPtr->titlebtnnext, lpht->pt)) {
-                        retval=MCHT_TITLEBTNNEXT;
-                        goto done;
-                }
-                if (PtInRect (&infoPtr->titlemonth, lpht->pt)) {
-                        retval=MCHT_TITLEMONTH;
-                        goto done;
-                }
-                if (PtInRect (&infoPtr->titleyear, lpht->pt)) {
-                        retval=MCHT_TITLEYEAR;
-                        goto done;
-                }
-                retval=MCHT_TITLE;
-                goto done;
-        }
-
- if (PtInRect (&infoPtr->days, lpht->pt)) {
-                retval=MCHT_CALENDARDAY;  /* FIXME: find out which day we're on */
-                goto done;
-        }
- if (PtInRect (&infoPtr->weeknums, lpht->pt)) {
-                retval=MCHT_CALENDARWEEKNUM;/* FIXME: find out which day we're on */
-                goto done;
-        }
- if (PtInRect (&infoPtr->prevmonth, lpht->pt)) {
-                retval=MCHT_CALENDARDATEPREV;
-                goto done;
-        }
- if (PtInRect (&infoPtr->nextmonth, lpht->pt) ||
-    ((x>infoPtr->nextmonth.left) && (x<infoPtr->nextmonth.right) &&
-     (y>infoPtr->nextmonth.bottom) && (y<infoPtr->today.top ))) {
-                retval=MCHT_CALENDARDATENEXT;
-                goto done;
-        }
-
-
- if (PtInRect (&infoPtr->today, lpht->pt)) {
-                retval=MCHT_TODAYLINK;
-                goto done;
-        }
+ x = lpht->pt.x;
+ y = lpht->pt.y;
+ retval = MCHT_NOWHERE;
+
+
+  /* are we in the header? */
+
+  if(PtInRect(&infoPtr->title, lpht->pt)) {
+    if(PtInRect(&infoPtr->titlebtnprev, lpht->pt)) {
+      retval = MCHT_TITLEBTNPREV;
+      goto done;
+    }
+    if(PtInRect(&infoPtr->titlebtnnext, lpht->pt)) {
+      retval = MCHT_TITLEBTNNEXT;
+      goto done;
+    }
+    if(PtInRect(&infoPtr->titlemonth, lpht->pt)) {
+      retval = MCHT_TITLEMONTH;
+      goto done;
+    }
+    if(PtInRect(&infoPtr->titleyear, lpht->pt)) {
+      retval = MCHT_TITLEYEAR;
+      goto done;
+    }
+
+    retval = MCHT_TITLE;
+    goto done;
+  }
+
+  if(PtInRect(&infoPtr->days, lpht->pt)) {
+    retval = MCHT_CALENDARDAY;  /* FIXME: find out which day we're on */
+    goto done;
+  }
+  if(PtInRect(&infoPtr->weeknums, lpht->pt)) {
+    retval = MCHT_CALENDARWEEKNUM; /* FIXME: find out which day we're on */
+    goto done;
+  }
+  if(PtInRect(&infoPtr->prevmonth, lpht->pt)) {
+    retval = MCHT_CALENDARDATEPREV;
+    goto done;
+  }
+
+  if(PtInRect(&infoPtr->nextmonth, lpht->pt) ||
+ ((x>infoPtr->nextmonth.left) &&(x<infoPtr->nextmonth.right) &&
+  (y>infoPtr->nextmonth.bottom) &&(y<infoPtr->today.top ))) {
+    retval = MCHT_CALENDARDATENEXT;
+    goto done;
+  }
+
+  if(PtInRect(&infoPtr->today, lpht->pt)) {
+    retval = MCHT_TODAYLINK;
+    goto done;
+  }
 
 /* MCHT_CALENDARDATE determination: since the next & previous month have
- * been handled already (MCHT_CALENDARDATEPREV/NEXT), we only have to check
+ * been handled already(MCHT_CALENDARDATEPREV/NEXT), we only have to check
  * whether we're in the calendar area. infoPtr->prevMonth.left handles the
  * MCS_WEEKNUMBERS style nicely.
@@ -1036,576 +1052,713 @@
 
 
- //TRACE ("%d %d [%d %d %d %d] [%d %d %d %d]\n",x,y,
+ //TRACE("%d %d [%d %d %d %d] [%d %d %d %d]\n", x, y,
  //       infoPtr->prevmonth.left, infoPtr->prevmonth.right,
  //       infoPtr->prevmonth.top, infoPtr->prevmonth.bottom,
  //       infoPtr->nextmonth.left, infoPtr->nextmonth.right,
  //       infoPtr->nextmonth.top, infoPtr->nextmonth.bottom);
-
- if ((x>infoPtr->prevmonth.left) && (x<infoPtr->nextmonth.right) &&
-         (y>infoPtr->prevmonth.top) && (y<infoPtr->nextmonth.bottom))  {
-                lpht->st.wYear=infoPtr->currentYear;
-                lpht->st.wMonth=infoPtr->currentMonth;
-
-                lpht->st.wDay=MONTHCAL_CalcDayFromPos (infoPtr,x,y);
-
-                //TRACE ("day hit: %d\n",lpht->st.wDay);
-                retval=MCHT_CALENDARDATE;
-                goto done;
-
-        }
-
-        /* Hit nothing special? What's left must be background :-) */
-
-  retval=MCHT_CALENDARBK;
+  if((x>infoPtr->prevmonth.left) &&(x<infoPtr->nextmonth.right) &&
+   (y>infoPtr->prevmonth.top) &&(y<infoPtr->nextmonth.bottom))  {
+    lpht->st.wYear = infoPtr->currentYear;
+    lpht->st.wMonth = infoPtr->currentMonth;
+
+    lpht->st.wDay = MONTHCAL_CalcDayFromPos(infoPtr, x, y);
+
+    //TRACE("day hit: %d\n", lpht->st.wDay);
+    retval = MCHT_CALENDARDATE;
+    goto done;
+
+  }
+
+  /* Hit nothing special? What's left must be background :-) */
+
+  retval = MCHT_CALENDARBK;
  done:
-  lpht->uHit=retval;
+  lpht->uHit = retval;
   return retval;
 }
 
 
-
-static void MONTHCAL_GoToNextMonth (HWND hwnd,  MONTHCAL_INFO *infoPtr)
-{
-    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-
-        //TRACE ("\n");
-
-        infoPtr->currentMonth++;
-        if (infoPtr->currentMonth>12) {
-                infoPtr->currentYear++;
-                infoPtr->currentMonth=1;
-        }
-
-        if (dwStyle & MCS_DAYSTATE) {
-                NMDAYSTATE nmds;
-                int i;
-
-        nmds.nmhdr.hwndFrom = hwnd;
-                nmds.nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
-                nmds.nmhdr.code     = MCN_GETDAYSTATE;
-                nmds.cDayState          = infoPtr->monthRange;
-                nmds.prgDayState        = COMCTL32_Alloc
-                                 (infoPtr->monthRange*sizeof(MONTHDAYSTATE));
-
-                SendMessageA (GetParent (hwnd), WM_NOTIFY,
-                                  (WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
-                for (i=0; i<infoPtr->monthRange; i++)
-                infoPtr->monthdayState[i]=nmds.prgDayState[i];
-        }
-
-}
-
-
-static void MONTHCAL_GoToPrevMonth (HWND hwnd,  MONTHCAL_INFO *infoPtr)
-{
-    DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
-
-        //TRACE ("\n");
-
-        infoPtr->currentMonth--;
-        if (infoPtr->currentMonth<1) {
-                infoPtr->currentYear--;
-                infoPtr->currentMonth=12;
-        }
-
-        if (dwStyle & MCS_DAYSTATE) {
-                NMDAYSTATE nmds;
-                int i;
-
-        nmds.nmhdr.hwndFrom = hwnd;
-                nmds.nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
-                nmds.nmhdr.code     = MCN_GETDAYSTATE;
-                nmds.cDayState          = infoPtr->monthRange;
-                nmds.prgDayState        = COMCTL32_Alloc
-                                 (infoPtr->monthRange*sizeof(MONTHDAYSTATE));
-
-                SendMessageA (GetParent (hwnd), WM_NOTIFY,
-                                 (WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
-                for (i=0; i<infoPtr->monthRange; i++)
-                infoPtr->monthdayState[i]=nmds.prgDayState[i];
-        }
-}
-
-
-static LRESULT
-MONTHCAL_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
-        MCHITTESTINFO ht;
-        HDC hdc;
-        DWORD hit;
-        HMENU hMenu;
-        HWND retval;
-
-
-        //TRACE ("%x %lx\n",wParam,lParam);
-
-    ht.pt.x = (INT)LOWORD(lParam);
-    ht.pt.y = (INT)HIWORD(lParam);
-    hit=MONTHCAL_HitTest (hwnd, (LPARAM) &ht);
-
-    hdc=GetDC (hwnd);
-
-        if (hit & MCHT_NEXT){
-                MONTHCAL_GoToNextMonth (hwnd, infoPtr);
-                infoPtr->status=MC_NEXTPRESSED;
-                SetTimer (hwnd, MC_NEXTMONTHTIMER, MC_NEXTMONTHDELAY,0);
-        }
-        if (hit & MCHT_PREV) {
-                MONTHCAL_GoToPrevMonth (hwnd, infoPtr);
-                infoPtr->status=MC_PREVPRESSED;
-                SetTimer (hwnd, MC_PREVMONTHTIMER, MC_NEXTMONTHDELAY,0);
-        }
-
-        if (hit == MCHT_TITLEMONTH) {
+static void MONTHCAL_GoToNextMonth(HWND hwnd, MONTHCAL_INFO *infoPtr)
+{
+  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
+
+  //TRACE("MONTHCAL_GoToNextMonth\n");
+
+  infoPtr->currentMonth++;
+  if(infoPtr->currentMonth > 12) {
+    infoPtr->currentYear++;
+    infoPtr->currentMonth = 1;
+  }
+
+  if(dwStyle & MCS_DAYSTATE) {
+    NMDAYSTATE nmds;
+    int i;
+
+    nmds.nmhdr.hwndFrom = hwnd;
+    nmds.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
+    nmds.nmhdr.code     = MCN_GETDAYSTATE;
+    nmds.cDayState      = infoPtr->monthRange;
+    nmds.prgDayState    = COMCTL32_Alloc(infoPtr->monthRange * sizeof(MONTHDAYSTATE));
+
+    SendMessageA(GetParent(hwnd), WM_NOTIFY,
+    (WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
+    for(i=0; i<infoPtr->monthRange; i++)
+      infoPtr->monthdayState[i] = nmds.prgDayState[i];
+  }
+}
+
+
+static void MONTHCAL_GoToPrevMonth(HWND hwnd,  MONTHCAL_INFO *infoPtr)
+{
+  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
+
+  //TRACE("MONTHCAL_GoToPrevMonth\n");
+
+  infoPtr->currentMonth--;
+  if(infoPtr->currentMonth < 1) {
+    infoPtr->currentYear--;
+    infoPtr->currentMonth = 12;
+  }
+
+  if(dwStyle & MCS_DAYSTATE) {
+    NMDAYSTATE nmds;
+    int i;
+
+    nmds.nmhdr.hwndFrom = hwnd;
+    nmds.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
+    nmds.nmhdr.code     = MCN_GETDAYSTATE;
+    nmds.cDayState      = infoPtr->monthRange;
+    nmds.prgDayState    = COMCTL32_Alloc
+                        (infoPtr->monthRange * sizeof(MONTHDAYSTATE));
+
+    SendMessageA(GetParent(hwnd), WM_NOTIFY,
+        (WPARAM)nmds.nmhdr.idFrom, (LPARAM)&nmds);
+    for(i=0; i<infoPtr->monthRange; i++)
+       infoPtr->monthdayState[i] = nmds.prgDayState[i];
+  }
+}
+
+
+static LRESULT
+MONTHCAL_LButtonDown(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  MCHITTESTINFO ht;
+  HDC hdc;
+  DWORD hit;
+  HMENU hMenu;
+  HWND retval;
+  BOOL redraw = FALSE;
+
+
+  //TRACE("%x %lx\n", wParam, lParam);
+
+  ht.pt.x = (INT)LOWORD(lParam);
+  ht.pt.y = (INT)HIWORD(lParam);
+  hit = MONTHCAL_HitTest(hwnd, (LPARAM)&ht);
+
+  /* FIXME: these flags should be checked by */
+  /*((hit & MCHT_XXX) == MCHT_XXX) b/c some of the flags are */
+  /* multi-bit */
+  if(hit & MCHT_NEXT) {
+    redraw = TRUE;
+    MONTHCAL_GoToNextMonth(hwnd, infoPtr);
+    infoPtr->status = MC_NEXTPRESSED;
+    SetTimer(hwnd, MC_NEXTMONTHTIMER, MC_NEXTMONTHDELAY, 0);
+  }
+  if(hit & MCHT_PREV) {
+    redraw = TRUE;
+    MONTHCAL_GoToPrevMonth(hwnd, infoPtr);
+    infoPtr->status = MC_PREVPRESSED;
+    SetTimer(hwnd, MC_PREVMONTHTIMER, MC_NEXTMONTHDELAY, 0);
+  }
+
+  if(hit == MCHT_TITLEMONTH) {
 /*
-                HRSRC hrsrc = FindResourceA( COMCTL32_hModule, MAKEINTRESOURCEA(IDD_MCMONTHMENU), RT_MENUA );
-        if (!hrsrc) {
-                        TRACE ("returning zero\n");
-                        return 0;
-                }
-                TRACE ("resource is:%x\n",hrsrc);
-        hMenu=LoadMenuIndirectA( (LPCVOID)LoadResource( COMCTL32_hModule, hrsrc ));
-
-                TRACE ("menu is:%x\n",hMenu);
+    HRSRC hrsrc = FindResourceA( COMCTL32_hModule, MAKEINTRESOURCEA(IDD_MCMONTHMENU), RT_MENUA );
+    if(!hrsrc) {
+      TRACE("returning zero\n");
+      return 0;
+    }
+    TRACE("resource is:%x\n",hrsrc);
+    hMenu = LoadMenuIndirectA((LPCVOID)LoadResource( COMCTL32_hModule, hrsrc ));
+
+    TRACE("menu is:%x\n",hMenu);
 */
 
-                hMenu=CreateMenu ();
-        AppendMenuA (hMenu,MF_STRING,IDM_JAN,"January");
-        AppendMenuA (hMenu,MF_STRING,IDM_FEB,"February");
-        AppendMenuA (hMenu,MF_STRING,IDM_MAR,"March");
-
-                retval=CreateWindowA (POPUPMENU_CLASS_ATOM, NULL,
-                        WS_CHILD | WS_VISIBLE,
-                        0,0,100,220,
-                        hwnd, hMenu, GetWindowLongA (hwnd, GWL_HINSTANCE), NULL);
-                //TRACE ("hwnd returned:%x\n",retval);
-
-        }
-        if (hit == MCHT_TITLEYEAR) {
-                        //FIXME ("create updown for yearselection\n");
-        }
-        if (hit == MCHT_TODAYLINK) {
-                        //FIXME ("set currentday\n");
-        }
-        if (hit == MCHT_CALENDARDATE) {
-                        SYSTEMTIME selArray[2];
-                        NMSELCHANGE nmsc;
-
-                        //TRACE ("\n");
-                    nmsc.nmhdr.hwndFrom = hwnd;
-                nmsc.nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
-                nmsc.nmhdr.code     = MCN_SELCHANGE;
-                        MONTHCAL_CopyTime (&nmsc.stSelStart, &infoPtr->minSel);
-                        MONTHCAL_CopyTime (&nmsc.stSelEnd, &infoPtr->maxSel);
-
-                SendMessageA (GetParent (hwnd), WM_NOTIFY,
-                                   (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
-
-                        MONTHCAL_CopyTime (&ht.st, &selArray[0]);
-                        MONTHCAL_CopyTime (&ht.st, &selArray[1]);
-                        MONTHCAL_SetSelRange (hwnd,0,(LPARAM) &selArray);
-
-                        infoPtr->firstSelDay=ht.st.wDay;
-                        infoPtr->curSelDay=ht.st.wDay;
-                        infoPtr->status=MC_SEL_LBUTDOWN;
-        }
-
-        MONTHCAL_Refresh (hwnd,hdc);
-        ReleaseDC (hwnd,hdc);
-        return 0;
-}
-
-static LRESULT
-MONTHCAL_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
-        NMSELCHANGE nmsc;
-    NMHDR nmhdr;
-        HDC hdc;
-
-        //TRACE ("\n");
-
-        if (infoPtr->status & MC_NEXTPRESSED)
-                        KillTimer (hwnd, MC_NEXTMONTHTIMER);
-        if (infoPtr->status & MC_PREVPRESSED)
-                        KillTimer (hwnd, MC_PREVMONTHTIMER);
-        infoPtr->status=MC_SEL_LBUTUP;
-        infoPtr->curSelDay=0;
-
-    nmhdr.hwndFrom = hwnd;
-    nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
-    nmhdr.code     = NM_RELEASEDCAPTURE;
-        //TRACE ("Sent notification from %x to %x\n", hwnd, GetParent (hwnd));
-
-    SendMessageA (GetParent (hwnd), WM_NOTIFY,
-                                   (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
-
+    hMenu = CreateMenu();
+    AppendMenuA(hMenu, MF_STRING,IDM_JAN, "January");
+    AppendMenuA(hMenu, MF_STRING,IDM_FEB, "February");
+    AppendMenuA(hMenu, MF_STRING,IDM_MAR, "March");
+
+    retval = CreateWindowA(POPUPMENU_CLASS_ATOM, NULL,
+              WS_CHILD | WS_VISIBLE, 0, 0 ,100 , 220,
+              hwnd, hMenu, GetWindowLongA(hwnd, GWL_HINSTANCE), NULL);
+    //TRACE("hwnd returned:%x\n", retval);
+
+  }
+  if(hit == MCHT_TITLEYEAR) {
+    //FIXME("create updown for yearselection\n");
+  }
+  if(hit == MCHT_TODAYLINK) {
+    //FIXME("set currentday\n");
+  }
+  if(hit == MCHT_CALENDARDATE) {
+    SYSTEMTIME selArray[2];
+    NMSELCHANGE nmsc;
+
+    //TRACE("\n");
     nmsc.nmhdr.hwndFrom = hwnd;
-    nmsc.nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
-    nmsc.nmhdr.code     = MCN_SELECT;
-        MONTHCAL_CopyTime (&nmsc.stSelStart, &infoPtr->minSel);
-        MONTHCAL_CopyTime (&nmsc.stSelEnd, &infoPtr->maxSel);
-
-    SendMessageA (GetParent (hwnd), WM_NOTIFY,
-                                   (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
-
-    hdc=GetDC (hwnd);
-    MONTHCAL_Refresh (hwnd,hdc);
-    ReleaseDC (hwnd,hdc);
-
-        return 0;
-}
-
-static LRESULT
-MONTHCAL_Timer (HWND hwnd, WPARAM wParam, LPARAM lParam)
-
-{
-    MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
-    HDC hdc;
-
-    //TRACE(" %d\n",wParam);
-    if (!infoPtr) return FALSE;
-
-    hdc=GetDC (hwnd);
-    switch (wParam) {
-        case MC_NEXTMONTHTIMER:
-                MONTHCAL_GoToNextMonth (hwnd, infoPtr);
-                break;
-        case MC_PREVMONTHTIMER:
-                MONTHCAL_GoToPrevMonth (hwnd, infoPtr);
-                break;
-    //default:
-        //ERR("got unknown timer\n");
-        }
-
-    MONTHCAL_Refresh (hwnd,hdc);
-    ReleaseDC (hwnd,hdc);
+    nmsc.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
+    nmsc.nmhdr.code     = MCN_SELCHANGE;
+    MONTHCAL_CopyTime(&nmsc.stSelStart, &infoPtr->minSel);
+    MONTHCAL_CopyTime(&nmsc.stSelEnd, &infoPtr->maxSel);
+
+    SendMessageA(GetParent(hwnd), WM_NOTIFY,
+           (WPARAM)nmsc.nmhdr.idFrom,(LPARAM)&nmsc);
+
+    MONTHCAL_CopyTime(&ht.st, &selArray[0]);
+    MONTHCAL_CopyTime(&ht.st, &selArray[1]);
+    MONTHCAL_SetSelRange(hwnd,0,(LPARAM) &selArray);
+
+    /* redraw if the selected day changed */
+    if(infoPtr->curSelDay != ht.st.wDay) {
+      redraw = TRUE;
+    }
+
+    infoPtr->firstSelDay = ht.st.wDay;
+    infoPtr->curSelDay = ht.st.wDay;
+    infoPtr->status = MC_SEL_LBUTDOWN;
+  }
+
+  /* redraw only if the control changed */
+  if(redraw) {
+    hdc = GetDC(hwnd);
+          MONTHCAL_Refresh(hwnd, hdc);
+    ReleaseDC(hwnd, hdc);
+  }
+
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_LButtonUp(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  NMSELCHANGE nmsc;
+  NMHDR nmhdr;
+  HDC hdc;
+  BOOL redraw = FALSE;
+
+  //TRACE("\n");
+
+  if(infoPtr->status & MC_NEXTPRESSED) {
+    KillTimer(hwnd, MC_NEXTMONTHTIMER);
+    redraw = TRUE;
+  }
+  if(infoPtr->status & MC_PREVPRESSED) {
+    KillTimer(hwnd, MC_PREVMONTHTIMER);
+    redraw = TRUE;
+  }
+
+  infoPtr->status = MC_SEL_LBUTUP;
+
+  nmhdr.hwndFrom = hwnd;
+  nmhdr.idFrom   = GetWindowLongA( hwnd, GWL_ID);
+  nmhdr.code     = NM_RELEASEDCAPTURE;
+  //TRACE("Sent notification from %x to %x\n", hwnd, GetParent(hwnd));
+
+  SendMessageA(GetParent(hwnd), WM_NOTIFY,
+                                (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
+
+  nmsc.nmhdr.hwndFrom = hwnd;
+  nmsc.nmhdr.idFrom   = GetWindowLongA(hwnd, GWL_ID);
+  nmsc.nmhdr.code     = MCN_SELECT;
+  MONTHCAL_CopyTime(&nmsc.stSelStart, &infoPtr->minSel);
+  MONTHCAL_CopyTime(&nmsc.stSelEnd, &infoPtr->maxSel);
+
+  SendMessageA(GetParent(hwnd), WM_NOTIFY,
+           (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
+
+  /* redraw if necessary */
+  if(redraw) {
+    hdc = GetDC(hwnd);
+    MONTHCAL_Refresh(hwnd, hdc);
+    ReleaseDC(hwnd, hdc);
+  }
+
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_Timer(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  HDC hdc;
+  BOOL redraw = FALSE;
+
+  //TRACE(" %d\n", wParam);
+  if(!infoPtr) return 0;
+
+  switch(wParam) {
+  case MC_NEXTMONTHTIMER:
+    redraw = TRUE;
+    MONTHCAL_GoToNextMonth(hwnd, infoPtr);
+    break;
+  case MC_PREVMONTHTIMER:
+    redraw = TRUE;
+    MONTHCAL_GoToPrevMonth(hwnd, infoPtr);
+    break;
+  //default:
+  //  ERR("got unknown timer\n");
+  }
+
+  /* redraw only if necessary */
+  if(redraw) {
+    hdc = GetDC(hwnd);
+    MONTHCAL_Refresh(hwnd, hdc);
+    ReleaseDC(hwnd, hdc);
+  }
+
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_MouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  MCHITTESTINFO ht;
+  HDC hdc;
+  int oldselday, selday, hit;
+  RECT r;
+
+  if(!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0;
+
+  ht.pt.x = LOWORD(lParam);
+  ht.pt.y = HIWORD(lParam);
+
+  hit = MONTHCAL_HitTest(hwnd, (LPARAM)&ht);
+
+  /* not on the calendar date numbers? bail out */
+  //TRACE("hit:%x\n",hit);
+  if((hit & MCHT_CALENDARDATE) != MCHT_CALENDARDATE) return 0;
+
+  selday = ht.st.wDay;
+  oldselday = infoPtr->curSelDay;
+  infoPtr->curSelDay = selday;
+  MONTHCAL_CalcPosFromDay(infoPtr, selday, ht.st. wMonth, &r);
+
+  if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
+    SYSTEMTIME selArray[2];
+    int i;
+
+    MONTHCAL_GetSelRange(hwnd, 0, (LPARAM)&selArray);
+    i = 0;
+    if(infoPtr->firstSelDay==selArray[0].wDay) i=1;
+    //TRACE("oldRange:%d %d %d %d\n", infoPtr->firstSelDay, selArray[0].wDay, selArray[1].wDay, i);
+    if(infoPtr->firstSelDay==selArray[1].wDay) {
+      /* 1st time we get here: selArray[0]=selArray[1])  */
+      /* if we're still at the first selected date, return */
+      if(infoPtr->firstSelDay==selday) goto done;
+      if(selday<infoPtr->firstSelDay) i = 0;
+    }
+
+    if(abs(infoPtr->firstSelDay - selday) >= infoPtr->maxSelCount) {
+      if(selday>infoPtr->firstSelDay)
+        selday = infoPtr->firstSelDay + infoPtr->maxSelCount;
+      else
+        selday = infoPtr->firstSelDay - infoPtr->maxSelCount;
+    }
+
+    if(selArray[i].wDay!=selday) {
+      //TRACE("newRange:%d %d %d %d\n", infoPtr->firstSelDay, selArray[0].wDay, selArray[1].wDay, i);
+
+      selArray[i].wDay = selday;
+
+      if(selArray[0].wDay>selArray[1].wDay) {
+        DWORD tempday;
+        tempday = selArray[1].wDay;
+        selArray[1].wDay = selArray[0].wDay;
+        selArray[0].wDay = tempday;
+      }
+
+      MONTHCAL_SetSelRange(hwnd, 0, (LPARAM)&selArray);
+    }
+  }
+
+done:
+
+  /* only redraw if the currently selected day changed */
+  if(oldselday != infoPtr->curSelDay) {
+    hdc = GetDC(hwnd);
+    MONTHCAL_Refresh(hwnd, hdc);
+    ReleaseDC(hwnd, hdc);
+  }
+
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_Paint(HWND hwnd, WPARAM wParam)
+{
+  HDC hdc;
+  PAINTSTRUCT ps;
+
+  hdc = (wParam==0 ? BeginPaint(hwnd, &ps) : (HDC)wParam);
+  MONTHCAL_Refresh(hwnd, hdc);
+  if(!wParam) EndPaint(hwnd, &ps);
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_KillFocus(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  HDC hdc;
+
+  //TRACE("\n");
+
+  hdc = GetDC(hwnd);
+  MONTHCAL_Refresh(hwnd, hdc);
+  ReleaseDC(hwnd, hdc);
+  InvalidateRect(hwnd, NULL, TRUE);
+
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_SetFocus(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  HDC hdc;
+
+  //TRACE("\n");
+
+  hdc = GetDC(hwnd);
+  MONTHCAL_Refresh(hwnd, hdc);
+  ReleaseDC(hwnd, hdc);
+
+  return 0;
+}
+
+/* sets the size information */
+static void MONTHCAL_UpdateSize(HWND hwnd)
+{
+  HDC hdc = GetDC(hwnd);
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+  RECT *rcClient=&infoPtr->rcClient;
+  RECT *rcDraw=&infoPtr->rcDraw;
+  RECT *title=&infoPtr->title;
+  RECT *prev=&infoPtr->titlebtnprev;
+  RECT *next=&infoPtr->titlebtnnext;
+  RECT *titlemonth=&infoPtr->titlemonth;
+  RECT *titleyear=&infoPtr->titleyear;
+  RECT *days=&infoPtr->days;
+  SIZE size;
+  TEXTMETRICA tm;
+  DWORD dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
+  HFONT currentFont;
+
+  currentFont = SelectObject(hdc, infoPtr->hFont);
+
+  /* FIXME: need a way to determine current font, without setting it */
+  /*
+  if(infoPtr->hFont!=currentFont) {
+    SelectObject(hdc, currentFont);
+    infoPtr->hFont=currentFont;
+    GetObjectA(currentFont, sizeof(LOGFONTA), &logFont);
+    logFont.lfWeight=FW_BOLD;
+    infoPtr->hBoldFont = CreateFontIndirectA(&logFont);
+  }
+  */
+
+  /* get the height and width of each day's text */
+  GetTextMetricsA(hdc, &tm);
+  infoPtr->textHeight = tm.tmHeight + tm.tmExternalLeading;
+  GetTextExtentPoint32A(hdc, "Sun", 3, &size);
+  infoPtr->textWidth = size.cx + 2;
+
+  /* retrieve the controls client rectangle info infoPtr->rcClient */
+  GetClientRect(hwnd, rcClient);
+
+  if(dwStyle & MCS_WEEKNUMBERS)
+    infoPtr->rcClient.right+=infoPtr->textWidth;
+
+  /* rcDraw is the rectangle the control is drawn in */
+  rcDraw->left = rcClient->left;
+  rcDraw->right = rcClient->right;
+  rcDraw->top = rcClient->top;
+  rcDraw->bottom = rcClient->bottom;
+
+  /* use DrawEdge to adjust the size of rcClient such that we */
+  /* do not overwrite the border when drawing the control */
+  DrawEdge((HDC)NULL, rcDraw, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
+
+
+  /* this is correct, the control does NOT expand vertically */
+  /* like it does horizontally */
+  /* make sure we don't move the controls bottom out of the client */
+  /* area */
+  if((rcDraw->top + 8 * infoPtr->textHeight + 5) < rcDraw->bottom) {
+    rcDraw->bottom = rcDraw->top + 8 * infoPtr->textHeight + 5;
+  }
+
+  /* calculate title area */
+  title->top    = rcClient->top + 1;
+  title->bottom = title->top + 2 * infoPtr->textHeight + 4;
+  title->left   = rcClient->left + 1;
+  title->right  = rcClient->right - 1;
+
+  /* recalculate the height and width increments and offsets */
+  infoPtr->width_increment = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) / 7.0;
+  infoPtr->height_increment = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) / 7.0;
+  infoPtr->left_offset = (infoPtr->rcDraw.right - infoPtr->rcDraw.left) - (infoPtr->width_increment * 7.0);
+  infoPtr->top_offset = (infoPtr->rcDraw.bottom - infoPtr->rcDraw.top) - (infoPtr->height_increment * 7.0);
+
+  /* set the dimensions of the next and previous buttons and center */
+  /* the month text vertically */
+  prev->top        = next->top    = title->top + 6;
+  prev->bottom = next->bottom = title->top + 2 * infoPtr->textHeight - 3;
+  prev->right  = title->left  + 28;
+  prev->left   = title->left  + 4;
+  next->left   = title->right - 28;
+  next->right  = title->right - 4;
+
+  /* titlemonth->left and right change based upon the current month */
+  /* and are recalculated in refresh as the current month may change */
+  /* without the control being resized */
+  titlemonth->bottom = titleyear->bottom = prev->top + 2 * infoPtr->textHeight - 3;
+  titlemonth->top    = titleyear->top    = title->top;
+
+  /* setup the dimensions of the rectangle we draw the names of the */
+  /* days of the week in */
+  days->left = infoPtr->left_offset;
+  if(dwStyle & MCS_WEEKNUMBERS) days->left+=infoPtr->textWidth;
+  days->right  = days->left + infoPtr->width_increment;
+  days->top    = title->bottom + 2;
+  days->bottom = title->bottom + infoPtr->textHeight + 2;
+
+  /* restore the originally selected font */
+  SelectObject(hdc, currentFont);
+
+  ReleaseDC(hwnd, hdc);
+}
+
+static LRESULT MONTHCAL_Size(HWND hwnd, int Width, int Height)
+{
+  //TRACE("(hwnd=%x, width=%d, height=%d)\n", hwnd, Width, Height);
+
+  MONTHCAL_UpdateSize(hwnd);
+
+  /* invalidate client area and erase background */
+  InvalidateRect(hwnd, NULL, TRUE);
+
+  return 0;
+}
+
+/* FIXME: check whether dateMin/dateMax need to be adjusted. */
+static LRESULT
+MONTHCAL_Create(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr;
+  LOGFONTA      logFont;
+
+  /* allocate memory for info structure */
+  infoPtr =(MONTHCAL_INFO*)COMCTL32_Alloc(sizeof(MONTHCAL_INFO));
+  SetWindowLongA(hwnd, 0, (DWORD)infoPtr);
+
+  if(infoPtr == NULL) {
+    //ERR( "could not allocate info memory!\n");
     return 0;
-}
-
-
-
-static LRESULT
-MONTHCAL_MouseMove (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
-        MCHITTESTINFO ht;
-        HDC hdc;
-        int selday,hit;
-        RECT r;
-
-        if (!(infoPtr->status & MC_SEL_LBUTDOWN)) return 0;
-
-        ht.pt.x=LOWORD(lParam);
-        ht.pt.y=HIWORD(lParam);
-
-        hit=MONTHCAL_HitTest (hwnd, (LPARAM) &ht);
-
-        /* not on the calendar date numbers? bail out */
-        //TRACE ("hit:%x\n",hit);
-        if ((hit & MCHT_CALENDARDATE) !=MCHT_CALENDARDATE) return 0;
-
-        selday=ht.st.wDay;
-        infoPtr->curSelDay=selday;
-        MONTHCAL_CalcPosFromDay (infoPtr,selday,ht.st.wMonth,&r);
-
-        if ( GetWindowLongA( hwnd, GWL_STYLE) & MCS_MULTISELECT)  {
-                SYSTEMTIME selArray[2];
-                int i;
-
-        MONTHCAL_GetSelRange (hwnd,0,(LPARAM) &selArray);
-                i=0;
-                if (infoPtr->firstSelDay==selArray[0].wDay) i=1;
-                //TRACE ("oldRange:%d %d %d %d\n",infoPtr->firstSelDay,selArray[0].wDay,selArray[1].wDay,i);
-                if (infoPtr->firstSelDay==selArray[1].wDay) {
-                                /* 1st time we get here: selArray[0]=selArray[1])  */
-                                /* if we're still at the first selected date, return */
-                        if (infoPtr->firstSelDay==selday) goto done;
-
-                        if (selday<infoPtr->firstSelDay) i=0;
-                }
-
-                if (abs(infoPtr->firstSelDay - selday) >= infoPtr->maxSelCount) {
-                        if (selday>infoPtr->firstSelDay)
-                                selday=infoPtr->firstSelDay+infoPtr->maxSelCount;
-                        else
-                                selday=infoPtr->firstSelDay-infoPtr->maxSelCount;
-                }
-
-                if (selArray[i].wDay!=selday) {
-
-                //TRACE ("newRange:%d %d %d %d\n",infoPtr->firstSelDay,selArray[0].wDay,selArray[1].wDay,i);
-
-                        selArray[i].wDay=selday;
-
-
-                        if (selArray[0].wDay>selArray[1].wDay) {
-                                DWORD tempday;
-                                tempday=selArray[1].wDay;
-                                selArray[1].wDay=selArray[0].wDay;
-                                selArray[0].wDay=tempday;
-                        }
-
-                MONTHCAL_SetSelRange (hwnd,0,(LPARAM) &selArray);
-                }
-        }
-
-done:
-
-        hdc=GetDC (hwnd);
-        MONTHCAL_Refresh (hwnd, hdc);
-        ReleaseDC (hwnd, hdc);
-
-        return 0;
-}
-
-static LRESULT
-MONTHCAL_Paint (HWND hwnd, WPARAM wParam)
-{
-    HDC hdc;
-    PAINTSTRUCT ps;
-
-    hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
-    MONTHCAL_Refresh (hwnd, hdc);
-    if(!wParam)
-    EndPaint (hwnd, &ps);
+  }
+  if((MONTHCAL_INFO*)GetWindowLongA(hwnd, 0) != infoPtr) {
+    //ERR( "pointer assignment error!\n");
     return 0;
-}
-
-static LRESULT
-MONTHCAL_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    HDC hdc;
-
-    //TRACE ("\n");
-
-    hdc = GetDC (hwnd);
-    MONTHCAL_Refresh (hwnd, hdc);
-    ReleaseDC (hwnd, hdc);
-    InvalidateRect (hwnd, NULL, TRUE);
-
-    return 0;
-}
-
-
-static LRESULT
-MONTHCAL_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    HDC hdc;
-
-    //TRACE ("\n");
-
-    hdc = GetDC (hwnd);
-    MONTHCAL_Refresh (hwnd, hdc);
-    ReleaseDC (hwnd, hdc);
-
-    return 0;
-}
-
-
-/* FIXME: check whether dateMin/dateMax need to be adjusted. */
-
-
-static LRESULT
-MONTHCAL_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    MONTHCAL_INFO *infoPtr;
-        LOGFONTA        logFont;
-
-    /* allocate memory for info structure */
-    infoPtr = (MONTHCAL_INFO *)COMCTL32_Alloc (sizeof(MONTHCAL_INFO));
-    SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
-
-        if (infoPtr == NULL) {
-        //ERR ( "could not allocate info memory!\n");
-        return 0;
-    }
-    if ((MONTHCAL_INFO*) GetWindowLongA( hwnd, 0) != infoPtr) {
-        //ERR ( "pointer assignment error!\n");
-        return 0;
-    }
-
-
-    infoPtr->hFont=GetStockObject(DEFAULT_GUI_FONT);
-                GetObjectA (infoPtr->hFont, sizeof (LOGFONTA), &logFont);
-        logFont.lfWeight=FW_BOLD;
-        infoPtr->hBoldFont = CreateFontIndirectA (&logFont);
-
-    /* initialize info structure */
-   /* FIXME: calculate systemtime ->> localtime (substract timezoneinfo) */
-
-        GetSystemTime (&infoPtr->todaysDate);
-        infoPtr->firstDay  = 0;
-        infoPtr->currentMonth = infoPtr->todaysDate.wMonth;
-        infoPtr->currentYear= infoPtr->todaysDate.wYear;
-        MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->minDate);
-        MONTHCAL_CopyTime (&infoPtr->todaysDate,&infoPtr->maxDate);
-        infoPtr->maxSelCount=6;
-        infoPtr->monthRange=3;
-        infoPtr->monthdayState=COMCTL32_Alloc
-                           (infoPtr->monthRange*sizeof(MONTHDAYSTATE));
-        infoPtr->titlebk     = GetSysColor (COLOR_GRAYTEXT);
-        infoPtr->titletxt    = GetSysColor (COLOR_WINDOW);
-        infoPtr->monthbk     = GetSysColor (COLOR_WINDOW);
-        infoPtr->trailingtxt = GetSysColor (COLOR_GRAYTEXT);
-        infoPtr->bk                  = GetSysColor (COLOR_WINDOW);
-        infoPtr->txt         = GetSysColor (COLOR_WINDOWTEXT);
-
-    return 0;
-}
-
-
-static LRESULT
-MONTHCAL_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
-{
-    MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr (hwnd);
-
-    /* free month calendar info data */
-    COMCTL32_Free (infoPtr);
-
-    return 0;
-}
-
+  }
+
+  infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
+  GetObjectA(infoPtr->hFont, sizeof(LOGFONTA), &logFont);
+  logFont.lfWeight = FW_BOLD;
+  infoPtr->hBoldFont = CreateFontIndirectA(&logFont);
+
+  /* initialize info structure */
+  /* FIXME: calculate systemtime ->> localtime(substract timezoneinfo) */
+
+  GetSystemTime(&infoPtr->todaysDate);
+  infoPtr->firstDay = 0;
+  infoPtr->currentMonth = infoPtr->todaysDate.wMonth;
+  infoPtr->currentYear = infoPtr->todaysDate.wYear;
+  MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->minDate);
+  MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
+  infoPtr->maxSelCount  = 6;
+  infoPtr->monthRange = 3;
+  infoPtr->monthdayState = COMCTL32_Alloc
+                         (infoPtr->monthRange * sizeof(MONTHDAYSTATE));
+  infoPtr->titlebk     = GetSysColor(COLOR_ACTIVECAPTION);
+  infoPtr->titletxt    = GetSysColor(COLOR_WINDOW);
+  infoPtr->monthbk     = GetSysColor(COLOR_WINDOW);
+  infoPtr->trailingtxt = GetSysColor(COLOR_GRAYTEXT);
+  infoPtr->bk          = GetSysColor(COLOR_WINDOW);
+  infoPtr->txt         = GetSysColor(COLOR_WINDOWTEXT);
+
+  /* call MONTHCAL_UpdateSize to set all of the dimensions */
+  /* of the control */
+  MONTHCAL_UpdateSize(hwnd);
+
+  return 0;
+}
+
+
+static LRESULT
+MONTHCAL_Destroy(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
+
+  /* free month calendar info data */
+  COMCTL32_Free(infoPtr);
+
+  return 0;
+}
 
 
 static LRESULT WINAPI
-MONTHCAL_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
-
-    switch (uMsg)
-    {
-
-        case MCM_GETCURSEL:
-        return MONTHCAL_GetCurSel (hwnd, wParam, lParam);
-
-        case MCM_SETCURSEL:
-        return MONTHCAL_SetCurSel (hwnd, wParam, lParam);
-
-        case MCM_GETMAXSELCOUNT:
-        return MONTHCAL_GetMaxSelCount (hwnd, wParam, lParam);
-
-        case MCM_SETMAXSELCOUNT:
-        return MONTHCAL_SetMaxSelCount (hwnd, wParam, lParam);
-
-        case MCM_GETSELRANGE:
-        return MONTHCAL_GetSelRange (hwnd, wParam, lParam);
-
-        case MCM_SETSELRANGE:
-        return MONTHCAL_SetSelRange (hwnd, wParam, lParam);
-
-        case MCM_GETMONTHRANGE:
-        return MONTHCAL_GetMonthRange (hwnd, wParam, lParam);
-
-        case MCM_SETDAYSTATE:
-        return MONTHCAL_SetDayState (hwnd, wParam, lParam);
-
-        case MCM_GETMINREQRECT:
-        return MONTHCAL_GetMinReqRect (hwnd, wParam, lParam);
-
-        case MCM_GETCOLOR:
-             return MONTHCAL_GetColor (hwnd, wParam, lParam);
-
-        case MCM_SETCOLOR:
-             return MONTHCAL_SetColor (hwnd, wParam, lParam);
-
-        case MCM_GETTODAY:
-             return MONTHCAL_GetToday (hwnd, wParam, lParam);
-
-        case MCM_SETTODAY:
-             return MONTHCAL_SetToday (hwnd, wParam, lParam);
-
-        case MCM_HITTEST:
-            return MONTHCAL_HitTest (hwnd,lParam);
-
-        case MCM_GETFIRSTDAYOFWEEK:
-        return MONTHCAL_GetFirstDayOfWeek (hwnd, wParam, lParam);
-
-        case MCM_SETFIRSTDAYOFWEEK:
-        return MONTHCAL_SetFirstDayOfWeek (hwnd, wParam, lParam);
-
-        case MCM_GETRANGE:
-             return MONTHCAL_GetRange (hwnd, wParam, lParam);
-
-        case MCM_SETRANGE:
-             return MONTHCAL_SetRange (hwnd, wParam, lParam);
-
-        case MCM_GETMONTHDELTA:
-             return MONTHCAL_GetMonthDelta (hwnd, wParam, lParam);
-
-        case MCM_SETMONTHDELTA:
-             return MONTHCAL_SetMonthDelta (hwnd, wParam, lParam);
-
-        case MCM_GETMAXTODAYWIDTH:
-             return MONTHCAL_GetMaxTodayWidth (hwnd);
-
-        case WM_GETDLGCODE:
-        return DLGC_WANTARROWS | DLGC_WANTCHARS;
-
-    case WM_KILLFOCUS:
-        return MONTHCAL_KillFocus (hwnd, wParam, lParam);
-
-    case WM_LBUTTONDOWN:
-        return MONTHCAL_LButtonDown (hwnd, wParam, lParam);
-
-    case WM_MOUSEMOVE:
-        return MONTHCAL_MouseMove (hwnd, wParam, lParam);
-
-    case WM_LBUTTONUP:
-        return MONTHCAL_LButtonUp (hwnd, wParam, lParam);
-
-    case WM_PAINT:
-        return MONTHCAL_Paint (hwnd, wParam);
-
-    case WM_SETFOCUS:
-        return MONTHCAL_SetFocus (hwnd, wParam, lParam);
-
-        case WM_CREATE:
-            return MONTHCAL_Create (hwnd, wParam, lParam);
-
-        case WM_TIMER:
-            return MONTHCAL_Timer (hwnd, wParam, lParam);
-
-        case WM_DESTROY:
-            return MONTHCAL_Destroy (hwnd, wParam, lParam);
-
-        default:
-            //if (uMsg >= WM_USER)
-            //    ERR ( "unknown msg %04x wp=%08x lp=%08lx\n",
-            //         uMsg, wParam, lParam);
-            return DefWindowProcA (hwnd, uMsg, wParam, lParam);
-    }
-    return 0;
+MONTHCAL_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+  switch(uMsg)
+  {
+  case MCM_GETCURSEL:
+    return MONTHCAL_GetCurSel(hwnd, wParam, lParam);
+
+  case MCM_SETCURSEL:
+    return MONTHCAL_SetCurSel(hwnd, wParam, lParam);
+
+  case MCM_GETMAXSELCOUNT:
+    return MONTHCAL_GetMaxSelCount(hwnd, wParam, lParam);
+
+  case MCM_SETMAXSELCOUNT:
+    return MONTHCAL_SetMaxSelCount(hwnd, wParam, lParam);
+
+  case MCM_GETSELRANGE:
+    return MONTHCAL_GetSelRange(hwnd, wParam, lParam);
+
+  case MCM_SETSELRANGE:
+    return MONTHCAL_SetSelRange(hwnd, wParam, lParam);
+
+  case MCM_GETMONTHRANGE:
+    return MONTHCAL_GetMonthRange(hwnd, wParam, lParam);
+
+  case MCM_SETDAYSTATE:
+    return MONTHCAL_SetDayState(hwnd, wParam, lParam);
+
+  case MCM_GETMINREQRECT:
+    return MONTHCAL_GetMinReqRect(hwnd, wParam, lParam);
+
+  case MCM_GETCOLOR:
+    return MONTHCAL_GetColor(hwnd, wParam, lParam);
+
+  case MCM_SETCOLOR:
+    return MONTHCAL_SetColor(hwnd, wParam, lParam);
+
+  case MCM_GETTODAY:
+    return MONTHCAL_GetToday(hwnd, wParam, lParam);
+
+  case MCM_SETTODAY:
+    return MONTHCAL_SetToday(hwnd, wParam, lParam);
+
+  case MCM_HITTEST:
+    return MONTHCAL_HitTest(hwnd,lParam);
+
+  case MCM_GETFIRSTDAYOFWEEK:
+    return MONTHCAL_GetFirstDayOfWeek(hwnd, wParam, lParam);
+
+  case MCM_SETFIRSTDAYOFWEEK:
+    return MONTHCAL_SetFirstDayOfWeek(hwnd, wParam, lParam);
+
+  case MCM_GETRANGE:
+    return MONTHCAL_GetRange(hwnd, wParam, lParam);
+
+  case MCM_SETRANGE:
+    return MONTHCAL_SetRange(hwnd, wParam, lParam);
+
+  case MCM_GETMONTHDELTA:
+    return MONTHCAL_GetMonthDelta(hwnd, wParam, lParam);
+
+  case MCM_SETMONTHDELTA:
+    return MONTHCAL_SetMonthDelta(hwnd, wParam, lParam);
+
+  case MCM_GETMAXTODAYWIDTH:
+    return MONTHCAL_GetMaxTodayWidth(hwnd);
+
+  case WM_GETDLGCODE:
+    return DLGC_WANTARROWS | DLGC_WANTCHARS;
+
+  case WM_KILLFOCUS:
+    return MONTHCAL_KillFocus(hwnd, wParam, lParam);
+
+  case WM_LBUTTONDOWN:
+    return MONTHCAL_LButtonDown(hwnd, wParam, lParam);
+
+  case WM_MOUSEMOVE:
+    return MONTHCAL_MouseMove(hwnd, wParam, lParam);
+
+  case WM_LBUTTONUP:
+    return MONTHCAL_LButtonUp(hwnd, wParam, lParam);
+
+  case WM_PAINT:
+    return MONTHCAL_Paint(hwnd, wParam);
+
+  case WM_SETFOCUS:
+    return MONTHCAL_SetFocus(hwnd, wParam, lParam);
+
+  case WM_SIZE:
+    return MONTHCAL_Size(hwnd, (int)SLOWORD(lParam), (int)SHIWORD(lParam));
+
+  case WM_CREATE:
+    return MONTHCAL_Create(hwnd, wParam, lParam);
+
+  case WM_TIMER:
+    return MONTHCAL_Timer(hwnd, wParam, lParam);
+
+  case WM_DESTROY:
+    return MONTHCAL_Destroy(hwnd, wParam, lParam);
+
+  default:
+    //if(uMsg >= WM_USER)
+    //  ERR( "unknown msg %04x wp=%08x lp=%08lx\n", uMsg, wParam, lParam);
+    return DefWindowProcA(hwnd, uMsg, wParam, lParam);
+  }
+  return 0;
 }
 
 
 void
-MONTHCAL_Register (void)
-{
-    WNDCLASSA wndClass;
+MONTHCAL_Register(void)
+{
+  WNDCLASSA wndClass;
 
 //SvL: Don't check this now
-//    if (GlobalFindAtomA (MONTHCAL_CLASSA)) return;
-
-    ZeroMemory (&wndClass, sizeof(WNDCLASSA));
-    wndClass.style         = CS_GLOBALCLASS;
-    wndClass.lpfnWndProc   = (WNDPROC)MONTHCAL_WindowProc;
-    wndClass.cbClsExtra    = 0;
-    wndClass.cbWndExtra    = sizeof(MONTHCAL_INFO *);
-    wndClass.hCursor       = LoadCursorA (0, IDC_ARROWA);
-    wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-    wndClass.lpszClassName = MONTHCAL_CLASSA;
-
-    RegisterClassA (&wndClass);
+//  if(GlobalFindAtomA(MONTHCAL_CLASSA)) return;
+
+  ZeroMemory(&wndClass, sizeof(WNDCLASSA));
+  wndClass.style         = CS_GLOBALCLASS;
+  wndClass.lpfnWndProc   = (WNDPROC)MONTHCAL_WindowProc;
+  wndClass.cbClsExtra    = 0;
+  wndClass.cbWndExtra    = sizeof(MONTHCAL_INFO *);
+  wndClass.hCursor       = LoadCursorA(0, IDC_ARROWA);
+  wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+  wndClass.lpszClassName = MONTHCAL_CLASSA;
+
+  RegisterClassA(&wndClass);
 }
 
 
 void
-MONTHCAL_Unregister (void)
-{
-    if (GlobalFindAtomA (MONTHCAL_CLASSA))
-        UnregisterClassA (MONTHCAL_CLASSA, (HINSTANCE)NULL);
-}
-
+MONTHCAL_Unregister(void)
+{
+  if(GlobalFindAtomA(MONTHCAL_CLASSA))
+    UnregisterClassA(MONTHCAL_CLASSA, (HINSTANCE)NULL);
+}
Index: trunk/src/comctl32/tooltips.c
===================================================================
--- trunk/src/comctl32/tooltips.c	(revision 2631)
+++ trunk/src/comctl32/tooltips.c	(revision 2635)
@@ -1,3 +1,3 @@
-/* $Id: tooltips.c,v 1.19 1999-12-27 17:13:40 cbratschi Exp $ */
+/* $Id: tooltips.c,v 1.20 2000-02-04 17:02:09 cbratschi Exp $ */
 /*
  * Tool tip control
@@ -17,5 +17,5 @@
  */
 
-/* WINE 991031 level */
+/* WINE 20000130 level */
 
 #include <string.h>
Index: trunk/src/comctl32/treeview.c
===================================================================
--- trunk/src/comctl32/treeview.c	(revision 2631)
+++ trunk/src/comctl32/treeview.c	(revision 2635)
@@ -1,3 +1,3 @@
-/* $Id: treeview.c,v 1.21 1999-12-21 17:01:38 cbratschi Exp $ */
+/* $Id: treeview.c,v 1.22 2000-02-04 17:02:09 cbratschi Exp $ */
 /* Treeview control
  *
@@ -85,5 +85,5 @@
 TREEVIEW_DoSelectItem (HWND hwnd, INT action, HTREEITEM newSelect, INT cause);
 static void
-TREEVIEW_Refresh (HWND hwnd);
+TREEVIEW_Refresh (HWND hwnd,HDC hdc);
 
 static LRESULT CALLBACK
@@ -129,5 +129,4 @@
   TREEVIEW_INFO *infoPtr,
   TREEVIEW_ITEM *tvItem)
-
 {
   TREEVIEW_ITEM *wineItem = tvItem;
@@ -394,6 +393,5 @@
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 
-//  TRACE (treeview,"\n");
-  if (infoPtr==NULL) return 0;
+  //TRACE (treeview,"\n");
 
   if ((INT)wParam == TVSIL_NORMAL)
@@ -411,5 +409,5 @@
     HIMAGELIST himlTemp;
 
-//    TRACE (treeview,"\n");
+    //TRACE (treeview,"\n");
     switch ((INT)wParam) {
         case TVSIL_NORMAL:
@@ -485,5 +483,5 @@
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
 
-  TRACE("\n");
+  //TRACE("\n");
   return (LRESULT) infoPtr->clrInsertMark;
 }
@@ -495,5 +493,5 @@
   COLORREF prevColor=infoPtr->clrInsertMark;
 
-  TRACE("%d %ld\n",wParam,lParam);
+  //TRACE("%d %ld\n",wParam,lParam);
   infoPtr->clrInsertMark=(COLORREF) lParam;
   return (LRESULT) prevColor;
@@ -504,12 +502,17 @@
 {
   TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
-
-  FIXME("%d %ld\n",wParam,lParam);
+  HDC hdc;
+
+  //FIXME("%d %ld\n",wParam,lParam);
   if (!TREEVIEW_ValidItem (infoPtr, (HTREEITEM)lParam)) return 0;
-  FIXME("%d %ld\n",wParam,lParam);
+  //FIXME("%d %ld\n",wParam,lParam);
 
   infoPtr->insertBeforeorAfter=(BOOL) wParam;
   infoPtr->insertMarkItem=(HTREEITEM) lParam;
-  TREEVIEW_Refresh (hwnd);
+
+  hdc = GetDC(hwnd);
+  TREEVIEW_Refresh(hwnd,hdc);
+  ReleaseDC(hwnd,hdc);
+
   return 1;
 }
@@ -714,5 +717,5 @@
         imageIndex=wineItem->state>>12;
         imageIndex++;          /* yeah, right */
-        TRACE ("imindex:%d\n",imageIndex);
+        //TRACE ("imindex:%d\n",imageIndex);
     if ((himlp) && (imageIndex))
     {
@@ -786,5 +789,5 @@
 
     if (wineItem->pszText== LPSTR_TEXTCALLBACKA) {
-      TRACE("LPSTR_TEXTCALLBACK\n");
+      //TRACE("LPSTR_TEXTCALLBACK\n");
       TREEVIEW_SendDispInfoNotify (hwnd, wineItem, TVN_GETDISPINFO, TVIF_TEXT);
     }
@@ -864,7 +867,7 @@
   /* Draw insertion mark if necessary */
 
-  if (infoPtr->insertMarkItem)
-                TRACE ("item:%d,mark:%d\n", (int)wineItem->hItem,
-                               (int) infoPtr->insertMarkItem);
+  //if (infoPtr->insertMarkItem)
+  //              TRACE ("item:%d,mark:%d\n", (int)wineItem->hItem,
+  //                             (int) infoPtr->insertMarkItem);
   if (wineItem->hItem==infoPtr->insertMarkItem) {
                 HPEN hNewPen, hOldPen;
@@ -896,5 +899,5 @@
                 cditem=TREEVIEW_SendCustomDrawItemNotify
                        (hwnd, hdc, wineItem, CDDS_ITEMPOSTPAINT);
-                TRACE("postpaint:cditem-app returns 0x%x\n",cditem);
+                //TRACE("postpaint:cditem-app returns 0x%x\n",cditem);
         }
 
@@ -909,4 +912,5 @@
   HTREEITEM     *iItem;
   LPRECT        lpRect   = (LPRECT)lParam;
+  HDC hdc;
 
 //  TRACE (treeview,"\n");
@@ -914,9 +918,13 @@
    * validate parameters
    */
-  if ( (infoPtr==NULL) || (lpRect == NULL) )
+  if (lpRect == NULL)
     return FALSE;
 
   if (infoPtr->Timer & TV_REFRESH_TIMER_SET)
-                TREEVIEW_Refresh (hwnd);        /* we want a rect for the current view */
+  {
+    hdc = GetDC(hwnd);
+    TREEVIEW_Refresh(hwnd,hdc);        /* we want a rect for the current view */
+    ReleaseDC(hwnd,hdc);
+  }
 
   /*
@@ -998,6 +1006,6 @@
 
   if (tvItem->mask & TVIF_STATE) {
-                TRACE ("prevstate,state,mask:%x,%x,%x\n",wineItem->state,tvItem->state,
-tvItem->stateMask);
+                //TRACE ("prevstate,state,mask:%x,%x,%x\n",wineItem->state,tvItem->state,
+//tvItem->stateMask);
         wineItem->state&= ~tvItem->stateMask;
                 wineItem->state|= (tvItem->state & tvItem->stateMask);
@@ -1039,12 +1047,11 @@
 
 static void
-TREEVIEW_Refresh (HWND hwnd)
+TREEVIEW_Refresh (HWND hwnd,HDC hdc)
 
 {
     TREEVIEW_INFO *infoPtr = TREEVIEW_GetInfoPtr(hwnd);
-        TEXTMETRICA tm;
-        HBRUSH hbrBk;
+    TEXTMETRICA tm;
+    HBRUSH hbrBk;
     RECT rect;
-        HDC hdc;
     INT iItem, indent, x, y, cx, height, itemHeight;
     INT viewtop,viewbottom,viewleft,viewright;
@@ -1052,6 +1059,4 @@
 
     //TRACE("\n");
-
-        hdc=GetDC (hwnd);
 
     if (infoPtr->Timer & TV_REFRESH_TIMER_SET) {
@@ -1067,11 +1072,8 @@
                                                 (hwnd, CDDS_PREPAINT, hdc, rect);
 
-        if (infoPtr->cdmode==CDRF_SKIPDEFAULT) {
-                  ReleaseDC (hwnd, hdc);
-                  return;
-        }
-
-        infoPtr->uVisibleHeight= rect.bottom-rect.top;
-        infoPtr->uVisibleWidth= rect.right-rect.left;
+    if (infoPtr->cdmode==CDRF_SKIPDEFAULT) return;
+
+    infoPtr->uVisibleHeight= rect.bottom-rect.top;
+    infoPtr->uVisibleWidth= rect.right-rect.left;
 
     viewtop=infoPtr->cy;
@@ -1188,5 +1190,4 @@
                                                                 (hwnd, CDDS_POSTPAINT, hdc, rect);
 
-    ReleaseDC (hwnd, hdc);
     //TRACE("done\n");
 }
@@ -1199,5 +1200,4 @@
 
 //  TRACE (treeview, " %d\n",wParam);
-  if (!infoPtr) return FALSE;
 
   switch (wParam) {
@@ -1312,7 +1312,6 @@
   TREEVIEW_ITEM *wineItem, *returnItem;
   INT iItem, retval, flag;
-
-
-  if (!infoPtr) return FALSE;
+  HDC hdc;
+
   flag  = (INT) wParam;
   iItem = (INT) lParam;
@@ -1323,9 +1322,10 @@
         case TVGN_CARET:retval=(INT)infoPtr->selectedItem;
                                         break;
-        case TVGN_FIRSTVISIBLE:
-                                TREEVIEW_Refresh (hwnd);
-/* FIXME:we should only recalculate, not redraw */
-                                        retval=(INT)infoPtr->firstVisible;
-                                        break;
+	case TVGN_FIRSTVISIBLE: /* FIXME:we should only recalculate, not redraw */
+  					hdc = GetDC (hwnd);
+  					TREEVIEW_Refresh (hwnd, hdc);
+  					ReleaseDC(hwnd,hdc);
+					retval=(INT)infoPtr->firstVisible;
+					break;
         case TVGN_DROPHILITE:
                                         retval=(INT)infoPtr->dropItem;
@@ -1983,5 +1983,4 @@
    }
 
-
    TREEVIEW_QueueRefresh (hwnd);
 
@@ -2049,5 +2048,4 @@
 
 //  TRACE (treeview,"\n");
-  if (!infoPtr) return FALSE;
 
   if (lParam == (INT)TVI_ROOT) {
@@ -2243,14 +2241,17 @@
 
 
-
 static LRESULT
 TREEVIEW_StyleChanged (HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
-//  TRACE (treeview,"(%x %lx)\n",wParam,lParam);
-
-  TREEVIEW_Refresh(hwnd);
+  HDC hdc;
+
+  //TRACE("(%x %lx)\n",wParam,lParam);
+  hdc = GetDC (hwnd);
+  TREEVIEW_Refresh (hwnd, hdc);
+  ReleaseDC(hwnd,hdc);
 
   return 0;
 }
+
 
 static LRESULT
@@ -2263,5 +2264,5 @@
         HDC hdc;
 
-    TRACE("wnd %x, style %lx\n",hwnd,dwStyle);
+    //TRACE("wnd %x, style %lx\n",hwnd,dwStyle);
       /* allocate memory for info structure */
     infoPtr = (TREEVIEW_INFO *) COMCTL32_Alloc (sizeof(TREEVIEW_INFO));
@@ -2270,10 +2271,10 @@
 
     if (infoPtr == NULL) {
-                ERR("could not allocate info memory!\n");
+                //ERR("could not allocate info memory!\n");
                 return 0;
     }
 
     if ((TREEVIEW_INFO*) GetWindowLongA( hwnd, 0) != infoPtr) {
-                ERR("pointer assignment error!\n");
+                //ERR("pointer assignment error!\n");
                 return 0;
     }
@@ -2308,5 +2309,5 @@
     infoPtr->pCallBackSort=NULL;
     infoPtr->uScrollTime = 300;  /* milliseconds */
-
+    	infoPtr->wpEditOrig = NULL; /* we haven't subclassed anything yet */
         infoPtr->hwndToolTip=0;
     if (!(dwStyle & TVS_NOTOOLTIPS)) {   /* Create tooltip control */
@@ -2342,7 +2343,4 @@
         SendMessageA (infoPtr->hwndToolTip, TTM_ADDTOOLA, 0, (LPARAM)&ti);
     }
-
-   // @@@PH 1999/11/05
-    infoPtr->wpEditOrig = NULL; /* no subclass */
 
         infoPtr->hwndEdit = CreateWindowExA (
@@ -2370,7 +2368,7 @@
 
                 hbmLoad = LoadBitmapA (COMCTL32_hModule, MAKEINTRESOURCEA(IDT_CHECK));
-                TRACE ("%x\n",hbmLoad);
+                //TRACE ("%x\n",hbmLoad);
         nIndex = ImageList_AddMasked (infoPtr->himlState, hbmLoad, CLR_DEFAULT);
-                TRACE ("%d\n",nIndex);
+                //TRACE ("%d\n",nIndex);
                 DeleteObject (hbmLoad);
         }
@@ -2389,6 +2387,4 @@
 
    TREEVIEW_RemoveTree (hwnd);
-
-   //@@@PH 1999/11/05 set infoPtr to NULL
    SetWindowLongA( hwnd, 0, (DWORD)NULL);
 
@@ -2412,5 +2408,5 @@
 //    TRACE (treeview,"\n");
     hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam;
-    TREEVIEW_Refresh (hwnd);
+    TREEVIEW_Refresh (hwnd,hdc);
     if(!wParam)
         EndPaint (hwnd, &ps);
@@ -2919,5 +2915,5 @@
 done:
   lpht->hItem=wineItem->hItem;
-  TRACE ("(%ld,%ld):result %x\n",lpht->pt.x,lpht->pt.y,lpht->flags);
+  //TRACE ("(%ld,%ld):result %x\n",lpht->pt.x,lpht->pt.y,lpht->flags);
 
   return (LRESULT) wineItem->hItem;
@@ -3050,5 +3046,5 @@
   ht.pt.y = (INT)HIWORD(lParam);
 
-  TRACE("\n");
+  //TRACE("\n");
 
   /* Return true to cancel default behaviour */
@@ -3058,5 +3054,5 @@
   /* Get the item */
   iItem = TREEVIEW_HitTest (hwnd, (LPARAM) &ht);
-  TRACE ("%d\n",iItem);
+  //TRACE ("%d\n",iItem);
   if (!iItem)
     return 0;
@@ -3085,5 +3081,5 @@
       }
 
-                TRACE("Edit started for %s.\n", wineItem->pszText);
+                //TRACE("Edit started for %s.\n", wineItem->pszText);
                 infoPtr->editItem = wineItem->hItem;
 
@@ -3119,8 +3115,8 @@
                         int state;                                       /* to toggle the current state */
                         state=1-(wineItem->state>>12);
-                        TRACE ("state:%x\n", state);
+                        //TRACE ("state:%x\n", state);
                         wineItem->state&= ~TVIS_STATEIMAGEMASK;
                         wineItem->state|=state<<12;
-                        TRACE ("state:%x\n", wineItem->state);
+                        //TRACE ("state:%x\n", wineItem->state);
                         TREEVIEW_QueueRefresh (hwnd);
                 }
@@ -3688,4 +3684,10 @@
 TREEVIEW_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
+   if (uMsg==WM_CREATE)
+		return TREEVIEW_Create (hwnd, wParam, lParam);
+
+   if (!TREEVIEW_GetInfoPtr(hwnd))
+       return DefWindowProcA (hwnd, uMsg, wParam, lParam);
+
     switch (uMsg) {
         case TVM_INSERTITEMA:
@@ -3835,7 +3837,4 @@
         case WM_COMMAND:
                 return TREEVIEW_Command (hwnd, wParam, lParam);
-
-        case WM_CREATE:
-                return TREEVIEW_Create (hwnd, wParam, lParam);
 
         case WM_DESTROY:
