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

Zhiyi Zhang zzhang at codeweavers.com
Tue Sep 11 07:27:32 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 fd9af3147b..c03b07966c 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 */
-    NULL_SEND_EMPTY = 0x04
+    NULL_SEND_EMPTY = 0x04,
+    /* Set text to null after parent received the notification if the required mask is not set before sending notification */
+    NO_MASK_SET_NULL = 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 & NO_MASK_SET_NULL) oldText = NULL;
+        goto done;
+    }
+
     if (oldTextMax < 0) goto done;
 
-    if ((*text && flags & CONVERT_SEND) || (!*text && flags & NULL_SEND_EMPTY))
+    if ((*text && flags & (CONVERT_SEND | ZERO_SEND)) || (!*text && flags & NULL_SEND_EMPTY))
     {
         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 | NO_MASK_SET_NULL | 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,
                                          NULL_SEND_EMPTY | 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 56b3116fd7..a01736f17f 100644
--- a/dlls/comctl32/tests/pager.c
+++ b/dlls/comctl32/tests/pager.c
@@ -65,7 +65,9 @@ enum test_conversion_flags
     CONVERT_RECEIVE = 0x04,
     NOT_CONVERT_RECEIVE = 0x08,
     NULL_SEND_EMPTY = 0x10,
-    NOT_NULL_SEND_EMPTY = 0x20
+    NOT_NULL_SEND_EMPTY = 0x20,
+    NO_MASK_SET_NULL = 0x40,
+    ZERO_SEND = 0x80
 };
 
 static struct notify_test_info
@@ -576,7 +578,10 @@ static void notify_generic_text_handler(CHAR **text, INT *text_max)
         const struct notify_test_send_data *data =
             (notify_test_info.test_id == CONVERT_SEND ? test_convert_send_datas : test_not_convert_send_datas)
             + 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(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 *)data->expect_text, *text);
@@ -658,6 +663,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:
         {
@@ -838,6 +869,33 @@ static void test_notify_generic_text_helper(HWND pager, void *ptr, size_t size,
     else
         notify_test_info.test_id = NOT_NULL_SEND_EMPTY;
     send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE);
+
+    notify_test_info.test_id = NO_MASK_SET_NULL;
+    memset(ptr, 0, size);
+    memset(buffer, 0, sizeof(buffer));
+    *text = buffer;
+    if (text_max) *text_max = ARRAY_SIZE(buffer);
+    send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE);
+    if(flags & NO_MASK_SET_NULL)
+        ok(!*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(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(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)
@@ -882,6 +940,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;
@@ -890,6 +950,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, NOT_CONVERT_SEND | NOT_CONVERT_RECEIVE},
+        {&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText, &nmcbe.ceItem.cchTextMax,
+         CBEN_DELETEITEM, CBEN_DELETEITEM, NOT_CONVERT_SEND | NOT_CONVERT_RECEIVE},
+        {&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText, &nmcbe.ceItem.cchTextMax,
+         CBEN_GETDISPINFOW, CBEN_GETDISPINFOA, ZERO_SEND | NO_MASK_SET_NULL | NOT_CONVERT_SEND | CONVERT_RECEIVE},
         /* Tool Bar */
         {&nmtbs, sizeof(nmtbs), NULL, 0, (WCHAR **)&nmtbs.tbButton.iString, NULL, TBN_SAVE, TBN_SAVE,
          NOT_CONVERT_SEND | NOT_CONVERT_RECEIVE},
@@ -922,6 +989,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_tooltip(pager);
 
     DestroyWindow(parent);
-- 
2.18.0




More information about the wine-devel mailing list