Detlef Riekenberg : user32/tests: Add tests for EM_GETHANDLE.

Alexandre Julliard julliard at winehq.org
Fri May 17 14:24:34 CDT 2013


Module: wine
Branch: master
Commit: caf1bbba94157211f7ab43b61f46a4b018c8e72e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=caf1bbba94157211f7ab43b61f46a4b018c8e72e

Author: Detlef Riekenberg <wine.dev at web.de>
Date:   Fri May  3 09:22:44 2013 +0200

user32/tests: Add tests for EM_GETHANDLE.

---

 dlls/user32/tests/edit.c |  116 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 116 insertions(+), 0 deletions(-)

diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c
index 11550f7..700dfb0 100644
--- a/dlls/user32/tests/edit.c
+++ b/dlls/user32/tests/edit.c
@@ -2530,6 +2530,120 @@ static void test_dialogmode(void)
     destroy_child_editcontrol(hwEdit);
 }
 
+static void test_EM_GETHANDLE(void)
+{
+    static const char str0[] = "untouched";
+    static const char str1[] = "1111+1111+1111#";
+    static const char str2[] = "2222-2222-2222-2222#";
+    static const char str3[] = "3333*3333*3333*3333*3333#";
+    CHAR    current[42];
+    HWND    hEdit;
+    HLOCAL  hmem;
+    HLOCAL  hmem2;
+    HLOCAL  halloc;
+    char    *buffer;
+    int     len;
+    int     r;
+
+    trace("EDIT: EM_GETHANDLE\n");
+
+    /* EM_GETHANDLE is not supported for a single line edit control */
+    hEdit = create_editcontrol(WS_BORDER, 0);
+    ok(hEdit != NULL, "got %p (expected != NULL)\n", hEdit);
+
+    hmem = (HGLOBAL) SendMessage(hEdit, EM_GETHANDLE, 0, 0);
+    ok(hmem == NULL, "got %p (expected NULL)\n", hmem);
+    DestroyWindow(hEdit);
+
+
+    /* EM_GETHANDLE needs a multiline edit control */
+    hEdit = create_editcontrol(WS_BORDER | ES_MULTILINE, 0);
+    ok(hEdit != NULL, "got %p (expected != NULL)\n", hEdit);
+
+    /* set some text */
+    r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
+    len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
+    ok((r == 1) && (len == lstrlenA(str1)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str1));
+
+    lstrcpyA(current, str0);
+    r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
+    ok((r == lstrlenA(str1)) && !lstrcmpA(current, str1),
+        "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str1), str1);
+
+    hmem = (HGLOBAL) SendMessage(hEdit, EM_GETHANDLE, 0, 0);
+    ok(hmem != NULL, "got %p (expected != NULL)\n", hmem);
+    /* The buffer belongs to the app now. According to MSDN, the app has to LocalFree the
+       buffer, LocalAlloc a new buffer and pass it to the edit control with EM_SETHANDLE. */
+
+    buffer = LocalLock(hmem);
+    ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
+    len = lstrlenA(buffer);
+    ok((len == lstrlenA(str1)) && !lstrcmpA(buffer, str1),
+        "got %d and \"%s\" (expected %d and \"%s\")\n", len, buffer, lstrlenA(str1), str1);
+    LocalUnlock(hmem);
+
+    /* use LocalAlloc first to get a different handle */
+    halloc = LocalAlloc(LMEM_MOVEABLE, 42);
+    ok(halloc != NULL, "got %p (expected != NULL)\n", halloc);
+    /* prepare our new memory */
+    buffer = LocalLock(halloc);
+    ok(buffer != NULL, "got %p (expected != NULL)\n", buffer);
+    lstrcpyA(buffer, str2);
+    LocalUnlock(halloc);
+
+    /* LocalFree the old memory handle before EM_SETHANDLE the new handle */
+    LocalFree(hmem);
+    /* use LocalAlloc after the LocalFree to likely consume the handle */
+    hmem2 = LocalAlloc(LMEM_MOVEABLE, 42);
+    ok(hmem2 != NULL, "got %p (expected != NULL)\n", hmem2);
+
+    SendMessage(hEdit, EM_SETHANDLE, (WPARAM)halloc, 0);
+
+    len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
+    ok(len == lstrlenA(str2), "got %d (expected %d)\n", len, lstrlenA(str2));
+
+    lstrcpyA(current, str0);
+    r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
+    ok((r == lstrlenA(str2)) && !lstrcmpA(current, str2),
+        "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str2), str2);
+
+    /* set a different text */
+    r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str3);
+    len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
+    ok((r == 1) && (len == lstrlenA(str3)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str3));
+
+    lstrcpyA(current, str0);
+    r = SendMessageA(hEdit, WM_GETTEXT, sizeof(current), (LPARAM)current);
+    ok((r == lstrlenA(str3)) && !lstrcmpA(current, str3),
+        "got %d and \"%s\" (expected %d and \"%s\")\n", r, current, lstrlenA(str3), str3);
+
+    LocalFree(hmem2);
+    DestroyWindow(hEdit);
+
+    /* Some apps have bugs ... */
+    hEdit = create_editcontrol(WS_BORDER | ES_MULTILINE, 0);
+
+    /* set some text */
+    r = SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)str1);
+    len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0);
+    ok((r == 1) && (len == lstrlenA(str1)), "got %d and %d (expected 1 and %d)\n", r, len, lstrlenA(str1));
+
+    /* everything is normal upto EM_GETHANDLE */
+    hmem = (HGLOBAL) SendMessage(hEdit, EM_GETHANDLE, 0, 0);
+    /* Some messages still work while other messages fail.
+       After LocalFree the memory handle, messages can crash the app */
+
+    /* A buggy editor used EM_GETHANDLE twice */
+    hmem2 = (HGLOBAL) SendMessage(hEdit, EM_GETHANDLE, 0, 0);
+    ok(hmem2 == hmem, "got %p (expected %p)\n", hmem2, hmem);
+
+    /* Let the edit control free the memory handle */
+    SendMessage(hEdit, EM_SETHANDLE, (WPARAM)hmem2, 0);
+
+    DestroyWindow(hEdit);
+}
+
+
 START_TEST(edit)
 {
     BOOL b;
@@ -2568,5 +2682,7 @@ START_TEST(edit)
     else
         win_skip("EndMenu is not available\n");
 
+    test_EM_GETHANDLE();
+
     UnregisterWindowClasses();
 }




More information about the wine-cvs mailing list