DateTime and MonthCal control fixes
Krzysztof Foltman
kfoltman at portal.onet.pl
Mon Apr 19 16:10:58 CDT 2004
This is my first Wine patch. It's supposed to fix a few bugs in Date
Time and Month Calendar controls. Most of changes are related to
interaction between date picker and the embedded (dropdown) calendar,
which is why I sent one patch and not two.
Changes in datetime:
- make monthcal a child of datetime (it was a sibling before, causing
completely incorrect message flow)
- update monthcal after date change in datetime
- choose different coordinates when DTS_SHOWNONE is not used
- embedded monthcal is now 200 pixels wide (about same width as on my
Windows machine, looks definitely better; I'm not sure if it should be a
fixed constant or it should be calculated from font size)
- selecting a day in embedded monthcal updates the datetime and hides
the monthcal
- changing months/years by clicking month name/year in title bar works
- embedded month calendar is correctly destroyed (it used to stick on
the screen long after the datetime's container was closed)
Changes in monthcal:
- next/prev month don't stick anymore
- min/max ranges initialized to some reasonable values
- fixed some bugs caused by reversed order of arguments of MONTHCAL_CopyTime
- update current month/year after setting current date
- changing months etc doesn't send MCN_SELECT (which could be sent only
after a particular day was click)
- changed (hit && MCHT_CALENDARDATE) to (hit == MCHT_CALENDARDATE) - the
former looks too much like a bug in this context (testing bit flags with
&& ? can't be right) - and behaves like a bug too
Known bugs made/left:
- Implementation still incomplete (there's at least one unhandled MCN_
value), however, it's complete enough for some Polish accounting program
I need to have running ;-)
- I didn't check correctness of min/max range behaviour yet (don't even
know if they're implemented)
- default min/max date ranges don't have proper month&day set (OK, I'm
lazy and don't care about 'em as long as they're half-decent)
I hope you'll like 'em :-)
Krzysztof
-------------- next part --------------
Index: datetime.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/datetime.c,v
retrieving revision 1.42
diff -u -r1.42 datetime.c
--- datetime.c 20 Nov 2003 22:04:14 -0000 1.42
+++ datetime.c 19 Apr 2004 20:52:20 -0000
@@ -148,13 +148,14 @@
TRACE("%p %04x %08lx\n",hwnd, wParam, lParam);
if (!lParam) return 0;
- TRACE("%04d/%02d/%02d %02d:%02d:%02d)\n",
+ TRACE("%04d/%02d/%02d %02d:%02d:%02d\n",
lprgSysTimeArray->wYear, lprgSysTimeArray->wMonth, lprgSysTimeArray->wDay,
lprgSysTimeArray->wHour, lprgSysTimeArray->wMinute, lprgSysTimeArray->wSecond);
if (wParam==GDT_VALID) {
infoPtr->dateValid = TRUE;
MONTHCAL_CopyTime (lprgSysTimeArray, &infoPtr->date);
+ SendMessageA(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
} else if (wParam==GDT_NONE) {
infoPtr->dateValid = FALSE;
@@ -784,8 +785,10 @@
GetTextExtentPoint32A (hdc, txt, strlen (txt), &size);
rcDraw->bottom = size.cy+2;
- if (dwStyle & DTS_SHOWNONE) checkbox->right = 18;
-
+ if (dwStyle & DTS_SHOWNONE)
+ checkbox->right = 18;
+ else
+ checkbox->right = 2;
prevright = checkbox->right;
for (i=0; i<infoPtr->nrFields; i++) {
@@ -882,19 +885,25 @@
/* recalculate the position of the monthcal popup */
if(dwStyle & DTS_RIGHTALIGN)
infoPtr->monthcal_pos.x = infoPtr->rcClient.right - ((infoPtr->calbutton.right -
- infoPtr->calbutton.left) + 145);
+ infoPtr->calbutton.left) + 200);
else
infoPtr->monthcal_pos.x = 8;
infoPtr->monthcal_pos.y = infoPtr->rcClient.bottom;
ClientToScreen (hwnd, &(infoPtr->monthcal_pos));
+ /* FIXME My Windoze has cx=about 200, but it probably depends on font size etc */
SetWindowPos(infoPtr->hMonthCal, 0, infoPtr->monthcal_pos.x,
- infoPtr->monthcal_pos.y, 145, 150, 0);
+ infoPtr->monthcal_pos.y, 200, 150, 0);
if(IsWindowVisible(infoPtr->hMonthCal))
ShowWindow(infoPtr->hMonthCal, SW_HIDE);
- else
- ShowWindow(infoPtr->hMonthCal, SW_SHOW);
+ else {
+ SYSTEMTIME *lprgSysTimeArray = &infoPtr->date;
+ TRACE("update calendar %04d/%02d/%02d\n",
+ lprgSysTimeArray->wYear, lprgSysTimeArray->wMonth, lprgSysTimeArray->wDay);
+ SendMessageA(infoPtr->hMonthCal, MCM_SETCURSEL, 0, (LPARAM)(&infoPtr->date));
+ ShowWindow(infoPtr->hMonthCal, SW_SHOW);
+ }
TRACE ("dt:%p mc:%p mc parent:%p, desktop:%p\n",
hwnd, infoPtr->hMonthCal, infoPtr->hwndNotify, GetDesktopWindow ());
@@ -995,6 +1004,18 @@
TRACE ("%x,%lx\n",wParam, lParam);
TRACE ("Got notification %x from %p\n", lpnmh->code, lpnmh->hwndFrom);
TRACE ("info: %p %p %p\n",hwnd,infoPtr->hMonthCal,infoPtr->hUpdown);
+
+ if (lpnmh->code==MCN_SELECT) {
+ NMSELCHANGE *psc = (NMSELCHANGE *)lpnmh;
+ ShowWindow(infoPtr->hMonthCal, SW_HIDE);
+ infoPtr->dateValid = TRUE;
+ SendMessageA (infoPtr->hMonthCal, MCM_GETCURSEL, 0, (LPARAM)&infoPtr->date);
+ TRACE("got from calendar %04d/%02d/%02d\n",
+ infoPtr->date.wYear, infoPtr->date.wMonth, infoPtr->date.wDay);
+ SendMessageA (infoPtr->hwndCheckbut, BM_SETCHECK, BST_CHECKED, 0);
+ InvalidateRect(hwnd, NULL, TRUE);
+ DATETIME_SendDateTimeChangeNotify (hwnd);
+ }
return 0;
}
@@ -1232,7 +1253,7 @@
infoPtr->hMonthCal = CreateWindowExA (0,"SysMonthCal32", 0,
WS_BORDER | WS_POPUP | WS_CLIPSIBLINGS,
0, 0, 0, 0,
- infoPtr->hwndNotify,
+ hwnd,
0, 0, 0);
/* initialize info structure */
@@ -1249,8 +1270,14 @@
DATETIME_INFO *infoPtr = DATETIME_GetInfoPtr (hwnd);
TRACE("\n");
+ if (infoPtr->hMonthCal) {
+ /* FIXME I don't completely understand why doesn't it
+ * happen automatically, WS_POPUP maybe? */
+ DestroyWindow(infoPtr->hMonthCal);
+ infoPtr->hMonthCal = NULL;
+ }
Free (infoPtr);
- SetWindowLongA( hwnd, 0, 0 );
+ SetWindowLongA( hwnd, 0, 0 ); /* clear infoPtr */
return 0;
}
Index: monthcal.c
===================================================================
RCS file: /home/wine/wine/dlls/comctl32/monthcal.c,v
retrieving revision 1.43
diff -u -r1.43 monthcal.c
--- monthcal.c 20 Nov 2003 22:04:14 -0000 1.43
+++ monthcal.c 19 Apr 2004 20:52:21 -0000
@@ -948,7 +948,7 @@
MONTHCAL_SetRange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
MONTHCAL_INFO *infoPtr = MONTHCAL_GetInfoPtr(hwnd);
- SYSTEMTIME lprgSysTimeArray[1];
+ SYSTEMTIME *lprgSysTimeArray=(SYSTEMTIME *)lParam;
int prev;
TRACE("%x %lx\n", wParam, lParam);
@@ -1033,6 +1033,7 @@
if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;
MONTHCAL_CopyTime(&infoPtr->minSel, lpSel);
+ TRACE("%d/%d/%d\n", lpSel->wYear, lpSel->wMonth, lpSel->wDay);
return TRUE;
}
@@ -1048,7 +1049,8 @@
if((infoPtr==NULL) ||(lpSel==NULL)) return FALSE;
if(GetWindowLongA(hwnd, GWL_STYLE) & MCS_MULTISELECT) return FALSE;
- TRACE("%d %d\n", lpSel->wMonth, lpSel->wDay);
+ infoPtr->currentMonth=lpSel->wMonth;
+ infoPtr->currentYear=lpSel->wYear;
MONTHCAL_CopyTime(lpSel, &infoPtr->minSel);
MONTHCAL_CopyTime(lpSel, &infoPtr->maxSel);
@@ -1479,23 +1481,24 @@
InvalidateRect(hwnd, NULL, FALSE);
return TRUE;
}
- if(hit && MCHT_CALENDARDATE) {
+ if(hit == MCHT_CALENDARDATE) {
SYSTEMTIME selArray[2];
NMSELCHANGE nmsc;
+ MONTHCAL_CopyTime(&ht.st, &selArray[0]);
+ MONTHCAL_CopyTime(&ht.st, &selArray[1]);
+ MONTHCAL_SetSelRange(hwnd,0,(LPARAM) &selArray);
+ MONTHCAL_SetCurSel(hwnd,0,(LPARAM) &selArray);
TRACE("MCHT_CALENDARDATE\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);
+ MONTHCAL_CopyTime(&infoPtr->minSel,&nmsc.stSelStart);
+ MONTHCAL_CopyTime(&infoPtr->maxSel,&nmsc.stSelEnd);
SendMessageA(infoPtr->hwndNotify, 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 both old and new days if the selected day changed */
if(infoPtr->curSelDay != ht.st.wDay) {
@@ -1530,10 +1533,12 @@
if(infoPtr->status & MC_NEXTPRESSED) {
KillTimer(hwnd, MC_NEXTMONTHTIMER);
+ infoPtr->status &= ~MC_NEXTPRESSED;
redraw = TRUE;
}
if(infoPtr->status & MC_PREVPRESSED) {
KillTimer(hwnd, MC_PREVMONTHTIMER);
+ infoPtr->status &= ~MC_PREVPRESSED;
redraw = TRUE;
}
@@ -1560,20 +1565,21 @@
SendMessageA(infoPtr->hwndNotify, 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(infoPtr->hwndNotify, WM_NOTIFY,
- (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
-
/* redraw if necessary */
if(redraw)
InvalidateRect(hwnd, NULL, FALSE);
+ /* only send MCN_SELECT if currently displayed month's day was selected */
+ if(hit == MCHT_CALENDARDATE) {
+ nmsc.nmhdr.hwndFrom = hwnd;
+ nmsc.nmhdr.idFrom = GetWindowLongA(hwnd, GWL_ID);
+ nmsc.nmhdr.code = MCN_SELECT;
+ MONTHCAL_CopyTime(&infoPtr->minSel, &nmsc.stSelStart);
+ MONTHCAL_CopyTime(&infoPtr->maxSel, &nmsc.stSelEnd);
+ SendMessageA(infoPtr->hwndNotify, WM_NOTIFY,
+ (WPARAM)nmsc.nmhdr.idFrom, (LPARAM)&nmsc);
+
+ }
return 0;
}
@@ -1898,6 +1904,8 @@
infoPtr->currentYear = infoPtr->todaysDate.wYear;
MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->minDate);
MONTHCAL_CopyTime(&infoPtr->todaysDate, &infoPtr->maxDate);
+ infoPtr->maxDate.wYear=2050;
+ infoPtr->minDate.wYear=1950;
infoPtr->maxSelCount = 7;
infoPtr->monthRange = 3;
infoPtr->monthdayState = Alloc
More information about the wine-patches
mailing list