[WineTests]
authorJames Tabor <james.tabor@reactos.org>
Sun, 2 Jun 2013 20:45:51 +0000 (20:45 +0000)
committerJames Tabor <james.tabor@reactos.org>
Sun, 2 Jun 2013 20:45:51 +0000 (20:45 +0000)
- Sync to 1.5.31.

svn path=/trunk/; revision=59156

rostests/winetests/user32/edit.c
rostests/winetests/user32/listbox.c
rostests/winetests/user32/scroll.c

index 11550f7..700dfb0 100755 (executable)
@@ -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();
 }
index ef4a35b..0a000cc 100644 (file)
@@ -274,30 +274,42 @@ static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
     return DefWindowProc(hwnd, msg, wparam, lparam);
 }
 
-static void test_ownerdraw(void)
+static HWND create_parent( void )
 {
     WNDCLASS cls;
-    HWND parent, hLB;
-    INT ret;
-    RECT rc;
+    HWND parent;
+    static ATOM class;
 
-    cls.style = 0;
-    cls.lpfnWndProc = main_window_proc;
-    cls.cbClsExtra = 0;
-    cls.cbWndExtra = 0;
-    cls.hInstance = GetModuleHandle(0);
-    cls.hIcon = 0;
-    cls.hCursor = LoadCursor(0, IDC_ARROW);
-    cls.hbrBackground = GetStockObject(WHITE_BRUSH);
-    cls.lpszMenuName = NULL;
-    cls.lpszClassName = "main_window_class";
-    ok (RegisterClass(&cls), "RegisterClass failed\n");
+    if (!class)
+    {
+        cls.style = 0;
+        cls.lpfnWndProc = main_window_proc;
+        cls.cbClsExtra = 0;
+        cls.cbWndExtra = 0;
+        cls.hInstance = GetModuleHandle(0);
+        cls.hIcon = 0;
+        cls.hCursor = LoadCursor(0, IDC_ARROW);
+        cls.hbrBackground = GetStockObject(WHITE_BRUSH);
+        cls.lpszMenuName = NULL;
+        cls.lpszClassName = "main_window_class";
+        class = RegisterClass( &cls );
+    }
 
     parent = CreateWindowEx(0, "main_window_class", NULL,
                             WS_POPUP | WS_VISIBLE,
                             100, 100, 400, 400,
                             GetDesktopWindow(), 0,
                             GetModuleHandle(0), NULL);
+    return parent;
+}
+
+static void test_ownerdraw(void)
+{
+    HWND parent, hLB;
+    INT ret;
+    RECT rc;
+
+    parent = create_parent();
     assert(parent);
 
     hLB = create_listbox(LBS_OWNERDRAWFIXED | WS_CHILD | WS_VISIBLE, parent);
@@ -1498,6 +1510,84 @@ static void test_listbox_dlgdir(void)
     DestroyWindow(hWnd);
 }
 
