[TRY3]user32/tests: add tests for creating subclassed builtin-class windows
Hongbo Ni
hongbo at njstar.com
Thu Aug 7 21:48:57 CDT 2008
Changes since TRY2 - thanks to Dmitry Timoshkov for advice.
1. adds extra bulitin classes: ScrollBar,Message,DDEMLEvent & all #327xx;
2. make sure created hwnd is valid;
3. more tests for unicodeness of built-in-class window before subclassing;
4. add more todo_wine for those extra classes without subclassing.
Tested on Windows Vista SP1, XP SP3.
---
dlls/user32/tests/class.c | 276 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 276 insertions(+), 0 deletions(-)
diff --git a/dlls/user32/tests/class.c b/dlls/user32/tests/class.c
index 8412e8b..ede8dc8 100644
--- a/dlls/user32/tests/class.c
+++ b/dlls/user32/tests/class.c
@@ -2,6 +2,7 @@
*
* Copyright 2002 Mike McCormack
* Copyright 2003 Alexandre Julliard
+ * Copyright 2008 Hongbo Ni
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -32,6 +33,7 @@
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
+#include "windows.h"
/* we don't want to include commctrl.h: */
static const CHAR WC_EDITA[] = "Edit";
@@ -778,6 +780,279 @@ static void test_builtinproc(void)
DestroyWindow(hwnd);
}
+#define MAX_CLASSNAME_LEN 11
+static void test_builtin_class_subclassed(const char *classA, BOOL has_text)
+{
+ HWND hwnd, hwnd2;
+ WNDPROC oldproc;
+ WCHAR classW[MAX_CLASSNAME_LEN];
+ int len;
+
+ /* convert to Unicode name, return len includes null terminating char */
+ if((int)strlen(classA)+1 > MAX_CLASSNAME_LEN)
+ {
+ trace("MAX_CLASSNAME_LEN is too short for class %s, require %d\n", classA, strlen(classA)+1);
+ return;
+ }
+ len = MultiByteToWideChar( CP_ACP, 0, classA, -1, classW, MAX_CLASSNAME_LEN );
+ if(len == 0)
+ {
+ trace("MultiByteToWideChar failed to convert class %s to Unicode\n", classA);
+ return;
+ }
+
+ /* create a unicode builtin-class window without subclass */
+ hwnd = CreateWindowExW(0, classW, NULL, WS_POPUP, 0, 0, 100, 100, NULL, 0, 0, NULL);
+ ok((hwnd != NULL), "%s - CreateWindowExW failed to create a Window\n", classA);
+ if(hwnd == NULL) return;
+
+ ok(IsWindowUnicode(hwnd),
+ "%s - CreateWindowExW should create a Unicode window (not subclassed)\n", classA);
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a Unicode wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC));
+
+ if(strcmp(classA, "Edit") == 0 ) /* Edit is special */
+ {
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC));
+ }
+ else
+ {
+ if(!has_text && strcmp(classA, "ScrollBar") != 0)
+ {
+ /* this block is the same as next block, but wine fails on some classes */
+ todo_wine
+ {
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC));
+ }
+ }
+ else
+ {
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC));
+ }
+ }
+ DestroyWindow(hwnd);
+
+ /* create an ansi builtin-class window without subclass */
+ hwnd = CreateWindowExA(0, classA, NULL, WS_POPUP, 0, 0, 100, 100, NULL, 0, 0, NULL);
+ ok((hwnd != NULL), "%s - CreateWindowExA failed to create a Window\n", classA);
+ if(hwnd == NULL) return;
+
+ if(has_text)
+ {
+ ok(!IsWindowUnicode(hwnd),
+ "%s - CreateWindowExA should create an Ansi window (not subclassed)\n", classA);
+ }
+ else
+ {
+ if(strcmp(classA, "ScrollBar") == 0 )
+ {
+ /* this block is the same as next block, but wine fails on ScrollBar */
+ todo_wine
+ {
+ ok(IsWindowUnicode(hwnd),
+ "%s - CreateWindowExA should create a Unicode window (not subclassed)\n", classA);
+ }
+ }
+ else
+ {
+ ok(IsWindowUnicode(hwnd),
+ "%s - CreateWindowExA should create a Unicode window (not subclassed)\n", classA);
+ }
+ }
+
+ if(!has_text && strcmp(classA, "ScrollBar") != 0)
+ {
+ /* this block is the same as next block, but wine fails on some classes */
+ todo_wine
+ {
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC));
+ }
+ }
+ else
+ {
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd, GWLP_WNDPROC));
+ }
+
+ if(strcmp(classA, "Edit") == 0 ) /* Edit is special */
+ {
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC));
+ }
+ else
+ {
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a Unicode wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd, GWLP_WNDPROC));
+ }
+ /* DestroyWindow(hwnd) at end - need to use hwnd for subclass */
+
+ /** subclass builtin class globally using SetClassLongPtrA with ClassTest_WndProc2(A) **/
+ oldproc = (WNDPROC)SetClassLongPtrA( hwnd, GCLP_WNDPROC, (ULONG_PTR)ClassTest_WndProc2);
+ if(!has_text && strcmp(classA, "ScrollBar") != 0)
+ {
+ /* this block is the same as next block, but wine fails on some classes */
+ todo_wine
+ {
+ ok(!IS_WNDPROC_HANDLE(oldproc),
+ "%s - SetClassLongPtrA should not return a wndproc handle, got %p\n", classA, (void *)oldproc);
+ }
+ }
+ else
+ {
+ ok(!IS_WNDPROC_HANDLE(oldproc),
+ "%s - SetClassLongPtrA should not return a wndproc handle, got %p\n", classA, (void *)oldproc);
+ }
+ ok(!IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)),
+ "%s - GetClassLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC));
+ ok(IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)),
+ "%s - GetClassLongPtrW should return a wndproc handle, got %p\n",
+ classA, (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC));
+
+ /* create a unicode builtin-class window after subclassed with SetClassLongPtrA*/
+ hwnd2 = CreateWindowExW(0, classW, NULL, WS_POPUP, 0, 0, 100, 100, NULL, 0, 0, NULL);
+ ok((hwnd2 != NULL), "%s - CreateWindowExW failed to create a Window\n", classA);
+ if(hwnd2 == NULL) return;
+
+ ok(!IsWindowUnicode(hwnd2),
+ "%s - CreateWindowExW should create an Ansi window (subclassed by SetClassLongPtrA)\n", classA);
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC));
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC));
+ DestroyWindow(hwnd2);
+
+ /* create a ansi builtin-class window after subclassed with SetClassLongPtrA */
+ hwnd2 = CreateWindowExA(0, classA, NULL, WS_POPUP, 0, 0, 100, 100, NULL, 0, 0, NULL);
+ ok((hwnd2 != NULL), "%s - CreateWindowExA failed to create a Window\n", classA);
+ if(hwnd2 == NULL) return;
+
+ ok(!IsWindowUnicode(hwnd2),
+ "%s - CreateWindowExA should create an Ansi window (subclassed by SetClassLongPtrA)\n", classA);
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC));
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC));
+ DestroyWindow(hwnd2);
+
+ SetWindowLongPtrA( hwnd, GCLP_WNDPROC, (ULONG_PTR)oldproc); /* restore procA */
+
+ /** subclass builtin class globally using SetClassLongPtrW with ClassTest_WndProc(W) **/
+ oldproc = (WNDPROC)SetClassLongPtrW( hwnd, GCLP_WNDPROC, (ULONG_PTR)ClassTest_WndProc);
+ ok(IS_WNDPROC_HANDLE(oldproc),
+ "%s - SetClassLongPtrW should not return a wndproc handle, got %p\n",
+ classA, (void *)oldproc);
+ ok(IS_WNDPROC_HANDLE(GetClassLongPtrA(hwnd, GCLP_WNDPROC)),
+ "%s - GetClassLongPtrA should return a wndproc handle, got %p\n",
+ classA, (void *)GetClassLongPtrA(hwnd, GCLP_WNDPROC));
+ ok(!IS_WNDPROC_HANDLE(GetClassLongPtrW(hwnd, GCLP_WNDPROC)),
+ "%s - GetClassLongPtrW should return a Unicode wndproc, got %p\n",
+ classA, (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC));
+
+ /* create a unicode builtin-class window after subclassed with SetClassLongPtrW */
+ hwnd2 = CreateWindowExW(0, classW, NULL, WS_POPUP, 0, 0, 100, 100, NULL, 0, 0, NULL);
+ ok((hwnd2 != NULL), "%s - CreateWindowExW failed to create a Window\n", classA);
+ if(hwnd2 == NULL) return;
+
+ ok(IsWindowUnicode(hwnd2),
+ "%s - CreateWindowExW should create a Unicode window (subclassed by SetClassLongPtrW)\n", classA);
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC));
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a Unicode wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC));
+ /* ClassTest_WndProc handles Unciode message - expected */
+ ok(((WNDPROC)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC) == ClassTest_WndProc),
+ "%s - GetWindowLongPtrW should return ClassTest_WndProc, %p vs %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC), ClassTest_WndProc);
+ DestroyWindow(hwnd2);
+
+ /* create an ansi builtin-class window after subclassed with SetClassLongPtrW */
+ hwnd2 = CreateWindowExA(0, classA, NULL, WS_POPUP, 0, 0, 100, 100, NULL, 0, 0, NULL);
+ ok((hwnd2 != NULL), "%s - CreateWindowExA failed to create a Window\n", classA);
+ if(hwnd2 == NULL) return;
+
+ if(has_text)
+ {
+ todo_wine
+ {
+ ok(!IsWindowUnicode(hwnd2),
+ "%s - CreateWindowExA should create an Ansi window (subclassed by SetClassLongPtrW)\n", classA);
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return an Ansi wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC));
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC));
+
+ /* ClassTest_WndProc(W) should also handle Ansi message - a window Hack */
+ ok(((WNDPROC)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC) == ClassTest_WndProc),
+ "%s - GetWindowLongPtrA should return ClassTest_WndProc, %p vs %p\n", classA,
+ (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC), ClassTest_WndProc);
+ } /* todo_wine */
+ }
+ else
+ {
+ ok(IsWindowUnicode(hwnd2),
+ "%s - CreateWindowExA should create a Unicode window (subclassed by SetClassLongPtrW)\n", classA);
+ ok(!IS_WNDPROC_HANDLE(GetWindowLongPtrW(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrW should return a Unicode wndproc, got %p\n",
+ classA, (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC));
+ ok(IS_WNDPROC_HANDLE(GetWindowLongPtrA(hwnd2, GWLP_WNDPROC)),
+ "%s - GetWindowLongPtrA should return a wndproc handle, got %p\n",
+ classA, (void *)GetWindowLongPtrA(hwnd2, GWLP_WNDPROC));
+
+ /* ClassTest_WndProc(W) should handle Unicode message - It's normal */
+ ok(((WNDPROC)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC) == ClassTest_WndProc),
+ "%s - GetWindowLongPtrW should return ClassTest_WndProc, %p vs %p\n", classA,
+ (void *)GetWindowLongPtrW(hwnd2, GWLP_WNDPROC), ClassTest_WndProc);
+ }
+ DestroyWindow(hwnd2);
+
+ SetWindowLongPtrW( hwnd, GCLP_WNDPROC, (ULONG_PTR)oldproc);
+ DestroyWindow(hwnd);
+}
+
+static void test_all_builtin_classes_subclassed(void)
+{
+ /* test builtin classes that deals with Ansi/Unicode text */
+ test_builtin_class_subclassed("Edit", 1);
+ test_builtin_class_subclassed("Button", 1);
+ test_builtin_class_subclassed("Static", 1);
+ test_builtin_class_subclassed("ComboBox", 1);
+ test_builtin_class_subclassed("ComboLBox", 1);
+ test_builtin_class_subclassed("ListBox", 1);
+ test_builtin_class_subclassed("#32770", 1); /* dialog */
+
+ /* test builtin classes that does not deal with Ansi/Unicode text */
+ test_builtin_class_subclassed("ScrollBar", 0);
+ test_builtin_class_subclassed("Message", 0);
+ test_builtin_class_subclassed("#32768", 0); /* menu */
+ test_builtin_class_subclassed("#32769", 0); /* desktop */
+ test_builtin_class_subclassed("#32772", 0); /* icon title */
+ todo_wine
+ { /* those 2 classes fail on the first call to CreateWindowExW */
+ test_builtin_class_subclassed("DDEMLEvent", 0);
+ test_builtin_class_subclassed("#32771", 0); /* task switch */
+ }
+}
static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@@ -842,6 +1117,7 @@ START_TEST(class)
CreateDialogParamTest(hInstance);
test_styles();
test_builtinproc();
+ test_all_builtin_classes_subclassed();
/* this test unregisters the Button class so it should be executed at the end */
test_instances();
--
1.5.6.1.1071.g76fb
More information about the wine-patches
mailing list