[PATCH v4 3/3] comctl32/pager: Support comboboxex notification conversion.

Zhiyi Zhang zzhang at codeweavers.com
Mon Sep 17 10:27:00 CDT 2018


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/comctl32/pager.c       | 61 +++++++++++++++++++++++++++----
 dlls/comctl32/tests/pager.c | 72 +++++++++++++++++++++++++++++++++++--
 2 files changed, 125 insertions(+), 8 deletions(-)

diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c
index a6ef2eeadd..7fc0544ee4 100644
--- a/dlls/comctl32/pager.c
+++ b/dlls/comctl32/pager.c
@@ -101,7 +101,11 @@ enum conversion_flags
     /* Convert ANSI text from parent back to Unicode for children */
     CONVERT_RECEIVE = 0x02,
     /* Send empty text to parent if text is NULL. Original text pointer still remains NULL */
-    SEND_EMPTY_IF_NULL = 0x04
+    SEND_EMPTY_IF_NULL = 0x04,
+    /* Set text to null after parent received the notification if the required mask is not set before sending notification */
+    SET_NULL_IF_NO_MASK = 0x08,
+    /* Zero out the text buffer before sending it to parent */
+    ZERO_SEND = 0x10
 };
 
 static void
@@ -1038,6 +1042,10 @@ static UINT PAGER_GetAnsiNtfCode(UINT code)
 {
     switch (code)
     {
+    /* ComboxBoxEx */
+    case CBEN_DRAGBEGINW: return CBEN_DRAGBEGINA;
+    case CBEN_ENDEDITW: return CBEN_ENDEDITA;
+    case CBEN_GETDISPINFOW: return CBEN_GETDISPINFOA;
     /* Toolbar */
     case TBN_GETBUTTONINFOW: return TBN_GETBUTTONINFOA;
     case TBN_GETINFOTIPW: return TBN_GETINFOTIPA;
@@ -1060,7 +1068,8 @@ static BOOL PAGER_AdjustBuffer(PAGER_INFO *infoPtr, INT size)
     return TRUE;
 }
 
-static LRESULT PAGER_SendConvertedNotify(PAGER_INFO *infoPtr, NMHDR *hdr, WCHAR **text, INT *textMax, DWORD flags)
+static LRESULT PAGER_SendConvertedNotify(PAGER_INFO *infoPtr, NMHDR *hdr, UINT *mask, UINT requiredMask, WCHAR **text,
+                                         INT *textMax, DWORD flags)
 {
     CHAR *sendBuffer = NULL;
     CHAR *receiveBuffer;
@@ -1074,14 +1083,21 @@ static LRESULT PAGER_SendConvertedNotify(PAGER_INFO *infoPtr, NMHDR *hdr, WCHAR
 
     hdr->code = PAGER_GetAnsiNtfCode(hdr->code);
 
+    if (mask && !(*mask & requiredMask))
+    {
+        ret = SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)hdr);
+        if (flags & SET_NULL_IF_NO_MASK) oldText = NULL;
+        goto done;
+    }
+
     if (oldTextMax < 0) goto done;
 
-    if ((*text && (flags & CONVERT_SEND)) || (!*text && (flags & SEND_EMPTY_IF_NULL)))
+    if ((*text && flags & (CONVERT_SEND | ZERO_SEND)) || (!*text && flags & SEND_EMPTY_IF_NULL))
     {
         bufferSize = textMax ? *textMax : lstrlenW(*text) + 1;
         sendBuffer = heap_alloc_zero(bufferSize);
         if (!sendBuffer) goto done;
-        WideCharToMultiByte(CP_ACP, 0, *text, -1, sendBuffer, bufferSize, NULL, FALSE);
+        if (!(flags & ZERO_SEND)) WideCharToMultiByte(CP_ACP, 0, *text, -1, sendBuffer, bufferSize, NULL, FALSE);
         *text = (WCHAR *)sendBuffer;
     }
 
@@ -1117,17 +1133,50 @@ static LRESULT PAGER_Notify(PAGER_INFO *infoPtr, NMHDR *hdr)
 
     switch (hdr->code)
     {
+    /* ComboBoxEx */
+    case CBEN_GETDISPINFOW:
+    {
+        NMCOMBOBOXEXW *nmcbe = (NMCOMBOBOXEXW *)hdr;
+        return PAGER_SendConvertedNotify(infoPtr, hdr, &nmcbe->ceItem.mask, CBEIF_TEXT, &nmcbe->ceItem.pszText,
+                                         &nmcbe->ceItem.cchTextMax, ZERO_SEND | SET_NULL_IF_NO_MASK | CONVERT_RECEIVE);
+    }
+    case CBEN_DRAGBEGINW:
+    {
+        NMCBEDRAGBEGINW *nmdbW = (NMCBEDRAGBEGINW *)hdr;
+        NMCBEDRAGBEGINA nmdbA = {0};
+        nmdbA.hdr.code = PAGER_GetAnsiNtfCode(nmdbW->hdr.code);
+        nmdbA.hdr.hwndFrom = nmdbW->hdr.hwndFrom;
+        nmdbA.hdr.idFrom = nmdbW->hdr.idFrom;
+        nmdbA.iItemid = nmdbW->iItemid;
+        WideCharToMultiByte(CP_ACP, 0, nmdbW->szText, ARRAY_SIZE(nmdbW->szText), nmdbA.szText, ARRAY_SIZE(nmdbA.szText),
+                            NULL, FALSE);
+        return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)&nmdbA);
+    }
+    case CBEN_ENDEDITW:
+    {
+        NMCBEENDEDITW *nmedW = (NMCBEENDEDITW *)hdr;
+        NMCBEENDEDITA nmedA = {0};
+        nmedA.hdr.code = PAGER_GetAnsiNtfCode(nmedW->hdr.code);
+        nmedA.hdr.hwndFrom = nmedW->hdr.hwndFrom;
+        nmedA.hdr.idFrom = nmedW->hdr.idFrom;
+        nmedA.fChanged = nmedW->fChanged;
+        nmedA.iNewSelection = nmedW->iNewSelection;
+        nmedA.iWhy = nmedW->iWhy;
+        WideCharToMultiByte(CP_ACP, 0, nmedW->szText, ARRAY_SIZE(nmedW->szText), nmedA.szText, ARRAY_SIZE(nmedA.szText),
+                            NULL, FALSE);
+        return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)&nmedA);
+    }
     /* Toolbar */
     case TBN_GETBUTTONINFOW:
     {
         NMTOOLBARW *nmtb = (NMTOOLBARW *)hdr;
-        return PAGER_SendConvertedNotify(infoPtr, hdr, &nmtb->pszText, &nmtb->cchText,
+        return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, &nmtb->pszText, &nmtb->cchText,
                                          SEND_EMPTY_IF_NULL | CONVERT_SEND | CONVERT_RECEIVE);
     }
     case TBN_GETINFOTIPW:
     {
         NMTBGETINFOTIPW *nmtbgit = (NMTBGETINFOTIPW *)hdr;
-        return PAGER_SendConvertedNotify(infoPtr, hdr, &nmtbgit->pszText, &nmtbgit->cchTextMax, CONVERT_RECEIVE);
+        return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, &nmtbgit->pszText, &nmtbgit->cchTextMax, CONVERT_RECEIVE);
     }
     /* Tooltip */
     case TTN_GETDISPINFOW:
