diff --git a/windows/datetimepicker.cpp b/windows/datetimepicker.cpp index 7d8bea39..2ea366c2 100644 --- a/windows/datetimepicker.cpp +++ b/windows/datetimepicker.cpp @@ -4,6 +4,8 @@ struct uiDateTimePicker { uiWindowsControl c; HWND hwnd; + void(*onChanged)(uiDateTimePicker *, void *); + void *onChangedData; }; // utility functions @@ -103,6 +105,7 @@ static void uiDateTimePickerDestroy(uiControl *c) uiDateTimePicker *d = uiDateTimePicker(c); uiWindowsUnregisterReceiveWM_WININICHANGE(d->hwnd); + uiWindowsUnregisterWM_NOTIFYHandler(d->hwnd); uiWindowsEnsureDestroyWindow(d->hwnd); uiFreeControl(uiControl(d)); } @@ -131,6 +134,72 @@ static void uiDateTimePickerMinimumSize(uiWindowsControl *c, int *width, int *he *height = y; } +static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult) +{ + uiDateTimePicker *d = uiDateTimePicker(c); + + if (nmhdr->code != DTN_DATETIMECHANGE) + return FALSE; + (*(d->onChanged))(d, d->onChangedData); + *lResult = 0; + return TRUE; +} + +static void fromSystemTime(LPSYSTEMTIME systime, struct tm *time) +{ + memset(time, 0, sizeof(struct tm)); + time->tm_sec = systime->wSecond; + time->tm_min = systime->wMinute; + time->tm_hour = systime->wHour; + time->tm_mday = systime->wDay; + time->tm_mon = systime->wMonth - 1; + time->tm_year = systime->wYear - 1900; + time->tm_wday = systime->wDayOfWeek; + time->tm_isdst = -1; +} + +static void toSystemTime(const struct tm *time, LPSYSTEMTIME systime) +{ + memset(systime, 0, sizeof(SYSTEMTIME)); + systime->wYear = time->tm_year + 1900; + systime->wMonth = time->tm_mon + 1; + systime->wDayOfWeek = time->tm_wday; + systime->wDay = time->tm_mday; + systime->wHour = time->tm_hour; + systime->wMinute = time->tm_min; + systime->wSecond = time->tm_sec; +} + +static void defaultOnChanged(uiDateTimePicker *d, void *data) +{ + // do nothing +} + +void uiDateTimePickerTime(uiDateTimePicker *d, struct tm *time) +{ + SYSTEMTIME systime; + + if (DateTime_GetSystemtime(d->hwnd, &systime) != GDT_VALID) + implbug("DTM_GETSYSTEMTIME message failed"); + fromSystemTime(&systime, time); +} + +void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time) +{ + SYSTEMTIME systime; + + toSystemTime(time, &systime); + if (!DateTime_SetSystemtime(d->hwnd, GDT_VALID, &systime)) + implbug("DTM_SETSYSTEMTIME message failed"); + (*(d->onChanged))(d, d->onChangedData); +} + +void uiDateTimePickerOnChanged(uiDateTimePicker *d, void(*f)(uiDateTimePicker *, void *), void *data) +{ + d->onChanged = f; + d->onChangedData = data; +} + static uiDateTimePicker *finishNewDateTimePicker(DWORD style) { uiDateTimePicker *d; @@ -147,6 +216,8 @@ static uiDateTimePicker *finishNewDateTimePicker(DWORD style) // for the standard styles, this is in the date-time picker itself // for our date/time mode, we do it in a subclass assigned in uiNewDateTimePicker() uiWindowsRegisterReceiveWM_WININICHANGE(d->hwnd); + uiWindowsRegisterWM_NOTIFYHandler(d->hwnd, onWM_NOTIFY, uiControl(d)); + uiDateTimePickerOnChanged(d, defaultOnChanged, NULL); return d; } @@ -168,18 +239,6 @@ static LRESULT CALLBACK datetimepickerSubProc(HWND hwnd, UINT uMsg, WPARAM wPara return DefSubclassProc(hwnd, uMsg, wParam, lParam); } -void uiDateTimePickerTime(uiDateTimePicker *d, struct tm *time) -{ -} - -void uiDateTimePickerSetTime(uiDateTimePicker *d, const struct tm *time) -{ -} - -void uiDateTimePickerOnChanged(uiDateTimePicker *d, void (*f)(uiDateTimePicker *, void *), void *data) -{ -} - uiDateTimePicker *uiNewDateTimePicker(void) { uiDateTimePicker *d;