diff --git a/rostests/winetests/user32/class.c b/rostests/winetests/user32/class.c index b7332ac1362..7a2f2b67225 100755 --- a/rostests/winetests/user32/class.c +++ b/rostests/winetests/user32/class.c @@ -28,13 +28,11 @@ #include "wine/test.h" #include "windef.h" #include "winbase.h" +#include "winnls.h" #include "winreg.h" #include "wingdi.h" #include "winuser.h" - -/* we don't want to include commctrl.h: */ -static const CHAR WC_EDITA[] = "Edit"; -static const WCHAR WC_EDITW[] = {'E','d','i','t',0}; +#include "commctrl.h" #define NUMCLASSWORDS 4 @@ -201,9 +199,9 @@ static void ClassTest(HINSTANCE hInstance, BOOL global) static void check_style( const char *name, int must_exist, UINT style, UINT ignore ) { - WNDCLASS wc; + WNDCLASSA wc; - if (GetClassInfo( 0, name, &wc )) + if (GetClassInfoA( 0, name, &wc )) { ok( !(~wc.style & style & ~ignore), "System class %s is missing bits %x (%08x/%08x)\n", name, ~wc.style & style, wc.style, style ); @@ -237,8 +235,8 @@ static void test_styles(void) static void check_class_(int line, HINSTANCE inst, const char *name, const char *menu_name) { - WNDCLASS wc; - UINT atom = GetClassInfo(inst,name,&wc); + WNDCLASSA wc; + UINT atom = GetClassInfoA(inst,name,&wc); ok_(__FILE__,line)( atom, "Class %s %p not found\n", name, inst ); if (atom) { @@ -259,7 +257,7 @@ static void check_instance_( int line, const char *name, HINSTANCE inst, WNDCLASSA wc; HWND hwnd; - ok_(__FILE__,line)( GetClassInfo( inst, name, &wc ), "Couldn't find class %s inst %p\n", name, inst ); + ok_(__FILE__,line)( GetClassInfoA( inst, name, &wc ), "Couldn't find class %s inst %p\n", name, inst ); ok_(__FILE__,line)( wc.hInstance == info_inst, "Wrong info instance %p/%p for class %s\n", wc.hInstance, info_inst, name ); hwnd = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, inst, 0 ); @@ -363,7 +361,7 @@ static void test_instances(void) wcexA.cbSize = sizeof(wcexA); ok( RegisterClassExA( &wcexA ), "Failed with valid number of cbSize bytes\n"); wcexA.cbSize = 0xdeadbeef; - ok( GetClassInfoEx(main_module, wcexA.lpszClassName, &wcexA), "GetClassInfoEx failed\n"); + ok( GetClassInfoExA(main_module, wcexA.lpszClassName, &wcexA), "GetClassInfoEx failed\n"); ok( wcexA.cbSize == 0xdeadbeef, "GetClassInfoEx returned wrong cbSize value %d\n", wcexA.cbSize); UnregisterClassA(wcexA.lpszClassName, main_module); @@ -411,13 +409,13 @@ static void test_instances(void) check_class( kernel32, name, "kernel32" ); check_instance( name, kernel32, kernel32, kernel32 ); check_thread_instance( name, kernel32, kernel32, kernel32 ); - ok( !GetClassInfo( 0, name, &wc ), "Class found with null instance\n" ); + ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" ); ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" ); /* GetClassInfo with instance 0 finds user32 instance */ SetClassLongPtrA( hwnd, GCLP_HMODULE, (LONG_PTR)user32 ); ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); - if (!GetClassInfo( 0, name, &wc )) zero_instance = user32; /* instance 0 not supported on wow64 */ + if (!GetClassInfoA( 0, name, &wc )) zero_instance = user32; /* instance 0 not supported on wow64 */ else { check_instance( name, 0, 0, kernel32 ); @@ -440,7 +438,7 @@ static void test_instances(void) check_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 ); check_thread_instance( name, kernel32, kernel32, kernel32 ); check_thread_instance( name, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0x12345678 ); - ok( !GetClassInfo( 0, name, &wc ), "Class found with null instance\n" ); + ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" ); /* creating a window with instance 0 uses the first class found */ cls.hInstance = (HINSTANCE)0xdeadbeef; @@ -458,7 +456,7 @@ static void test_instances(void) "Didn't get kernel32 class for null instance\n" ); DestroyWindow( hwnd2 ); - r = GetClassName( hwnd, buffer, 4 ); + r = GetClassNameA( hwnd, buffer, 4 ); ok( r == 3, "expected 3, got %d\n", r ); ok( !strcmp( buffer, "__t"), "name wrong: %s\n", buffer ); @@ -484,7 +482,7 @@ static void test_instances(void) check_class( main_module, name, "null" ); check_instance( name, main_module, main_module, main_module ); check_thread_instance( name, main_module, main_module, main_module ); - ok( !GetClassInfo( 0, name, &wc ), "Class found with null instance\n" ); + ok( !GetClassInfoA( 0, name, &wc ), "Class found with null instance\n" ); ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() ); ok( UnregisterClassA( name, 0 ), "Unregister failed for null instance\n" ); @@ -581,12 +579,12 @@ static void test_instances(void) check_thread_instance( "BUTTON", user32, zero_instance, user32 ); /* we can unregister system classes */ - ok( GetClassInfo( 0, "BUTTON", &wc ), "Button class not found with null instance\n" ); - ok( GetClassInfo( kernel32, "BUTTON", &wc ), "Button class not found with kernel32\n" ); - ok( UnregisterClass( "BUTTON", (HINSTANCE)0x12345678 ), "Failed to unregister button\n" ); - ok( !UnregisterClass( "BUTTON", (HINSTANCE)0x87654321 ), "Unregistered button a second time\n" ); + ok( GetClassInfoA( 0, "BUTTON", &wc ), "Button class not found with null instance\n" ); + ok( GetClassInfoA( kernel32, "BUTTON", &wc ), "Button class not found with kernel32\n" ); + ok( UnregisterClassA( "BUTTON", (HINSTANCE)0x12345678 ), "Failed to unregister button\n" ); + ok( !UnregisterClassA( "BUTTON", (HINSTANCE)0x87654321 ), "Unregistered button a second time\n" ); ok( GetLastError() == ERROR_CLASS_DOES_NOT_EXIST, "Wrong error code %d\n", GetLastError() ); - ok( !GetClassInfo( 0, "BUTTON", &wc ), "Button still exists\n" ); + ok( !GetClassInfoA( 0, "BUTTON", &wc ), "Button still exists\n" ); /* last error not set reliably */ /* we can change the instance of a system class */ @@ -624,10 +622,10 @@ static void test_builtinproc(void) HWND hwnd; int i; - pDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcA"); - pDefWindowProcW = (void *)GetProcAddress(GetModuleHandle("user32.dll"), "DefWindowProcW"); - pNtdllDefWindowProcA = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtdllDefWindowProc_A"); - pNtdllDefWindowProcW = (void *)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtdllDefWindowProc_W"); + pDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcA"); + pDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "DefWindowProcW"); + pNtdllDefWindowProcA = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_A"); + pNtdllDefWindowProcW = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtdllDefWindowProc_W"); /* On Vista+, the user32.dll export DefWindowProcA/W is forwarded to */ /* ntdll.NtdllDefWindowProc_A/W. However, the wndproc returned by */ @@ -641,7 +639,7 @@ static void test_builtinproc(void) { ZeroMemory(&cls, sizeof(cls)); cls.cbSize = sizeof(cls); - cls.hInstance = GetModuleHandle(NULL); + cls.hInstance = GetModuleHandleA(NULL); cls.hbrBackground = GetStockObject (WHITE_BRUSH); if (i & 1) cls.lpfnWndProc = pDefWindowProcA; @@ -660,7 +658,7 @@ static void test_builtinproc(void) } ok(atom != 0, "Couldn't register class, i=%d, %d\n", i, GetLastError()); - hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), NULL); + hwnd = CreateWindowA(classA, NULL, 0, 0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), NULL); ok(hwnd != NULL, "Couldn't create window i=%d\n", i); ok(GetWindowLongPtrA(hwnd, GWLP_WNDPROC) == (LONG_PTR)pDefWindowProcA, "Wrong ANSI wndproc: %p vs %p\n", @@ -674,21 +672,21 @@ static void test_builtinproc(void) (void *)GetClassLongPtrW(hwnd, GCLP_WNDPROC), pDefWindowProcW); DestroyWindow(hwnd); - UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL)); + UnregisterClassA((LPSTR)(DWORD_PTR)atom, GetModuleHandleA(NULL)); } } /* built-in winproc - window A/W type automatically detected */ ZeroMemory(&cls, sizeof(cls)); cls.cbSize = sizeof(cls); - cls.hInstance = GetModuleHandle(NULL); + cls.hInstance = GetModuleHandleA(NULL); cls.hbrBackground = GetStockObject (WHITE_BRUSH); cls.lpszClassName = classA; cls.lpfnWndProc = pDefWindowProcW; atom = RegisterClassExA(&cls); hwnd = CreateWindowExW(0, classW, NULL, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0); + CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleW(NULL), 0); ok(IsWindowUnicode(hwnd), "Windows should be Unicode\n"); SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)pDefWindowProcA); ok(IsWindowUnicode(hwnd), "Windows should have remained Unicode\n"); @@ -706,12 +704,12 @@ static void test_builtinproc(void) ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have switched window to ANSI\n"); DestroyWindow(hwnd); - UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL)); + UnregisterClassA((LPSTR)(DWORD_PTR)atom, GetModuleHandleA(NULL)); /* custom winproc - the same function can be used as both A and W*/ ZeroMemory(&cls, sizeof(cls)); cls.cbSize = sizeof(cls); - cls.hInstance = GetModuleHandle(NULL); + cls.hInstance = GetModuleHandleA(NULL); cls.hbrBackground = GetStockObject (WHITE_BRUSH); cls.lpszClassName = classA; cls.lpfnWndProc = ClassTest_WndProc2; @@ -726,7 +724,7 @@ static void test_builtinproc(void) ok(IsWindowUnicode(hwnd) == FALSE, "SetWindowLongPtrA should have changed window to ANSI\n"); DestroyWindow(hwnd); - UnregisterClass((LPSTR)(DWORD_PTR)atom, GetModuleHandle(NULL)); + UnregisterClassA((LPSTR)(DWORD_PTR)atom, GetModuleHandleA(NULL)); /* For most of the builtin controls both GetWindowLongPtrA and W returns a pointer that is executed directly * by CallWindowProcA/W */ @@ -736,7 +734,7 @@ static void test_builtinproc(void) hwnd = CreateWindowExA(0, NORMAL_CLASSES[i], classA, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, NULL, 0); ok(hwnd != NULL, "Couldn't create window of class %s\n", NORMAL_CLASSES[i]); - SetWindowText(hwnd, classA); /* ComboBox needs this */ + SetWindowTextA(hwnd, classA); /* ComboBox needs this */ procA = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_WNDPROC); procW = (WNDPROC)GetWindowLongPtrW(hwnd, GWLP_WNDPROC); ok(!IS_WNDPROC_HANDLE(procA), "procA should not be a handle for %s (%p)\n", NORMAL_CLASSES[i], procA); @@ -837,30 +835,30 @@ static void test_builtinproc(void) static LRESULT WINAPI TestDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - return DefWindowProc(hWnd, uMsg, wParam, lParam); + return DefWindowProcA(hWnd, uMsg, wParam, lParam); } static BOOL RegisterTestDialog(HINSTANCE hInstance) { - WNDCLASSEX wcx; + WNDCLASSEXA wcx; ATOM atom = 0; - ZeroMemory(&wcx, sizeof(WNDCLASSEX)); + ZeroMemory(&wcx, sizeof(WNDCLASSEXA)); wcx.cbSize = sizeof(wcx); wcx.lpfnWndProc = TestDlgProc; wcx.cbClsExtra = 0; wcx.cbWndExtra = DLGWINDOWEXTRA; wcx.hInstance = hInstance; - wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); - wcx.hCursor = LoadCursor(NULL, IDC_ARROW); + wcx.hIcon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION); + wcx.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); wcx.hbrBackground = GetStockObject(WHITE_BRUSH); wcx.lpszClassName = "TestDialog"; wcx.lpszMenuName = "TestDialog"; - wcx.hIconSm = LoadImage(hInstance, MAKEINTRESOURCE(5), IMAGE_ICON, + wcx.hIconSm = LoadImageA(hInstance, (LPCSTR)MAKEINTRESOURCE(5), IMAGE_ICON, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR); - atom = RegisterClassEx(&wcx); + atom = RegisterClassExA(&wcx); ok(atom != 0, "RegisterClassEx returned 0\n"); return atom; @@ -874,7 +872,7 @@ static void CreateDialogParamTest(HINSTANCE hInstance) if (RegisterTestDialog(hInstance)) { - hWndMain = CreateDialogParam(hInstance, "CLASS_TEST_DIALOG", NULL, 0, 0); + hWndMain = CreateDialogParamA(hInstance, "CLASS_TEST_DIALOG", NULL, 0, 0); ok(hWndMain != NULL, "CreateDialogParam returned NULL\n"); ShowWindow(hWndMain, SW_SHOW); DestroyWindow(hWndMain); @@ -901,8 +899,8 @@ static void test_extra_values(void) int i; for(i=0; i< sizeof(extra_values)/sizeof(extra_values[0]); i++) { - WNDCLASSEX wcx; - BOOL ret = GetClassInfoEx(NULL,extra_values[i].name,&wcx); + WNDCLASSEXA wcx; + BOOL ret = GetClassInfoExA(NULL,extra_values[i].name,&wcx); ok( ret, "GetClassInfo (0) failed for global class %s\n", extra_values[i].name); if (!ret) continue; @@ -1029,9 +1027,91 @@ static void test_icons(void) DestroyWindow(hwnd); } +static void test_comctl32_class( const char *name ) +{ + WNDCLASSA wcA; + WNDCLASSW wcW; + BOOL ret; + HMODULE module; + WCHAR nameW[20]; + HWND hwnd; + + module = GetModuleHandleA( "comctl32" ); + ok( !module, "comctl32 already loaded\n" ); + ret = GetClassInfoA( 0, name, &wcA ); + ok( ret || broken(!ret) /* <= winxp */, "GetClassInfoA failed for %s\n", name ); + if (!ret) return; + MultiByteToWideChar( CP_ACP, 0, name, -1, nameW, sizeof(nameW)/sizeof(WCHAR) ); + ret = GetClassInfoW( 0, nameW, &wcW ); + ok( ret, "GetClassInfoW failed for %s\n", name ); + module = GetModuleHandleA( "comctl32" ); + ok( module != 0, "comctl32 not loaded\n" ); + FreeLibrary( module ); + module = GetModuleHandleA( "comctl32" ); + ok( !module, "comctl32 still loaded\n" ); + hwnd = CreateWindowA( name, "test", WS_OVERLAPPEDWINDOW, 0, 0, 10, 10, NULL, NULL, NULL, 0 ); + ok( hwnd != 0, "failed to create window for %s\n", name ); + module = GetModuleHandleA( "comctl32" ); + ok( module != 0, "comctl32 not loaded\n" ); +} + +/* verify that comctl32 classes are automatically loaded by user32 */ +static void test_comctl32_classes(void) +{ + char path_name[MAX_PATH]; + PROCESS_INFORMATION info; + STARTUPINFOA startup; + char **argv; + int i; + + static const char *classes[] = + { + ANIMATE_CLASSA, + WC_COMBOBOXEXA, + DATETIMEPICK_CLASSA, + WC_HEADERA, + HOTKEY_CLASSA, + WC_IPADDRESSA, + WC_LISTVIEWA, + MONTHCAL_CLASSA, + WC_NATIVEFONTCTLA, + WC_PAGESCROLLERA, + PROGRESS_CLASSA, + REBARCLASSNAMEA, + STATUSCLASSNAMEA, + WC_TABCONTROLA, + TOOLBARCLASSNAMEA, + TOOLTIPS_CLASSA, + TRACKBAR_CLASSA, + WC_TREEVIEWA, + UPDOWN_CLASSA + }; + + winetest_get_mainargs( &argv ); + for (i = 0; i < sizeof(classes) / sizeof(classes[0]); i++) + { + memset( &startup, 0, sizeof(startup) ); + startup.cb = sizeof( startup ); + sprintf( path_name, "%s class %s", argv[0], classes[i] ); + ok( CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info ), + "CreateProcess failed.\n" ); + winetest_wait_child_process( info.hProcess ); + CloseHandle( info.hProcess ); + CloseHandle( info.hThread ); + } +} + START_TEST(class) { + char **argv; HANDLE hInstance = GetModuleHandleA( NULL ); + int argc = winetest_get_mainargs( &argv ); + + if (argc >= 3) + { + test_comctl32_class( argv[2] ); + return; + } test_GetClassInfo(); test_extra_values(); @@ -1048,6 +1128,7 @@ START_TEST(class) test_styles(); test_builtinproc(); test_icons(); + test_comctl32_classes(); /* this test unregisters the Button class so it should be executed at the end */ test_instances();