[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