[PATCH v6] comctl32: Implement handling of EM_SETCUEBANNER/EM_GETCUEBANNER messages.

Sergio Gómez Del Real sdelreal at codeweavers.com
Mon Oct 29 22:10:10 CDT 2018


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 dlls/comctl32/edit.c       | 67 ++++++++++++++++++++++++++++++++
 dlls/comctl32/tests/edit.c | 78 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+)

diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c
index f0180adfbe..aeba9f73e7 100644
--- a/dlls/comctl32/edit.c
+++ b/dlls/comctl32/edit.c
@@ -131,6 +131,7 @@ typedef struct
 					   should be sent to the first parent. */
 	HWND hwndListBox;		/* handle of ComboBox's listbox or NULL */
 	INT wheelDeltaRemainder;        /* scroll wheel delta left over after scrolling whole lines */
+       WCHAR *cue_banner_text;
 	/*
 	 *	only for multi line controls
 	 */
@@ -2181,6 +2182,12 @@ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev)
 		x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE);
 	} else
 		x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE);
+
+       if (es->cue_banner_text && es->text_length == 0 && !(es->flags & EF_FOCUSED))
+       {
+	       SetTextColor(dc, GetSysColor(COLOR_GRAYTEXT));
+	       TextOutW(dc, x, y, es->cue_banner_text, strlenW(es->cue_banner_text));
+       }
 }
 
 
@@ -4152,6 +4159,57 @@ static LRESULT EDIT_EM_GetThumb(EDITSTATE *es)
                         EDIT_WM_HScroll(es, EM_GETTHUMB, 0));
 }
 
+static inline WCHAR *heap_strdupW(const WCHAR *str)
+{
+    int len = strlenW(str) + 1;
+    WCHAR *ret = heap_alloc(len * sizeof(WCHAR));
+    strcpyW(ret, str);
+    return ret;
+}
+
+/*********************************************************************
+ *
+ *	EM_SETCUEBANNER
+ *
+ */
+static BOOL EDIT_EM_SetCueBanner(EDITSTATE *es, BOOL focus, const WCHAR *cue_text)
+{
+    if (es->style & ES_MULTILINE || !cue_text)
+        return FALSE;
+
+    if (focus)
+        FIXME("cue banner for focused control not implemented.\n");
+
+    heap_free(es->cue_banner_text);
+    es->cue_banner_text = heap_strdupW(cue_text);
+
+    return TRUE;
+}
+
+/*********************************************************************
+ *
+ *	EM_GETCUEBANNER
+ *
+ */
+static BOOL EDIT_EM_GetCueBanner(EDITSTATE *es, WCHAR *buf, DWORD size)
+{
+    if (es->style & ES_MULTILINE)
+        return FALSE;
+
+    if (!es->cue_banner_text)
+    {
+        if (buf && size)
+            *buf = 0;
+        return FALSE;
+    }
+    else
+    {
+        if (buf)
+            lstrcpynW(buf, es->cue_banner_text, size);
+        return TRUE;
+    }
+}
+
 
 /********************************************************************
  *
@@ -4489,6 +4547,7 @@ static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es)
 
     SetWindowLongPtrW( es->hwndSelf, 0, 0 );
     heap_free(es->undo_text);
+    heap_free(es->cue_banner_text);
     heap_free(es);
 
     return 0;
@@ -4703,6 +4762,14 @@ static LRESULT CALLBACK EDIT_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
         result = EDIT_EM_CharFromPos(es, (short)LOWORD(lParam), (short)HIWORD(lParam));
         break;
 
+    case EM_SETCUEBANNER:
+        result = EDIT_EM_SetCueBanner(es, (BOOL)wParam, (const WCHAR *)lParam);
+        break;
+
+    case EM_GETCUEBANNER:
+        result = EDIT_EM_GetCueBanner(es, (WCHAR *)wParam, (DWORD)lParam);
+        break;
+
     /* End of the EM_ messages which were in numerical order; what order
      * are these in?  vaguely alphabetical?
      */