+static void test_set_count( void )
+{
+    HWND parent, listbox;
+    LONG ret;
+    RECT r;
+
+    parent = create_parent();
+    listbox = create_listbox( LBS_OWNERDRAWFIXED | LBS_NODATA | WS_CHILD | WS_VISIBLE, parent );
+
+    UpdateWindow( listbox );
+    GetUpdateRect( listbox, &r, TRUE );
+    ok( IsRectEmpty( &r ), "got non-empty rect\n");
+
+    ret = SendMessage( listbox, LB_SETCOUNT, 100, 0 );
+    ok( ret == 0, "got %d\n", ret );
+    ret = SendMessage( listbox, LB_GETCOUNT, 0, 0 );
+    ok( ret == 100, "got %d\n", ret );
+
+    GetUpdateRect( listbox, &r, TRUE );
+    ok( !IsRectEmpty( &r ), "got empty rect\n");
+
+    ValidateRect( listbox, NULL );
+    GetUpdateRect( listbox, &r, TRUE );
+    ok( IsRectEmpty( &r ), "got non-empty rect\n");
+
+    ret = SendMessage( listbox, LB_SETCOUNT, 99, 0 );
+    ok( ret == 0, "got %d\n", ret );
+
+    GetUpdateRect( listbox, &r, TRUE );
+    ok( !IsRectEmpty( &r ), "got empty rect\n");
+
+    DestroyWindow( listbox );
+    DestroyWindow( parent );
+}
+
+static DWORD (WINAPI *pGetListBoxInfo)(HWND);
+static int lb_getlistboxinfo;
+
+static LRESULT WINAPI listbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+    WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
+
+    if (message == LB_GETLISTBOXINFO)
+        lb_getlistboxinfo++;
+
+    return CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
+}
+
+static void test_GetListBoxInfo(void)
+{
+    HWND listbox, parent;
+    WNDPROC oldproc;
+    DWORD ret;
+
+    pGetListBoxInfo = (void*)GetProcAddress(GetModuleHandle("user32"), "GetListBoxInfo");
+
+    if (!pGetListBoxInfo)
+    {
+        win_skip("GetListBoxInfo() not available\n");
+        return;
+    }
+
+    parent = create_parent();
+    listbox = create_listbox(WS_CHILD | WS_VISIBLE, parent);
+
+    oldproc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (LONG_PTR)listbox_subclass_proc);
+    SetWindowLongPtrA(listbox, GWLP_USERDATA, (LONG_PTR)oldproc);
+
+    lb_getlistboxinfo = 0;
+    ret = pGetListBoxInfo(listbox);
+    ok(ret > 0, "got %d\n", ret);
+todo_wine
+    ok(lb_getlistboxinfo == 0, "got %d\n", lb_getlistboxinfo);
+
+    DestroyWindow(listbox);
+    DestroyWindow(parent);
+}
+
 START_TEST(listbox)
 {
   const struct listbox_test SS =
@@ -1576,4 +1666,6 @@ START_TEST(listbox)
   test_listbox_item_data();
   test_listbox_LB_DIR();
   test_listbox_dlgdir();
+  test_set_count();
+  test_GetListBoxInfo();
 }