diff --git a/dlls/comctl32/tests/pager.c b/dlls/comctl32/tests/pager.c
index cd7b637b91..b689549aa5 100644
--- a/dlls/comctl32/tests/pager.c
+++ b/dlls/comctl32/tests/pager.c
@@ -65,7 +65,9 @@ enum test_conversion_flags
     CONVERT_RECEIVE = 0x04,
     DONT_CONVERT_RECEIVE = 0x08,
     SEND_EMPTY_IF_NULL = 0x10,
-    DONT_SEND_EMPTY_IF_NULL = 0x20
+    DONT_SEND_EMPTY_IF_NULL = 0x20,
+    SET_NULL_IF_NO_MASK = 0x40,
+    ZERO_SEND = 0x80
 };
 
 static struct notify_test_info
@@ -578,7 +580,10 @@ static void notify_generic_text_handler(CHAR **text, INT *text_max)
     {
         send_data = (notify_test_info.test_id == CONVERT_SEND ? test_convert_send_data : test_dont_convert_send_data)
                     + notify_test_info.sub_test_id;
-        if (notify_test_info.flags & CONVERT_SEND)
+        if (notify_test_info.flags & ZERO_SEND)
+            ok(!lstrcmpA(*text, empty_a), "Code 0x%08x test 0x%08x sub test %d expect empty text, got %s\n",
+               notify_test_info.unicode, notify_test_info.test_id, notify_test_info.sub_test_id, *text);
+        else if (notify_test_info.flags & CONVERT_SEND)
             ok(!lstrcmpA(send_data->expect_text, *text), "Code 0x%08x test 0x%08x sub test %d expect %s, got %s\n",
                notify_test_info.unicode, notify_test_info.test_id, notify_test_info.sub_test_id,
                (CHAR *)send_data->expect_text, *text);
@@ -659,6 +664,32 @@ static LRESULT WINAPI test_notify_proc(HWND hwnd, UINT message, WPARAM wParam, L
         }
         switch (hdr->code)
         {
+        /* ComboBoxEx */
+        case CBEN_INSERTITEM:
+        case CBEN_DELETEITEM:
+        {
+            NMCOMBOBOXEXW *nmcbe = (NMCOMBOBOXEXW *)hdr;
+            notify_generic_text_handler((CHAR **)&nmcbe->ceItem.pszText, NULL);
+            break;
+        }
+        case CBEN_DRAGBEGINA:
+        {
+            NMCBEDRAGBEGINA *nmcbedb = (NMCBEDRAGBEGINA *)hdr;
+            ok(!lstrcmpA(nmcbedb->szText, test_a), "Expect %s, got %s\n", nmcbedb->szText, test_a);
+            break;
+        }
+        case CBEN_ENDEDITA:
+        {
+            NMCBEENDEDITA *nmcbeed = (NMCBEENDEDITA *)hdr;
+            ok(!lstrcmpA(nmcbeed->szText, test_a), "Expect %s, got %s\n", nmcbeed->szText, test_a);
+            break;
+        }
+        case CBEN_GETDISPINFOA:
+        {
+            NMCOMBOBOXEXA *nmcbe = (NMCOMBOBOXEXA *)hdr;
+            notify_generic_text_handler(&nmcbe->ceItem.pszText, &nmcbe->ceItem.cchTextMax);
+            break;
+        }
         /* Toolbar */
         case TBN_SAVE:
         {
@@ -836,6 +867,33 @@ static void test_notify_generic_text_helper(HWND pager, const struct generic_tex
     else
         notify_test_info.test_id = DONT_SEND_EMPTY_IF_NULL;
     send_notify(pager, para->code_unicode, para->code_ansi, (LPARAM)para->ptr, TRUE);
+
+    notify_test_info.test_id = SET_NULL_IF_NO_MASK;
+    memset(para->ptr, 0, para->size);
+    memset(buffer, 0, sizeof(buffer));
+    *para->text = buffer;
+    if (para->text_max) *para->text_max = ARRAY_SIZE(buffer);
+    send_notify(pager, para->code_unicode, para->code_ansi, (LPARAM)para->ptr, TRUE);
+    if(para->flags & SET_NULL_IF_NO_MASK)
+        ok(!*para->text, "Expect null text\n");
+}
+
+static void test_wm_notify_comboboxex(HWND pager)
+{
+    static NMCBEDRAGBEGINW nmcbedb;
+    static NMCBEENDEDITW nmcbeed;
+
+    /* CBEN_DRAGBEGIN */
+    memset(&nmcbedb, 0, sizeof(nmcbedb));
+    memcpy(nmcbedb.szText, test_w, sizeof(test_w));
+    send_notify(pager, CBEN_DRAGBEGINW, CBEN_DRAGBEGINA, (LPARAM)&nmcbedb, FALSE);
+    ok(!lstrcmpW(nmcbedb.szText, test_w), "Expect %s, got %s\n", wine_dbgstr_w(test_w), wine_dbgstr_w(nmcbedb.szText));
+
+    /* CBEN_ENDEDIT */
+    memset(&nmcbeed, 0, sizeof(nmcbeed));
+    memcpy(nmcbeed.szText, test_w, sizeof(test_w));
+    send_notify(pager, CBEN_ENDEDITW, CBEN_ENDEDITA, (LPARAM)&nmcbeed, FALSE);
+    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_tooltip(HWND pager)
@@ -880,6 +938,8 @@ static void test_wm_notify(void)
 {
     static const CHAR *class = "Pager notify class";
     HWND parent, pager;
+    /* Combo Box Ex */
+    static NMCOMBOBOXEXW nmcbe;
     /* Tool Bar */
     static NMTBRESTORE nmtbr;
     static NMTBSAVE nmtbs;
@@ -888,6 +948,13 @@ static void test_wm_notify(void)
     static NMTBGETINFOTIPW nmtbgit;
     static const struct generic_text_helper_para paras[] =
     {
+        /* Combo Box Ex */
+        {&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText, &nmcbe.ceItem.cchTextMax,
+         CBEN_INSERTITEM, CBEN_INSERTITEM, DONT_CONVERT_SEND | DONT_CONVERT_RECEIVE},
+        {&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText, &nmcbe.ceItem.cchTextMax,
+         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},
         /* Tool Bar */
         {&nmtbs, sizeof(nmtbs), NULL, 0, (WCHAR **)&nmtbs.tbButton.iString, NULL, TBN_SAVE, TBN_SAVE,
          DONT_CONVERT_SEND | DONT_CONVERT_RECEIVE},
@@ -916,6 +983,7 @@ static void test_wm_notify(void)
         test_notify_generic_text_helper(pager, paras + i);
 
     /* Tests for those that can't be covered by generic text test helper */
+    test_wm_notify_comboboxex(pager);
     test_wm_notify_tooltip(pager);
 
     DestroyWindow(parent);
-- 
2.18.0




More information about the wine-devel mailing list