[PATCH 3/3] comctl32/pager: Support comboboxex notification conversion.
Zhiyi Zhang
zzhang at codeweavers.com
Mon Aug 27 22:28:37 CDT 2018
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
dlls/comctl32/pager.c | 59 +++++++++++++-
dlls/comctl32/tests/pager.c | 148 +++++++++++++++++++++++++++++++++---
2 files changed, 192 insertions(+), 15 deletions(-)
diff --git a/dlls/comctl32/pager.c b/dlls/comctl32/pager.c
index 9ab492e333..37b2e52325 100644
--- a/dlls/comctl32/pager.c
+++ b/dlls/comctl32/pager.c
@@ -101,7 +101,11 @@ typedef enum
/* Convert Unicode text to ANSI for parent before sending. If not set, do nothing */
TO_ANSI = 0x02,
/* Send empty text to parent if text is NULL, original text pointer still remain NULL */
- SET_NULL_EMPTY = 0x04
+ SET_NULL_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 the text buffer before sending */
+ ZERO_BUFFER = 0x10
} ConversionFlag;
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, ConversionFlag flags)
+static LRESULT PAGER_SendConvertedNotify(PAGER_INFO *infoPtr, NMHDR *hdr, UINT *mask, UINT requiredMask, WCHAR **text,
+ INT *textMax, ConversionFlag flags)
{
WCHAR emptyW[] = {0};
WCHAR *oldText;
@@ -1075,8 +1084,17 @@ 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 & ZERO_BUFFER) memset(*text, 0, oldTextMax * sizeof(WCHAR));
+
if (!*text && flags & SET_NULL_EMPTY)
*text = emptyW;
@@ -1117,17 +1135,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, NO_MASK_SET_NULL | ZERO_BUFFER | FROM_ANSI);
+ }
+ 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,
SET_NULL_EMPTY | TO_ANSI | FROM_ANSI);
}
case TBN_GETINFOTIPW:
{
NMTBGETINFOTIPW *nmtbgit = (NMTBGETINFOTIPW *)hdr;
- return PAGER_SendConvertedNotify(infoPtr, hdr, &nmtbgit->pszText, &nmtbgit->cchTextMax, FROM_ANSI);
+ return PAGER_SendConvertedNotify(infoPtr, hdr, NULL, 0, &nmtbgit->pszText, &nmtbgit->cchTextMax, FROM_ANSI);
}
/* Tooltip */
case TTN_GETDISPINFOW:
diff --git a/dlls/comctl32/tests/pager.c b/dlls/comctl32/tests/pager.c
index bf79f34c5b..ee8d36d040 100644
--- a/dlls/comctl32/tests/pager.c
+++ b/dlls/comctl32/tests/pager.c
@@ -45,7 +45,11 @@ typedef enum
/* Convert Unicode text to ANSI for parent before sending. If not set, do nothing */
TO_ANSI = 0x02,
/* Send empty text to parent if text is NULL, original text pointer still remain NULL */
- SET_NULL_EMPTY = 0x04
+ SET_NULL_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 the text buffer before sending */
+ ZERO_BUFFER = 0x10
} ConversionFlag;
static struct notify_test_data
@@ -505,12 +509,15 @@ static void wm_notify_text_handler(CHAR **text, INT *textMax)
expect_eq_int(*textMax, notify_test_data.text_size);
switch (notify_test_data.sub_test_id)
{
- case 1:
+ case 0:
if (notify_test_data.flags & SET_NULL_EMPTY)
expect_text_empty(*text);
else
expect_null(*text);
break;
+ case 1:
+ expect_text_empty(*text);
+ break;
case 2:
{
INT length = lstrlenA(*text);
@@ -521,7 +528,9 @@ static void wm_notify_text_handler(CHAR **text, INT *textMax)
break;
}
case 3:
- if (notify_test_data.flags & TO_ANSI)
+ if (notify_test_data.flags & ZERO_BUFFER)
+ expect_text_empty(*text);
+ else if (notify_test_data.flags & TO_ANSI)
{
expect_eq_text_a(*text, test_a);
ok(*text != (CHAR *)buffer, "Expect using a new buffer\n");
@@ -579,6 +588,49 @@ static LRESULT WINAPI test_notify_proc(HWND hwnd, UINT message, WPARAM wParam, L
}
switch (hdr->code)
{
+ /* ComboBoxEx */
+ /* No conversion for CBEN_INSERTITEM and CBEN_DELETEITEM */
+ case CBEN_INSERTITEM:
+ case CBEN_DELETEITEM:
+ {
+ NMCOMBOBOXEXW *nmcbe = (NMCOMBOBOXEXW *)hdr;
+ expect_eq_text_w(nmcbe->ceItem.pszText, test_w);
+ break;
+ }
+ case CBEN_DRAGBEGINA:
+ {
+ NMCBEDRAGBEGINA *nmcbedb = (NMCBEDRAGBEGINA *)hdr;
+ switch (notify_test_data.sub_test_id)
+ {
+ case 0:
+ expect_text_empty(nmcbedb->szText);
+ break;
+ case 1:
+ expect_eq_text_a(nmcbedb->szText, test_a);
+ break;
+ }
+ break;
+ }
+ case CBEN_ENDEDITA:
+ {
+ NMCBEENDEDITA *nmcbeed = (NMCBEENDEDITA *)hdr;
+ switch (notify_test_data.sub_test_id)
+ {
+ case 0:
+ expect_text_empty(nmcbeed->szText);
+ break;
+ case 1:
+ expect_eq_text_a(nmcbeed->szText, test_a);
+ break;
+ }
+ break;
+ }
+ case CBEN_GETDISPINFOA:
+ {
+ NMCOMBOBOXEXA *nmcbe = (NMCOMBOBOXEXA *)hdr;
+ wm_notify_text_handler(&nmcbe->ceItem.pszText, &nmcbe->ceItem.cchTextMax);
+ break;
+ }
/* Toolbar */
/* No conversion for TBN_SAVE and TBN_RESTORE */
case TBN_SAVE:
@@ -724,24 +776,46 @@ static void send_notify_(HWND pager, UINT unicode, UINT ansi, LPARAM lParam, BOO
#define send_notify(a, b, c, d, e) send_notify_(pager, a, b, c, d, e)
/* Send notify to test text field conversion. In parent proc wm_notify_text_handler() handles these messages */
-static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHAR **text, INT *textMax,
- UINT code_unicode, UINT code_ansi, ConversionFlag flags)
+static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, UINT *mask, UINT requiredMask, WCHAR **text,
+ INT *textMax, UINT code_unicode, UINT code_ansi, ConversionFlag flags)
{
notify_test_data.flags = flags;
/* NULL text */
- notify_test_data.sub_test_id = 1;
+ notify_test_data.sub_test_id = 0;
memset(ptr, 0, size);
+ if (mask) *mask = requiredMask;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE, TRUE);
expect_null(*text);
expect_eq_int(*textMax, notify_test_data.text_size);
+ if (mask)
+ {
+ /* No required mask */
+ notify_test_data.sub_test_id = 1;
+ memset(ptr, 0, size);
+ memset(buffer, 0, sizeof(buffer));
+ *text = buffer;
+ *textMax = ARRAY_SIZE(buffer);
+ notify_test_data.text_size = *textMax;
+ send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE, TRUE);
+ if (flags & NO_MASK_SET_NULL)
+ expect_null(*text);
+ else
+ {
+ expect_text_empty(*text);
+ expect_eq_pointer(*text, buffer);
+ }
+ expect_eq_int(*textMax, notify_test_data.text_size);
+ }
+
/* Zero text max size */
notify_test_data.sub_test_id = 2;
memset(ptr, 0, size);
memset(buffer, 0, sizeof(buffer));
+ if (mask) *mask = requiredMask;
*text = buffer;
notify_test_data.text_size = *textMax;
send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE, TRUE);
@@ -753,11 +827,14 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
notify_test_data.sub_test_id = 3;
memset(ptr, 0, size);
memcpy(buffer, test_w, sizeof(test_w));
+ if (mask) *mask = requiredMask;
*text = buffer;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE, TRUE);
- if (!(flags & TO_ANSI) && flags & FROM_ANSI)
+ if (flags & ZERO_BUFFER)
+ expect_text_empty(*text);
+ else if (!(flags & TO_ANSI) && flags & FROM_ANSI)
expect_eq_text_w(*text, t_w);
else
expect_eq_text_w(*text, test_w);
@@ -768,6 +845,7 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
notify_test_data.sub_test_id = 4;
memset(ptr, 0, size);
memset(buffer, 0, sizeof(buffer));
+ if (mask) *mask = requiredMask;
*text = buffer;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
@@ -780,6 +858,7 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
notify_test_data.sub_test_id = 5;
memset(ptr, 0, size);
memset(buffer, 0, sizeof(buffer));
+ if (mask) *mask = requiredMask;
*text = buffer;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
@@ -791,6 +870,7 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
notify_test_data.sub_test_id = 6;
memset(ptr, 0, size);
memset(buffer, 0, sizeof(buffer));
+ if (mask) *mask = requiredMask;
*text = buffer;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
@@ -802,6 +882,7 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
/* NULL text. Parent replace buffer */
notify_test_data.sub_test_id = 7;
memset(ptr, 0, size);
+ if (mask) *mask = requiredMask;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
send_notify(code_unicode, code_ansi, (LPARAM)ptr, TRUE, TRUE);
@@ -813,6 +894,7 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
memset(ptr, 0, size);
memset(buffer, 0, sizeof(buffer));
memset(buffer2, 0, sizeof(buffer2));
+ if (mask) *mask = requiredMask;
*text = buffer;
*textMax = ARRAY_SIZE(buffer);
notify_test_data.text_size = *textMax;
@@ -823,7 +905,50 @@ static void test_wm_notify_text_helper_(HWND pager, void *ptr, size_t size, WCHA
expect_eq_int(*textMax, notify_test_data.text_size);
}
-#define test_wm_notify_text_helper(a, b, c, d, e, f, g) test_wm_notify_text_helper_(pager, a, b, c, d, e, f, g)
+#define test_wm_notify_text_helper(a, b, c, d, e, f, g, h, i) \
+ test_wm_notify_text_helper_(pager, a, b, c, d, e, f, g, h, i)
+
+static void test_wm_notify_comboboxex(HWND pager)
+{
+ NMCOMBOBOXEXW nmcbe;
+ NMCBEDRAGBEGINW nmcbedb;
+ NMCBEENDEDITW nmcbeed;
+
+ /* CBEN_INSERTITEM and CBEN_DELETEITEM will be forwarded unchanged */
+ memset(&nmcbe, 0, sizeof(nmcbe));
+ nmcbe.ceItem.mask = CBEIF_TEXT;
+ nmcbe.ceItem.pszText = test_w;
+ nmcbe.ceItem.cchTextMax = ARRAY_SIZE(test_w);
+ send_notify(CBEN_INSERTITEM, CBEN_INSERTITEM, (LPARAM)&nmcbe, TRUE, TRUE);
+ send_notify(CBEN_DELETEITEM, CBEN_DELETEITEM, (LPARAM)&nmcbe, TRUE, TRUE);
+
+ /* CBEN_DRAGBEGIN */
+ notify_test_data.sub_test_id = 0;
+ memset(&nmcbedb, 0, sizeof(nmcbedb));
+ send_notify(CBEN_DRAGBEGINW, CBEN_DRAGBEGINA, (LPARAM)&nmcbedb, FALSE, TRUE);
+
+ notify_test_data.sub_test_id = 1;
+ memset(&nmcbedb, 0, sizeof(nmcbedb));
+ memcpy(nmcbedb.szText, test_w, sizeof(test_w));
+ send_notify(CBEN_DRAGBEGINW, CBEN_DRAGBEGINA, (LPARAM)&nmcbedb, FALSE, TRUE);
+ expect_eq_text_w(nmcbedb.szText, test_w);
+
+ /* CBEN_ENDEDIT */
+ notify_test_data.sub_test_id = 0;
+ memset(&nmcbeed, 0, sizeof(nmcbeed));
+ send_notify(CBEN_ENDEDITW, CBEN_ENDEDITA, (LPARAM)&nmcbeed, FALSE, TRUE);
+
+ notify_test_data.sub_test_id = 1;
+ memset(&nmcbeed, 0, sizeof(nmcbeed));
+ memcpy(nmcbeed.szText, test_w, sizeof(test_w));
+ send_notify(CBEN_ENDEDITW, CBEN_ENDEDITA, (LPARAM)&nmcbeed, FALSE, TRUE);
+ expect_eq_text_w(nmcbeed.szText, test_w);
+
+ /* CBEN_GETDISPINFO */
+ test_wm_notify_text_helper(&nmcbe, sizeof(nmcbe), &nmcbe.ceItem.mask, CBEIF_TEXT, &nmcbe.ceItem.pszText,
+ &nmcbe.ceItem.cchTextMax, CBEN_GETDISPINFOW, CBEN_GETDISPINFOA,
+ NO_MASK_SET_NULL | ZERO_BUFFER | FROM_ANSI);
+}
static void test_wm_notify_toolbar(HWND pager)
{
@@ -869,10 +994,10 @@ static void test_wm_notify_toolbar(HWND pager)
send_notify(TBN_GETDISPINFOW, TBN_GETDISPINFOW, (LPARAM)&nmtbdi, TRUE, TRUE);
expect_eq_text_a((CHAR *)nmtbdi.pszText, test_a);
- test_wm_notify_text_helper(&nmtb, sizeof(nmtb), &nmtb.pszText, &nmtb.cchText, TBN_GETBUTTONINFOW,
+ test_wm_notify_text_helper(&nmtb, sizeof(nmtb), NULL, 0, &nmtb.pszText, &nmtb.cchText, TBN_GETBUTTONINFOW,
TBN_GETBUTTONINFOA, SET_NULL_EMPTY | TO_ANSI);
- test_wm_notify_text_helper(&nmtbgit, sizeof(nmtbgit), &nmtbgit.pszText, &nmtbgit.cchTextMax, TBN_GETINFOTIPW,
- TBN_GETINFOTIPA, FROM_ANSI);
+ test_wm_notify_text_helper(&nmtbgit, sizeof(nmtbgit), NULL, 0, &nmtbgit.pszText, &nmtbgit.cchTextMax,
+ TBN_GETINFOTIPW, TBN_GETINFOTIPA, FROM_ANSI);
}
static void test_wm_notify_tooltip(HWND pager)
@@ -979,6 +1104,7 @@ static void test_wm_notify(void)
ok(child1_wnd != NULL, "CreateWindow failed\n");
SendMessageW(pager, PGM_SETCHILD, 0, (LPARAM)child1_wnd);
+ test_wm_notify_comboboxex(pager);
test_wm_notify_toolbar(pager);
test_wm_notify_tooltip(pager);
--
2.18.0
More information about the wine-devel
mailing list