[PATCH 1/4] comctl32/pager: Support date time picker notification conversion.
Zhiyi Zhang
zzhang at codeweavers.com
Mon Sep 24 02:12:02 CDT 2018
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/comctl32/pager.c | 65 +++++++++++++++++++++++++
dlls/comctl32/tests/pager.c | 97 +++++++++++++++++++++++++++++++++++++
2 files changed, 162 insertions(+)
diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c
index 96a66806ee..605141b9ab 100644
--- a/dlls/comctl32/pager.c
+++ b/dlls/comctl32/pager.c
@@ -1046,6 +1046,11 @@ static UINT PAGER_GetAnsiNtfCode(UINT code)
case CBEN_DRAGBEGINW: return CBEN_DRAGBEGINA;
case CBEN_ENDEDITW: return CBEN_ENDEDITA;
case CBEN_GETDISPINFOW: return CBEN_GETDISPINFOA;
+ /* Date and Time Picker */
+ case DTN_FORMATW: return DTN_FORMATA;
+ case DTN_FORMATQUERYW: return DTN_FORMATQUERYA;
+ case DTN_USERSTRINGW: return DTN_USERSTRINGA;
+ case DTN_WMKEYDOWNW: return DTN_WMKEYDOWNA;
/* Toolbar */
case TBN_GETBUTTONINFOW: return TBN_GETBUTTONINFOA;
case TBN_GETINFOTIPW: return TBN_GETINFOTIPA;
@@ -1068,6 +1073,23 @@ static BOOL PAGER_AdjustBuffer(PAGER_INFO *infoPtr, INT size)
return TRUE;
}
+/* Convert text to Unicode and return the original text address */
+static WCHAR *PAGER_ConvertText(WCHAR **text)
+{
+ WCHAR *oldText = *text;
+ *text = NULL;
+ Str_SetPtrWtoA((CHAR **)text, oldText);
+ return oldText;
+}
+
+static void PAGER_RestoreText(WCHAR **text, WCHAR *oldText)
+{
+ if (!oldText) return;
+
+ Free(*text);
+ *text = oldText;
+}
+
static LRESULT PAGER_SendConvertedNotify(PAGER_INFO *infoPtr, NMHDR *hdr, UINT *mask, UINT requiredMask, WCHAR **text,
INT *textMax, DWORD flags)
{
@@ -1166,6 +1188,49 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr)
NULL, FALSE);
return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)&nmedA);
}
+ /* Date and Time Picker */
+ case DTN_FORMATW:
+ {
+ NMDATETIMEFORMATW *nmdtf = (NMDATETIMEFORMATW *)hdr;
+ WCHAR *oldFormat;
+ INT textLength;
+
+ hdr->code = PAGER_GetAnsiNtfCode(hdr->code);
+ oldFormat = PAGER_ConvertText((WCHAR **)&nmdtf->pszFormat);
+ ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)nmdtf);
+ PAGER_RestoreText((WCHAR **)&nmdtf->pszFormat, oldFormat);
+
+ if (nmdtf->pszDisplay)
+ {
+ textLength = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, 0, 0);
+ if (!PAGER_AdjustBuffer(infoPtr, textLength * sizeof(WCHAR))) return ret;
+ MultiByteToWideChar(CP_ACP, 0, (LPCSTR)nmdtf->pszDisplay, -1, infoPtr->pwszBuffer, textLength);
+ if (nmdtf->pszDisplay != nmdtf->szDisplay)
+ nmdtf->pszDisplay = infoPtr->pwszBuffer;
+ else
+ {
+ textLength = min(textLength, ARRAY_SIZE(nmdtf->szDisplay));
+ memcpy(nmdtf->szDisplay, infoPtr->pwszBuffer, textLength * sizeof(WCHAR));
+ }
+ }
+
+ return ret;
+ }
+ case DTN_FORMATQUERYW:
+ {
+ NMDATETIMEFORMATQUERYW *nmdtfq = (NMDATETIMEFORMATQUERYW *)hdr;
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, (WCHAR **)&nmdtfq->pszFormat, NULL, CONVERT_SEND);
+ }
+ case DTN_WMKEYDOWNW:
+ {
+ NMDATETIMEWMKEYDOWNW *nmdtkd = (NMDATETIMEWMKEYDOWNW *)hdr;
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, (WCHAR **)&nmdtkd->pszFormat, NULL, CONVERT_SEND);
+ }
+ case DTN_USERSTRINGW:
+ {
+ NMDATETIMESTRINGW *nmdts = (NMDATETIMESTRINGW *)hdr;
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, (WCHAR **)&nmdts->pszUserString, NULL, CONVERT_SEND);
+ }
/* Toolbar */
case TBN_GETBUTTONINFOW:
{
diff --git a/dlls/comctl32/tests/pager.c b/dlls/comctl32/tests/pager.c
index b689549aa5..8993118711 100644
--- a/dlls/comctl32/tests/pager.c
+++ b/dlls/comctl32/tests/pager.c
@@ -32,6 +32,8 @@ static INT notify_format;
static BOOL notify_query_received;
static WCHAR test_w[] = {'t', 'e', 's', 't', 0};
static CHAR test_a[] = {'t', 'e', 's', 't', 0};
+/* Double zero so that it's safe to cast it to WCHAR * */
+static CHAR te_a[] = {'t', 'e', 0, 0};
static WCHAR empty_w[] = {0};
static CHAR empty_a[] = {0};
static CHAR large_a[] = "You should have received a copy of the GNU Lesser General Public License along with this ...";
@@ -180,6 +182,29 @@ static const struct notify_test_tooltip
{NULL, 0, large_a, NULL, large_truncated_80_w, sizeof(large_truncated_80_w), large_w}
};
+static const struct notify_test_datetime_format
+{
+ /* Data send to parent */
+ WCHAR *send_pszformat;
+ /* Data expected by parent */
+ CHAR *expect_pszformat;
+ /* Data for parent to write */
+ CHAR *write_szdisplay;
+ INT write_szdisplay_size;
+ CHAR *write_pszdisplay;
+ /* Data when message returned */
+ WCHAR *return_szdisplay;
+ INT return_szdisplay_size;
+ WCHAR *return_pszdisplay;
+} test_datetime_format_data[] =
+{
+ {test_w, test_a},
+ {NULL, NULL, NULL, 0, test_a, empty_w, -1, test_w},
+ {NULL, NULL, test_a, sizeof(test_a), NULL, test_w, -1, test_w},
+ {NULL, NULL, test_a, 2, test_a, (WCHAR *)te_a, -1, test_w},
+ {NULL, NULL, NULL, 0, large_a, NULL, 0, large_w}
+};
+
#define CHILD1_ID 1
#define CHILD2_ID 2
@@ -639,6 +664,18 @@ static void notify_tooltip_handler(NMTTDISPINFOA *nm)
if (data->write_hinst) nm->hinst = data->write_hinst;
}
+static void notify_datetime_handler(NMDATETIMEFORMATA *nm)
+{
+ const struct notify_test_datetime_format *data = test_datetime_format_data + notify_test_info.sub_test_id;
+ if (data->expect_pszformat)
+ ok(!lstrcmpA(data->expect_pszformat, nm->pszFormat), "Sub test %d expect %s, got %s\n",
+ notify_test_info.sub_test_id, data->expect_pszformat, nm->pszFormat);
+ ok(nm->pszDisplay == nm->szDisplay, "Test %d expect %p, got %p\n", notify_test_info.sub_test_id, nm->szDisplay,
+ nm->pszDisplay);
+ if (data->write_szdisplay) memcpy(nm->szDisplay, data->write_szdisplay, data->write_szdisplay_size);
+ if (data->write_pszdisplay) nm->pszDisplay = data->write_pszdisplay;
+}
+
static LRESULT WINAPI test_notify_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static const WCHAR test[] = {'t', 'e', 's', 't', 0};
@@ -690,6 +727,30 @@ static LRESULT WINAPI test_notify_proc(HWND hwnd, UINT message, WPARAM wParam, L
notify_generic_text_handler(&nmcbe->ceItem.pszText, &nmcbe->ceItem.cchTextMax);
break;
}
+ /* Date and Time Picker */
+ case DTN_FORMATA:
+ {
+ notify_datetime_handler((NMDATETIMEFORMATA *)hdr);
+ break;
+ }
+ case DTN_FORMATQUERYA:
+ {
+ NMDATETIMEFORMATQUERYA *nmdtfq = (NMDATETIMEFORMATQUERYA *)hdr;
+ notify_generic_text_handler((CHAR **)&nmdtfq->pszFormat, NULL);
+ break;
+ }
+ case DTN_WMKEYDOWNA:
+ {
+ NMDATETIMEWMKEYDOWNA *nmdtkd = (NMDATETIMEWMKEYDOWNA *)hdr;
+ notify_generic_text_handler((CHAR **)&nmdtkd->pszFormat, NULL);
+ break;
+ }
+ case DTN_USERSTRINGA:
+ {
+ NMDATETIMESTRINGA *nmdts = (NMDATETIMESTRINGA *)hdr;
+ notify_generic_text_handler((CHAR **)&nmdts->pszUserString, NULL);
+ break;
+ }
/* Toolbar */
case TBN_SAVE:
{
@@ -896,6 +957,30 @@ static void test_wm_notify_comboboxex(HWND pager)
ok(!lstrcmpW(nmcbeed.szText, test_w), "Expect %s, got %s\n", wine_dbgstr_w(test_w), wine_dbgstr_w(nmcbeed.szText));
}
+static void test_wm_notify_datetime(HWND pager)
+{
+ const struct notify_test_datetime_format *data;
+ NMDATETIMEFORMATW nmdtf;
+ INT i;
+
+ for (i = 0; i < ARRAY_SIZE(test_datetime_format_data); i++)
+ {
+ data = test_datetime_format_data + i;
+ notify_test_info.sub_test_id = i;
+
+ memset(&nmdtf, 0, sizeof(nmdtf));
+ if(data->send_pszformat) nmdtf.pszFormat = data->send_pszformat;
+ nmdtf.pszDisplay = nmdtf.szDisplay;
+ send_notify(pager, DTN_FORMATW, DTN_FORMATA, (LPARAM)&nmdtf, TRUE);
+ if (data->return_szdisplay)
+ ok(!lstrcmpW(nmdtf.szDisplay, data->return_szdisplay), "Sub test %d expect %s, got %s\n", i,
+ wine_dbgstr_w(data->return_szdisplay), wine_dbgstr_w(nmdtf.szDisplay));
+ if (data->return_pszdisplay)
+ ok(!lstrcmpW(nmdtf.pszDisplay, data->return_pszdisplay), "Sub test %d expect %s, got %s\n", i,
+ wine_dbgstr_w(data->return_pszdisplay), wine_dbgstr_w(nmdtf.pszDisplay));
+ }
+}
+
static void test_wm_notify_tooltip(HWND pager)
{
NMTTDISPINFOW nmttdi;
@@ -940,6 +1025,10 @@ static void test_wm_notify(void)
HWND parent, pager;
/* Combo Box Ex */
static NMCOMBOBOXEXW nmcbe;
+ /* Date and Time Picker */
+ static NMDATETIMEFORMATQUERYW nmdtfq;
+ static NMDATETIMEWMKEYDOWNW nmdtkd;
+ static NMDATETIMESTRINGW nmdts;
/* Tool Bar */
static NMTBRESTORE nmtbr;
static NMTBSAVE nmtbs;
@@ -955,6 +1044,13 @@ static void test_wm_notify(void)
CBEN_DELETEITEM, CBEN_DELETEITEM, DONT_CONVERT_SEND | DONT_CONVERT_RECEIVE},
{&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText, &nmcbe.ceItem.cchTextMax,
CBEN_GETDISPINFOW, CBEN_GETDISPINFOA, ZERO_SEND | SET_NULL_IF_NO_MASK | DONT_CONVERT_SEND | CONVERT_RECEIVE},
+ /* Date and Time Picker */
+ {&nmdtfq, sizeof(nmdtfq), NULL, 0, (WCHAR **)&nmdtfq.pszFormat, NULL, DTN_FORMATQUERYW, DTN_FORMATQUERYA,
+ CONVERT_SEND},
+ {&nmdtkd, sizeof(nmdtkd), NULL, 0, (WCHAR **)&nmdtkd.pszFormat, NULL, DTN_WMKEYDOWNW, DTN_WMKEYDOWNA,
+ CONVERT_SEND},
+ {&nmdts, sizeof(nmdts), NULL, 0, (WCHAR **)&nmdts.pszUserString, NULL, DTN_USERSTRINGW, DTN_USERSTRINGA,
+ CONVERT_SEND},
/* Tool Bar */
{&nmtbs, sizeof(nmtbs), NULL, 0, (WCHAR **)&nmtbs.tbButton.iString, NULL, TBN_SAVE, TBN_SAVE,
DONT_CONVERT_SEND | DONT_CONVERT_RECEIVE},
@@ -984,6 +1080,7 @@ static void test_wm_notify(void)
/* Tests for those that can't be covered by generic text test helper */
test_wm_notify_comboboxex(pager);
+ test_wm_notify_datetime(pager);
test_wm_notify_tooltip(pager);
DestroyWindow(parent);
--
2.18.0
More information about the wine-devel
mailing list