diff --git a/dlls/comctl32/tests/edit.c b/dlls/comctl32/tests/edit.c
index a5097d1cbb..bc44d0c240 100644
--- a/dlls/comctl32/tests/edit.c
+++ b/dlls/comctl32/tests/edit.c
@@ -3061,6 +3061,83 @@ static const struct message killfocus_combined_seq[] =
     { 0 }
 };
 
+static void test_cue_banner(void)
+{
+    HWND hwnd_edit;
+    BOOL ret;
+    static WCHAR getcuetestW[5] = {'T',0};
+    static const WCHAR testcmp1W[] = {'T','e','s','t',0};
+    static const WCHAR testcmp2W[] = {'T','e','s',0};
+    static const WCHAR emptyW[] = {0};
+
+    hwnd_edit = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
+
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
+    if (lstrcmpW(getcuetestW, emptyW) != 0)
+    {
+        win_skip("skipping for Win XP and 2003 Server.\n");
+        DestroyWindow(hwnd_edit);
+        return;
+    }
+    ok(lstrcmpW(getcuetestW, emptyW) == 0, "First char is %c\n", getcuetestW[0]);
+    ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
+
+    lstrcpyW(getcuetestW, testcmp1W);
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 0);
+    ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "String was %s.\n", wine_dbgstr_w(getcuetestW));
+    ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
+
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, 0, 0);
+    ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
+
+    ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, 0);
+    ok(ret == FALSE, "EM_SETCUEBANNER should have returned FALSE.\n");
+
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, 0, 0);
+    ok(ret == FALSE, "EM_GETCUEBANNER should have returned FALSE.\n");
+
+    lstrcpyW(getcuetestW, testcmp1W);
+    ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)getcuetestW);
+    ok(ret == TRUE, "EM_SETCUEBANNER should have returned TRUE.\n");
+
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, 0, 5);
+    ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
+
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
+    ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
+    ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
+
+    ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)emptyW);
+    ok(ret == TRUE, "EM_SETCUEBANNER should have returned TRUE.\n");
+
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
+    ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
+    ok(lstrcmpW(getcuetestW, emptyW) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
+
+    /* EM_GETCUEBANNER's buffer size includes null char */
+    ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)testcmp1W);
+    ok(ret == TRUE, "EM_SETCUEBANNER should have returned TRUE.\n");
+    memset(getcuetestW, 0, lstrlenW(testcmp1W)*sizeof(WCHAR));
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, (LPARAM)lstrlenW(testcmp1W)+1);
+    ok(ret == TRUE, "EM_GETCUEBANNER should have returned TRUE.\n");
+    ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
+    memset(getcuetestW, 0, lstrlenW(testcmp1W)*sizeof(WCHAR));
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, (LPARAM)lstrlenW(testcmp1W));
+    ok(lstrcmpW(getcuetestW, testcmp2W) == 0, "EM_GETCUEBANNER returned string %s.\n", wine_dbgstr_w(getcuetestW));
+    DestroyWindow(hwnd_edit);
+
+    /* setting cue banner fails for multi-line edit controls */
+    hwnd_edit = create_editcontrolW(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0);
+    lstrcpyW(getcuetestW, testcmp1W);
+    ret = SendMessageW(hwnd_edit, EM_GETCUEBANNER, (WPARAM)getcuetestW, 5);
+    ok(ret == FALSE, "EM_SETCUEBANNER.\n");
+    ok(lstrcmpW(getcuetestW, testcmp1W) == 0, "String was %s.\n", wine_dbgstr_w(getcuetestW));
+    ret = SendMessageW(hwnd_edit, EM_SETCUEBANNER, 0, (LPARAM)getcuetestW);
+    ok(ret == FALSE, "EM_SETCUEBANNER.\n");
+
+    DestroyWindow(hwnd_edit);
+}
+
 static void test_change_focus(void)
 {
     HWND hwnd, parent_wnd;
@@ -3138,6 +3215,7 @@ START_TEST(edit)
     test_EM_GETLINE();
     test_wordbreak_proc();
     test_change_focus();
+    test_cue_banner();
 
     UnregisterWindowClasses();
 
-- 
2.17.1




More information about the wine-devel mailing list