index 1d7e75e..0f0ede2 100644 (file)
@@ -241,7 +241,6 @@ static void scrollbar_test_default( DWORD style)
         ok( min == 0 && max == 0,
                 "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style);
     else
-todo_wine
         ok(( min == 0 && max == 100) ||
                 broken( min == 0 && max == 0), /* Win 9x/ME */
                 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
@@ -253,7 +252,6 @@ todo_wine
         ok( min == 0 && max == 0,
                 "Scroll bar range is %d,%d. Expected 0,0. Style %08x\n", min, max, style);
     else
-todo_wine
         ok(( min == 0 && max == 100) ||
                 broken( min == 0 && max == 0), /* Win 9x/ME */
                 "Scroll bar range is %d,%d. Expected 0,100. Style %08x\n", min, max, style);
@@ -263,7 +261,6 @@ todo_wine
     if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
         ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
     else
-todo_wine
         ok( ret ||
                 broken( !ret), /* Win 9x/ME */
                 "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
@@ -273,7 +270,6 @@ todo_wine
     if( !( style & ( WS_VSCROLL | WS_HSCROLL)))
         ok( !ret, "GetScrollInfo succeeded unexpectedly. Style is %08x\n", style);
     else
-todo_wine
         ok( ret ||
                 broken( !ret), /* Win 9x/ME */
                 "GetScrollInfo failed unexpectedly. Style is %08x\n", style);
@@ -396,6 +392,98 @@ todo_wine
     DestroyWindow( hwnd);
 }
 
+static LRESULT CALLBACK scroll_init_proc(HWND hwnd, UINT msg,
+                                        WPARAM wparam, LPARAM lparam)
+{
+    SCROLLINFO horz, vert;
+    CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
+    BOOL h_ret, v_ret;
+
+    switch(msg)
+    {
+        case WM_NCCREATE:
+            return cs->lpCreateParams ? DefWindowProcA(hwnd, msg, wparam, lparam) :
+                                        TRUE;
+
+        case WM_CREATE:
+            horz.cbSize = sizeof horz;
+            horz.fMask  = SIF_ALL;
+            horz.nMin   = 0xdeadbeaf;
+            horz.nMax   = 0xbaadc0de;
+            vert = horz;
+            h_ret = GetScrollInfo(hwnd, SB_HORZ, &horz);
+            v_ret = GetScrollInfo(hwnd, SB_VERT, &vert);
+
+            if(cs->lpCreateParams)
+            {
+                /* WM_NCCREATE was passed to DefWindowProc */
+                if(cs->style & (WS_VSCROLL | WS_HSCROLL))
+                {
+                    ok(h_ret && v_ret, "GetScrollInfo() should return NON-zero "
+                            "but got h_ret=%d v_ret=%d\n", h_ret, v_ret);
+                    ok(vert.nMin == 0 && vert.nMax == 100,
+                            "unexpected init values(SB_VERT): min=%d max=%d\n",
+                            vert.nMin, vert.nMax);
+                    ok(horz.nMin == 0 && horz.nMax == 100,
+                            "unexpected init values(SB_HORZ): min=%d max=%d\n",
+                            horz.nMin, horz.nMax);
+                }
+                else
+                {
+                    ok(!h_ret && !v_ret, "GetScrollInfo() should return zeru, "
+                            "but got h_ret=%d v_ret=%d\n", h_ret, v_ret);
+                    ok(vert.nMin == 0xdeadbeaf && vert.nMax == 0xbaadc0de,
+                            "unexpected  initialization(SB_VERT): min=%d max=%d\n",
+                            vert.nMin, vert.nMax);
+                    ok(horz.nMin == 0xdeadbeaf && horz.nMax == 0xbaadc0de,
+                            "unexpected  initialization(SB_HORZ): min=%d max=%d\n",
+                            horz.nMin, horz.nMax);
+                }
+            }
+            else
+            {
+                ok(!h_ret && !v_ret, "GetScrollInfo() should return zeru, "
+                    "but got h_ret=%d v_ret=%d\n", h_ret, v_ret);
+                ok(horz.nMin == 0xdeadbeaf && horz.nMax == 0xbaadc0de &&
+                    vert.nMin == 0xdeadbeaf && vert.nMax == 0xbaadc0de,
+                        "unexpected initialization\n");
+            }
+            return FALSE; /* abort creation */
+
+        default:
+            /* need for WM_GETMINMAXINFO, which precedes WM_NCCREATE */
+            return 0;
+    }
+}
+
+static void scrollbar_test_init(void)
+{
+    WNDCLASSEXA wc;
+    CHAR cls_name[] = "scroll_test_class";
+    LONG style[] = {WS_VSCROLL, WS_HSCROLL, WS_VSCROLL | WS_HSCROLL, 0};
+    int i;
+
+    memset( &wc, 0, sizeof wc );
+    wc.cbSize        = sizeof wc;
+    wc.style         = CS_VREDRAW | CS_HREDRAW;
+    wc.hInstance     = GetModuleHandleA(0);
+    wc.hCursor       = LoadCursorA(NULL, IDC_ARROW);
+    wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+    wc.lpszClassName = cls_name;
+    wc.lpfnWndProc   = scroll_init_proc;
+    RegisterClassExA(&wc);
+
+    for(i = 0; i < sizeof style / sizeof style[0]; i++)
+    {
+        /* need not to destroy these windows due creation abort */
+        CreateWindowExA(0, cls_name, NULL, style[i],
+                100, 100, 100, 100, NULL, NULL, wc.hInstance, (LPVOID)TRUE);
+        CreateWindowExA(0, cls_name, NULL, style[i],
+                100, 100, 100, 100, NULL, NULL, wc.hInstance, (LPVOID)FALSE);
+    }
+    UnregisterClassA(cls_name, wc.hInstance);
+}
+
 START_TEST ( scroll )
 {
     WNDCLASSA wc;
@@ -444,6 +532,8 @@ START_TEST ( scroll )
     scrollbar_test_default( WS_VSCROLL);
     scrollbar_test_default( WS_HSCROLL | WS_VSCROLL);
 
+    scrollbar_test_init();
+
     DestroyWindow(hScroll);
     DestroyWindow(hMainWnd);
 }