Author: jimtabor Date: Wed Apr 5 06:34:10 2006 New Revision: 21455
URL: http://svn.reactos.ru/svn/reactos?rev=21455&view=rev Log: Update Wine User32 test to Apr 4 2006 cvs.
Added: trunk/reactos/regtests/winetests/user32/monitor.c (with props) Modified: trunk/reactos/regtests/winetests/user32/class.c trunk/reactos/regtests/winetests/user32/clipboard.c (contents, props changed) trunk/reactos/regtests/winetests/user32/dce.c (contents, props changed) trunk/reactos/regtests/winetests/user32/dde.c (contents, props changed) trunk/reactos/regtests/winetests/user32/dialog.c (props changed) trunk/reactos/regtests/winetests/user32/edit.c (contents, props changed) trunk/reactos/regtests/winetests/user32/input.c (props changed) trunk/reactos/regtests/winetests/user32/listbox.c (contents, props changed) trunk/reactos/regtests/winetests/user32/menu.c (contents, props changed) trunk/reactos/regtests/winetests/user32/msg.c (contents, props changed) trunk/reactos/regtests/winetests/user32/resource.c (contents, props changed) trunk/reactos/regtests/winetests/user32/resource.rc (props changed) trunk/reactos/regtests/winetests/user32/sysparams.c (contents, props changed) trunk/reactos/regtests/winetests/user32/testlist.c (contents, props changed) trunk/reactos/regtests/winetests/user32/text.c (contents, props changed) trunk/reactos/regtests/winetests/user32/user32.rbuild (contents, props changed) trunk/reactos/regtests/winetests/user32/win.c (contents, props changed) trunk/reactos/regtests/winetests/user32/winstation.c (contents, props changed) trunk/reactos/regtests/winetests/user32/wsprintf.c (props changed)
Modified: trunk/reactos/regtests/winetests/user32/class.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/cl... ============================================================================== --- trunk/reactos/regtests/winetests/user32/class.c (original) +++ trunk/reactos/regtests/winetests/user32/class.c Wed Apr 5 06:34:10 2006 @@ -248,12 +248,12 @@ wc.hInstance, info_inst, name ); hwnd = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, inst, 0 ); ok( hwnd != NULL, "Couldn't create window for class %s inst %p\n", name, inst ); - ok( (HINSTANCE)GetClassLongA( hwnd, GCL_HMODULE ) == gcl_inst, + ok( (HINSTANCE)GetClassLongPtrA( hwnd, GCLP_HMODULE ) == gcl_inst, "Wrong GCL instance %p/%p for class %s\n", - (HINSTANCE)GetClassLongA( hwnd, GCL_HMODULE ), gcl_inst, name ); - ok( (HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ) == inst, + (HINSTANCE)GetClassLongPtrA( hwnd, GCLP_HMODULE ), gcl_inst, name ); + ok( (HINSTANCE)GetWindowLongPtrA( hwnd, GWLP_HINSTANCE ) == inst, "Wrong GWL instance %p/%p for window %s\n", - (HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), inst, name ); + (HINSTANCE)GetWindowLongPtrA( hwnd, GWLP_HINSTANCE ), inst, name ); ok(!UnregisterClassA(name, inst), "UnregisterClassA should fail while exists a class window\n"); ok(GetLastError() == ERROR_CLASS_HAS_WINDOWS, "GetLastError() should be set to ERROR_CLASS_HAS_WINDOWS not %ld\n", GetLastError()); DestroyWindow(hwnd); @@ -363,7 +363,7 @@ ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
/* changing the instance doesn't make it global */ - SetClassLongA( hwnd, GCL_HMODULE, 0 ); + SetClassLongPtrA( hwnd, GCLP_HMODULE, 0 ); ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); check_class( kernel32, name, "kernel32" ); check_instance( name, kernel32, kernel32, kernel32 ); @@ -372,7 +372,7 @@ ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
/* GetClassInfo with instance 0 finds user32 instance */ - SetClassLongA( hwnd, GCL_HMODULE, (LONG)user32 ); + SetClassLongPtrA( hwnd, GCLP_HMODULE, (LONG_PTR)user32 ); ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); check_class( kernel32, name, "kernel32" ); check_class( user32, name, "main_module" ); @@ -385,7 +385,7 @@ check_thread_instance( name, 0, 0, kernel32 ); ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
- SetClassLongA( hwnd, GCL_HMODULE, 0x12345678 ); + SetClassLongPtrA( hwnd, GCLP_HMODULE, 0x12345678 ); ok( RegisterClassA( &cls ), "Failed to register local class for kernel32\n" ); check_class( kernel32, name, "kernel32" ); check_class( (HINSTANCE)0x12345678, name, "main_module" ); @@ -401,24 +401,24 @@ cls.style = 3; ok( RegisterClassA( &cls ), "Failed to register local class for deadbeef\n" ); hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 ); - ok( (HINSTANCE)GetClassLong( hwnd2, GCL_HMODULE ) == (HINSTANCE)0xdeadbeef, + ok( (HINSTANCE)GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == (HINSTANCE)0xdeadbeef, "Didn't get deadbeef class for null instance\n" ); DestroyWindow( hwnd2 ); ok( UnregisterClassA( name, (HINSTANCE)0xdeadbeef ), "Unregister failed for deadbeef\n" );
hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 ); - ok( (HINSTANCE)GetClassLong( hwnd2, GCL_HMODULE ) == kernel32, + ok( (HINSTANCE)GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == kernel32, "Didn't get kernel32 class for null instance\n" ); DestroyWindow( hwnd2 );
ok( UnregisterClassA( name, kernel32 ), "Unregister failed for kernel32\n" );
hwnd2 = CreateWindowExA( 0, name, "test_window", 0, 0, 0, 0, 0, 0, 0, NULL, 0 ); - ok( GetClassLong( hwnd2, GCL_HMODULE ) == 0x12345678, + ok( GetClassLongPtrA( hwnd2, GCLP_HMODULE ) == 0x12345678, "Didn't get 12345678 class for null instance\n" ); DestroyWindow( hwnd2 );
- SetClassLongA( hwnd, GCL_HMODULE, (LONG)main_module ); + SetClassLongPtrA( hwnd, GCLP_HMODULE, (LONG_PTR)main_module ); DestroyWindow( hwnd );
/* null handle means the same thing as main module */ @@ -476,7 +476,7 @@ check_thread_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, main_module );
/* changing the instance for global class doesn't make much difference */ - SetClassLongA( hwnd, GCL_HMODULE, 0xdeadbeef ); + SetClassLongPtrA( hwnd, GCLP_HMODULE, 0xdeadbeef ); check_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef ); check_instance( name, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef ); check_thread_instance( name, main_module, main_module, (HINSTANCE)0xdeadbeef ); @@ -542,7 +542,7 @@ check_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 ); check_thread_instance( "EDIT", (HINSTANCE)0xdeadbeef, (HINSTANCE)0xdeadbeef, user32 ); hwnd = CreateWindowExA( 0, "EDIT", "test", 0, 0, 0, 0, 0, 0, 0, main_module, 0 ); - SetClassLongA( hwnd, GCL_HMODULE, 0xdeadbeef ); + SetClassLongPtrA( hwnd, GCLP_HMODULE, 0xdeadbeef ); check_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef ); check_thread_instance( "EDIT", (HINSTANCE)0x12345678, (HINSTANCE)0x12345678, (HINSTANCE)0xdeadbeef ); }
Modified: trunk/reactos/regtests/winetests/user32/clipboard.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/cl... ============================================================================== --- trunk/reactos/regtests/winetests/user32/clipboard.c (original) +++ trunk/reactos/regtests/winetests/user32/clipboard.c Wed Apr 5 06:34:10 2006 @@ -30,8 +30,8 @@ { \ if (!is_win9x) \ ok(GetLastError() == expected_error, \ - "Last error should be set to %ld, not %ld\n", \ - (DWORD) expected_error, (DWORD) GetLastError()); \ + "Last error should be set to %d, not %ld\n", \ + expected_error, GetLastError()); \ } while (0)
static void test_ClipboardOwner(void)
Propchange: trunk/reactos/regtests/winetests/user32/clipboard.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/dce.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/dc... ============================================================================== --- trunk/reactos/regtests/winetests/user32/dce.c (original) +++ trunk/reactos/regtests/winetests/user32/dce.c Wed Apr 5 06:34:10 2006 @@ -33,7 +33,9 @@
#include "wine/test.h"
-#define DCX_USESTYLE 0x00010000 +#ifndef DCX_USESTYLE +#define DCX_USESTYLE 0x00010000 +#endif
static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2;
Propchange: trunk/reactos/regtests/winetests/user32/dce.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/dde.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/dd... ============================================================================== --- trunk/reactos/regtests/winetests/user32/dde.c (original) +++ trunk/reactos/regtests/winetests/user32/dde.c Wed Apr 5 06:34:10 2006 @@ -289,13 +289,11 @@
ok(DdeFreeStringHandle(dde_inst, hsz_server), "DdeFreeStringHandle error %x\n", DdeGetLastError(dde_inst));
- /* This call hangs on win2k SP4. + /* This call hangs on win2k SP4 and XP SP1. DdeUninitialize(dde_inst);*/
DestroyWindow(hwnd_client); DestroyWindow(hwnd_server); - - DdeUninitialize(dde_inst); }
static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
Propchange: trunk/reactos/regtests/winetests/user32/dde.c ------------------------------------------------------------------------------ native = class.c
Propchange: trunk/reactos/regtests/winetests/user32/dialog.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/edit.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/ed... ============================================================================== --- trunk/reactos/regtests/winetests/user32/edit.c (original) +++ trunk/reactos/regtests/winetests/user32/edit.c Wed Apr 5 06:34:10 2006 @@ -20,7 +20,6 @@
#include <assert.h> #include <windows.h> -#include <windowsx.h> #include <commctrl.h>
#include "wine/test.h" @@ -38,9 +37,11 @@
static struct edit_notify notifications;
-static char szEditTest2Name[] = "Edit Test 2 window class"; static HINSTANCE hinst; static HWND hwndET2; +static const char szEditTest2Class[] = "EditTest2Class"; +static const char szEditTest3Class[] = "EditTest3Class"; +static const char szEditTextPositionClass[] = "EditTextPositionWindowClass";
static HWND create_editcontrol (DWORD style, DWORD exstyle) { @@ -48,14 +49,57 @@
handle = CreateWindowEx(exstyle, "EDIT", - NULL, - ES_AUTOHSCROLL | ES_AUTOVSCROLL | style, + "Test Text", + style, 10, 10, 300, 300, - NULL, NULL, NULL, NULL); + NULL, NULL, hinst, NULL); assert (handle); if (winetest_interactive) ShowWindow (handle, SW_SHOW); return handle; +} + +static HWND create_child_editcontrol (DWORD style, DWORD exstyle) +{ + HWND parentWnd; + HWND editWnd; + RECT rect; + + rect.left = 0; + rect.top = 0; + rect.right = 300; + rect.bottom = 300; + assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE)); + + parentWnd = CreateWindowEx(0, + szEditTextPositionClass, + "Edit Test", + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, + rect.right - rect.left, rect.bottom - rect.top, + NULL, NULL, hinst, NULL); + assert(parentWnd); + + editWnd = CreateWindowEx(exstyle, + "EDIT", + "Test Text", + WS_CHILD | style, + 0, 0, 300, 300, + parentWnd, NULL, hinst, NULL); + assert(editWnd); + if (winetest_interactive) + ShowWindow (parentWnd, SW_SHOW); + return editWnd; +} + +static void destroy_child_editcontrol (HWND hwndEdit) +{ + if (GetParent(hwndEdit)) + DestroyWindow(GetParent(hwndEdit)); + else { + trace("Edit control has no parent!\n"); + DestroyWindow(hwndEdit); + } }
static LONG get_edit_style (HWND hwnd) @@ -87,30 +131,29 @@
GetWindowRect(Wnd, &WindowRect); GetClientRect(Wnd, &ClientRect); - SetWindowPos(Wnd, NULL, WindowRect.left, WindowRect.top, + SetWindowPos(Wnd, NULL, 0, 0, WindowRect.right - WindowRect.left, - Height + (WindowRect.bottom - WindowRect.top) - (ClientRect.bottom - ClientRect.top), - SWP_NOMOVE | SWP_NOZORDER); -} - -#define edit_pos_ok(exp, got, txt) \ - ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got); - -#define edit_todo_pos_ok(exp, got, txt, todo) \ - if (todo) todo_wine { edit_pos_ok(exp, got, txt); } \ - else edit_pos_ok(exp, got, txt) - -#define check_pos(hwEdit, set_height, test_top, test_height, test_left, todo_top, todo_height, todo_left) \ -do { \ - RECT format_rect; \ - int left_margin; \ - set_client_height(hwEdit, set_height); \ - SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \ - left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \ - edit_todo_pos_ok(test_top, format_rect.top, vertical position, todo_top); \ - edit_todo_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height, todo_height); \ - edit_todo_pos_ok(test_left, format_rect.left - left_margin, left, todo_left); \ -} while(0) + Height + (WindowRect.bottom - WindowRect.top) - + (ClientRect.bottom - ClientRect.top), + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + + /* Workaround for a bug in Windows' edit control + (multi-line mode) */ + GetWindowRect(Wnd, &WindowRect); + SetWindowPos(Wnd, NULL, 0, 0, + WindowRect.right - WindowRect.left + 1, + WindowRect.bottom - WindowRect.top + 1, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + SetWindowPos(Wnd, NULL, 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER); + + GetClientRect(Wnd, &ClientRect); + ok(ClientRect.bottom - ClientRect.top == Height, + "The client height should be %ld, but is %ld\n", + (long)Height, (long)(ClientRect.bottom - ClientRect.top)); +}
static void test_edit_control_1(void) { @@ -118,14 +161,11 @@ MSG msMessage; int i; LONG r; - HFONT Font, OldFont; - HDC Dc; - TEXTMETRIC Metrics;
msMessage.message = WM_KEYDOWN;
trace("EDIT: Single line\n"); - hwEdit = create_editcontrol(0, 0); + hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); r = get_edit_style(hwEdit); ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL), "Wrong style expected 0xc0 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -138,7 +178,7 @@ DestroyWindow (hwEdit);
trace("EDIT: Single line want returns\n"); - hwEdit = create_editcontrol(ES_WANTRETURN, 0); + hwEdit = create_editcontrol(ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); r = get_edit_style(hwEdit); ok(r == (ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN), "Wrong style expected 0x10c0 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -151,7 +191,7 @@ DestroyWindow (hwEdit);
trace("EDIT: Multiline line\n"); - hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL, 0); + hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); r = get_edit_style(hwEdit); ok(r == (ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0xc4 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -164,7 +204,7 @@ DestroyWindow (hwEdit);
trace("EDIT: Multi line want returns\n"); - hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN, 0); + hwEdit = create_editcontrol(ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); r = get_edit_style(hwEdit); ok(r == (ES_WANTRETURN | ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE), "Wrong style expected 0x10c4 got: 0x%lx\n", r); for (i=0;i<65535;i++) @@ -175,260 +215,6 @@ "Expected DLGC_WANTCHARS | DLGC_HASSETSEL | DLGC_WANTALLKEYS | DLGC_WANTARROWS got %lx\n", r); } DestroyWindow (hwEdit); - - /* Get a stock font for which we can determine the metrics */ - Font = GetStockObject(SYSTEM_FONT); - assert(NULL != Font); - Dc = GetDC(NULL); - assert(NULL != Dc); - OldFont = SelectObject(Dc, Font); - assert(NULL != OldFont); - if (! GetTextMetrics(Dc, &Metrics)) - { - assert(FALSE); - } - SelectObject(Dc, OldFont); - ReleaseDC(NULL, Dc); - - trace("EDIT: Text position\n"); - hwEdit = create_editcontrol(0, 0); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, 0); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, WS_EX_CLIENTEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, WS_EX_CLIENTEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP, 0); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 0, Metrics.tmHeight , 0, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, 0); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 0, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 3, 0, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 2, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 2, Metrics.tmHeight , 2, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP, WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 0, Metrics.tmHeight , 0, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 0, Metrics.tmHeight , 0, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 0, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 3, 0, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 2, Metrics.tmHeight , 2, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 2, Metrics.tmHeight , 2, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, ES_MULTILINE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_CLIENTEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_CLIENTEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 1, 1, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 1, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(0, ES_MULTILINE | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); - - hwEdit = create_editcontrol(WS_BORDER, ES_MULTILINE | WS_EX_CLIENTEDGE | WS_EX_WINDOWEDGE); - SendMessage(hwEdit, WM_SETFONT, (WPARAM) Font, (LPARAM) FALSE); - check_pos(hwEdit, Metrics.tmHeight - 1, 0, Metrics.tmHeight - 1, 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight , 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 1, 0, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 2, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 4, 1, Metrics.tmHeight , 1, 0, 0, 0); - check_pos(hwEdit, Metrics.tmHeight + 10, 1, Metrics.tmHeight , 1, 0, 0, 0); - DestroyWindow(hwEdit); }
/* WM_SETTEXT is implemented by selecting all text, and then replacing the @@ -443,7 +229,7 @@ char szLocalString[MAXLEN];
/* Create main and edit windows. */ - hwndMain = CreateWindow(szEditTest2Name, "ET2", WS_OVERLAPPEDWINDOW, + hwndMain = CreateWindow(szEditTest2Class, "ET2", WS_OVERLAPPEDWINDOW, 0, 0, 200, 200, NULL, NULL, hinst, NULL); assert(hwndMain); if (winetest_interactive) @@ -491,27 +277,11 @@ static LRESULT CALLBACK ET2_WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { - HANDLE_MSG(hwnd, WM_COMMAND, ET2_OnCommand); + case WM_COMMAND: + ET2_OnCommand(hwnd, LOWORD(wParam), (HWND)lParam, HIWORD(wParam)); + break; } return DefWindowProc(hwnd, iMsg, wParam, lParam); -} - -static BOOL RegisterWindowClasses (void) -{ - WNDCLASSA cls; - cls.style = 0; - cls.lpfnWndProc = ET2_WndProc; - cls.cbClsExtra = 0; - cls.cbWndExtra = 0; - cls.hInstance = hinst; - cls.hIcon = NULL; - cls.hCursor = LoadCursorA (NULL, IDC_ARROW); - cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); - cls.lpszMenuName = NULL; - cls.lpszClassName = szEditTest2Name; - if (!RegisterClassA (&cls)) return FALSE; - - return TRUE; }
static void zero_notify(void) @@ -555,7 +325,6 @@ */ static void test_edit_control_3(void) { - WNDCLASSA cls; HWND hWnd; HWND hParent; int len; @@ -564,21 +333,8 @@
trace("EDIT: Test notifications\n");
- cls.style = 0; - cls.lpfnWndProc = edit3_wnd_procA; - cls.cbClsExtra = 0; - cls.cbWndExtra = 0; - cls.hInstance = GetModuleHandleA(0); - cls.hIcon = 0; - cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW); - cls.hbrBackground = GetStockObject(WHITE_BRUSH); - cls.lpszMenuName = NULL; - cls.lpszClassName = "ParentWindowClass"; - - assert(RegisterClassA(&cls)); - hParent = CreateWindowExA(0, - "ParentWindowClass", + szEditTest3Class, NULL, 0, CW_USEDEFAULT, CW_USEDEFAULT, 10, 10, @@ -807,7 +563,7 @@ int i;
trace("EDIT: Test EM_CHARFROMPOS and EM_POSFROMCHAR\n"); - hwEdit = create_editcontrol(0, 0); + hwEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa"); lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0)); hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0)); @@ -825,7 +581,7 @@ ok(-1 == ret, "expected -1 got %d\n", ret); DestroyWindow(hwEdit);
- hwEdit = create_editcontrol(ES_RIGHT, 0); + hwEdit = create_editcontrol(ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa"); lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0)); hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0)); @@ -843,7 +599,7 @@ ok(-1 == ret, "expected -1 got %d\n", ret); DestroyWindow(hwEdit);
- hwEdit = create_editcontrol(ES_CENTER, 0); + hwEdit = create_editcontrol(ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa"); lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0)); hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0)); @@ -861,7 +617,7 @@ ok(-1 == ret, "expected -1 got %d\n", ret); DestroyWindow(hwEdit);
- hwEdit = create_editcontrol(ES_MULTILINE, 0); + hwEdit = create_editcontrol(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa"); lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0)); hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0)); @@ -879,7 +635,7 @@ ok(-1 == ret, "expected -1 got %d\n", ret); DestroyWindow(hwEdit);
- hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT, 0); + hwEdit = create_editcontrol(ES_MULTILINE | ES_RIGHT | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa"); lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0)); hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0)); @@ -897,7 +653,7 @@ ok(-1 == ret, "expected -1 got %d\n", ret); DestroyWindow(hwEdit);
- hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER, 0); + hwEdit = create_editcontrol(ES_MULTILINE | ES_CENTER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); SendMessage(hwEdit, WM_SETTEXT, 0, (LPARAM) "aa"); lo = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 0, 0)); hi = LOWORD(SendMessage(hwEdit, EM_POSFROMCHAR, 1, 0)); @@ -916,6 +672,40 @@ DestroyWindow(hwEdit); }
+/* Test if creating edit control without ES_AUTOHSCROLL and ES_AUTOVSCROLL + * truncates text that doesn't fit. + */ +static void test_edit_control_5(void) +{ + static const char *str = "test\r\ntest"; + HWND hWnd; + int len; + + hWnd = CreateWindowEx(0, + "EDIT", + str, + 0, + 10, 10, 1, 1, + NULL, NULL, NULL, NULL); + assert(hWnd); + + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(lstrlenA(str) == len, "text shouldn't have been truncated\n"); + DestroyWindow(hWnd); + + hWnd = CreateWindowEx(0, + "EDIT", + str, + ES_MULTILINE, + 10, 10, 1, 1, + NULL, NULL, NULL, NULL); + assert(hWnd); + + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(lstrlenA(str) == len, "text shouldn't have been truncated\n"); + DestroyWindow(hWnd); +} + static void test_margins(void) { HWND hwEdit; @@ -923,7 +713,7 @@ INT old_left_margin, old_right_margin; DWORD old_margins, new_margins;
- hwEdit = create_editcontrol(WS_BORDER, 0); + hwEdit = create_editcontrol(WS_BORDER | ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0);
old_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); old_left_margin = LOWORD(old_margins); @@ -970,19 +760,314 @@ ok(new_rect.right == old_rect.right, "The right border of the rectangle has changed\n"); ok(new_rect.top == old_rect.top, "The top border of the rectangle has changed\n"); ok(new_rect.bottom == old_rect.bottom, "The bottom border of the rectangle has changed\n"); - + DestroyWindow (hwEdit); }
+static INT CALLBACK find_font_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) +{ + return 0; +} + +static void test_margins_font_change(void) +{ + HWND hwEdit; + DWORD margins, font_margins; + LOGFONT lf; + HFONT hfont, hfont2; + HDC hdc = GetDC(0); + + if(EnumFontFamiliesA(hdc, "Arial", find_font_proc, 0)) + { + trace("Arial not found - skipping font change margin tests\n"); + ReleaseDC(0, hdc); + return; + } + ReleaseDC(0, hdc); + + hwEdit = create_child_editcontrol(0, 0); + + SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE); + + memset(&lf, 0, sizeof(lf)); + strcpy(lf.lfFaceName, "Arial"); + lf.lfHeight = 16; + lf.lfCharSet = DEFAULT_CHARSET; + hfont = CreateFontIndirectA(&lf); + lf.lfHeight = 30; + hfont2 = CreateFontIndirectA(&lf); + + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); + font_margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(font_margins) != 0, "got %d\n", LOWORD(font_margins)); + ok(HIWORD(font_margins) != 0, "got %d\n", HIWORD(font_margins)); + + /* With 'small' edit controls, test that the margin doesn't get set */ + SetWindowPos(hwEdit, NULL, 10, 10, 16, 100, SWP_NOZORDER | SWP_NOACTIVATE); + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins)); + + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins)); + + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); + + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO)); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); + + /* Above a certain size threshold then the margin is updated */ + SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE); + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); + + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); + + SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO)); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) == LOWORD(font_margins), "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); + SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0); + margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); + ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins)); + ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins)); + + SendMessageA(hwEdit, WM_SETFONT, 0, 0); + + DeleteObject(hfont2); + DeleteObject(hfont); + destroy_child_editcontrol(hwEdit); + +} + +#define edit_pos_ok(exp, got, txt) \ + ok(exp == got, "wrong " #txt " expected %d got %ld\n", exp, got); + +#define check_pos(hwEdit, set_height, test_top, test_height, test_left) \ +do { \ + RECT format_rect; \ + int left_margin; \ + set_client_height(hwEdit, set_height); \ + SendMessage(hwEdit, EM_GETRECT, 0, (LPARAM) &format_rect); \ + left_margin = LOWORD(SendMessage(hwEdit, EM_GETMARGINS, 0, 0)); \ + edit_pos_ok(test_top, format_rect.top, vertical position); \ + edit_pos_ok((int)test_height, format_rect.bottom - format_rect.top, height); \ + edit_pos_ok(test_left, format_rect.left - left_margin, left); \ +} while(0) + +void test_text_position_style(DWORD style) +{ + HWND hwEdit; + HFONT font, oldFont; + HDC dc; + TEXTMETRIC metrics; + INT b, bm, b2, b3; + BOOL single_line = !(style & ES_MULTILINE); + + b = GetSystemMetrics(SM_CYBORDER) + 1; + b2 = 2 * b; + b3 = 3 * b; + bm = b2 - 1; + + /* Get a stock font for which we can determine the metrics */ + assert(font = GetStockObject(SYSTEM_FONT)); + assert(dc = GetDC(NULL)); + oldFont = SelectObject(dc, font); + assert(GetTextMetrics(dc, &metrics)); + SelectObject(dc, oldFont); + ReleaseDC(NULL, dc); + + /* Windows' edit control has some bugs in multi-line mode: + * - Sometimes the format rectangle doesn't get updated + * (see workaround in set_client_height()) + * - If the height of the control is smaller than the height of a text + * line, the format rectangle is still as high as a text line + * (higher than the client rectangle) and the caret is not shown + */ + + /* Edit controls that are in a parent window */ + + hwEdit = create_child_editcontrol(style | WS_VISIBLE, 0); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0); + check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0); + check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0); + destroy_child_editcontrol(hwEdit); + + hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, 0); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b); + destroy_child_editcontrol(hwEdit); + + hwEdit = create_child_editcontrol(style | WS_VISIBLE, WS_EX_CLIENTEDGE); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1); + destroy_child_editcontrol(hwEdit); + + hwEdit = create_child_editcontrol(style | WS_BORDER | WS_VISIBLE, WS_EX_CLIENTEDGE); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1); + destroy_child_editcontrol(hwEdit); + + + /* Edit controls that are popup windows */ + + hwEdit = create_editcontrol(style | WS_POPUP, 0); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 0); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 0); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 0); + check_pos(hwEdit, metrics.tmHeight + 2, 0, metrics.tmHeight , 0); + check_pos(hwEdit, metrics.tmHeight + 10, 0, metrics.tmHeight , 0); + DestroyWindow(hwEdit); + + hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, 0); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, b); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + bm, 0, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + b2, b, metrics.tmHeight , b); + check_pos(hwEdit, metrics.tmHeight + b3, b, metrics.tmHeight , b); + DestroyWindow(hwEdit); + + hwEdit = create_editcontrol(style | WS_POPUP, WS_EX_CLIENTEDGE); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1); + DestroyWindow(hwEdit); + + hwEdit = create_editcontrol(style | WS_POPUP | WS_BORDER, WS_EX_CLIENTEDGE); + SendMessage(hwEdit, WM_SETFONT, (WPARAM) font, (LPARAM) FALSE); + if (single_line) + check_pos(hwEdit, metrics.tmHeight - 1, 0, metrics.tmHeight - 1, 1); + check_pos(hwEdit, metrics.tmHeight , 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 1, 0, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 2, 1, metrics.tmHeight , 1); + check_pos(hwEdit, metrics.tmHeight + 10, 1, metrics.tmHeight , 1); + DestroyWindow(hwEdit); +} + +void test_text_position(void) +{ + trace("EDIT: Text position (Single line)\n"); + test_text_position_style(ES_AUTOHSCROLL | ES_AUTOVSCROLL); + trace("EDIT: Text position (Multi line)\n"); + test_text_position_style(ES_MULTILINE | ES_AUTOHSCROLL | ES_AUTOVSCROLL); +} + +static BOOL RegisterWindowClasses (void) +{ + WNDCLASSA test2; + WNDCLASSA test3; + WNDCLASSA text_position; + + test2.style = 0; + test2.lpfnWndProc = ET2_WndProc; + test2.cbClsExtra = 0; + test2.cbWndExtra = 0; + test2.hInstance = hinst; + test2.hIcon = NULL; + test2.hCursor = LoadCursorA (NULL, IDC_ARROW); + test2.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + test2.lpszMenuName = NULL; + test2.lpszClassName = szEditTest2Class; + if (!RegisterClassA(&test2)) return FALSE; + + test3.style = 0; + test3.lpfnWndProc = edit3_wnd_procA; + test3.cbClsExtra = 0; + test3.cbWndExtra = 0; + test3.hInstance = hinst; + test3.hIcon = 0; + test3.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW); + test3.hbrBackground = GetStockObject(WHITE_BRUSH); + test3.lpszMenuName = NULL; + test3.lpszClassName = szEditTest3Class; + if (!RegisterClassA(&test3)) return FALSE; + + text_position.style = CS_HREDRAW | CS_VREDRAW; + text_position.cbClsExtra = 0; + text_position.cbWndExtra = 0; + text_position.hInstance = hinst; + text_position.hIcon = NULL; + text_position.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW)); + text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + text_position.lpszMenuName = NULL; + text_position.lpszClassName = szEditTextPositionClass; + text_position.lpfnWndProc = DefWindowProc; + if (!RegisterClassA(&text_position)) return FALSE; + + return TRUE; +} + +static void UnregisterWindowClasses (void) +{ + UnregisterClassA(szEditTest2Class, hinst); + UnregisterClassA(szEditTest3Class, hinst); + UnregisterClassA(szEditTextPositionClass, hinst); +} + START_TEST(edit) { - hinst = GetModuleHandleA (NULL); - if (!RegisterWindowClasses()) - assert(0); + hinst = GetModuleHandleA(NULL); + assert(RegisterWindowClasses());
test_edit_control_1(); test_edit_control_2(); test_edit_control_3(); test_edit_control_4(); + test_edit_control_5(); test_margins(); -} + test_margins_font_change(); + test_text_position(); + + UnregisterWindowClasses(); +}
Propchange: trunk/reactos/regtests/winetests/user32/edit.c ------------------------------------------------------------------------------ native = class.c
Propchange: trunk/reactos/regtests/winetests/user32/input.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/listbox.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/li... ============================================================================== --- trunk/reactos/regtests/winetests/user32/listbox.c (original) +++ trunk/reactos/regtests/winetests/user32/listbox.c Wed Apr 5 06:34:10 2006 @@ -47,10 +47,14 @@ static HWND create_listbox (DWORD add_style, HWND parent) { - HWND handle=CreateWindow ("LISTBOX", "TestList", + HWND handle; + int ctl_id=0; + if (parent) + ctl_id=1; + handle=CreateWindow ("LISTBOX", "TestList", (LBS_STANDARD & ~LBS_SORT) | add_style, 0, 0, 100, 100, - parent, (HMENU)1, NULL, 0); + parent, (HMENU)ctl_id, NULL, 0);
assert (handle); SendMessage (handle, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strings[0]); @@ -135,6 +139,7 @@ HWND hLB=create_listbox (test.prop.add_style, 0); RECT second_item; int i; + int res;
listbox_query (hLB, &answer); listbox_ok (test, init, answer); @@ -175,6 +180,16 @@ HeapFree (GetProcessHeap(), 0, txt); }
+ /* Confirm the count of items, and that an invalid delete does not remove anything */ + res = SendMessage (hLB, LB_GETCOUNT, 0, 0); + ok((res==4), "Expected 4 items, got %d\n", res); + res = SendMessage (hLB, LB_DELETESTRING, -1, 0); + ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res); + res = SendMessage (hLB, LB_DELETESTRING, 4, 0); + ok((res==LB_ERR), "Expected LB_ERR items, got %d\n", res); + res = SendMessage (hLB, LB_GETCOUNT, 0, 0); + ok((res==4), "Expected 4 items, got %d\n", res); + WAIT; DestroyWindow (hLB); } @@ -212,7 +227,8 @@
trace("%p WM_DRAWITEM %08x %08lx\n", hwnd, wparam, lparam);
- ok(wparam == 0, "wrong wparam %04x\n", wparam); + ok(wparam == dis->CtlID, "got wParam=%08x instead of %08x\n", + wparam, dis->CtlID); ok(dis->CtlType == ODT_LISTBOX, "wrong CtlType %04x\n", dis->CtlType);
GetClientRect(dis->hwndItem, &rc_client); @@ -286,6 +302,131 @@
DestroyWindow(hLB); DestroyWindow(parent); +} + +#define listbox_test_query(exp, got) \ + ok(exp.selected == got.selected, "expected selected %d, got %d\n", exp.selected, got.selected); \ + ok(exp.anchor == got.anchor, "expected anchor %d, got %d\n", exp.anchor, got.anchor); \ + ok(exp.caret == got.caret, "expected caret %d, got %d\n", exp.caret, got.caret); \ + ok(exp.selcount == got.selcount, "expected selcount %d, got %d\n", exp.selcount, got.selcount); + +static void test_selection(void) +{ + static const struct listbox_stat test_nosel = { 0, LB_ERR, 0, 0 }; + static const struct listbox_stat test_1 = { 0, LB_ERR, 0, 2 }; + static const struct listbox_stat test_2 = { 0, LB_ERR, 0, 3 }; + static const struct listbox_stat test_3 = { 0, LB_ERR, 0, 4 }; + HWND hLB; + struct listbox_stat answer; + INT ret; + + trace("testing LB_SELITEMRANGE\n"); + + hLB = create_listbox(LBS_EXTENDEDSEL, 0); + assert(hLB); + + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, 2)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_1, answer); + + SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(0, 4)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_3, answer); + + SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(-5, 5)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(2, 10)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_1, answer); + + SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(4, 10)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(10, 1)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_2, answer); + + SendMessage(hLB, LB_SETSEL, FALSE, (LPARAM)-1); + listbox_query(hLB, &answer); + listbox_test_query(test_nosel, answer); + + ret = SendMessage(hLB, LB_SELITEMRANGE, TRUE, MAKELPARAM(1, -1)); + ok(ret == LB_OKAY, "LB_SELITEMRANGE returned %d instead of LB_OKAY\n", ret); + listbox_query(hLB, &answer); + listbox_test_query(test_2, answer); + + DestroyWindow(hLB); +} + +static void test_listbox_height(void) +{ + HWND hList; + int r, id; + + hList = CreateWindow( "ListBox", "list test", 0, + 1, 1, 600, 100, NULL, NULL, NULL, NULL ); + ok( hList != NULL, "failed to create listbox\n"); + + id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi"); + ok( id == 0, "item id wrong\n"); + + r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 20, 0 )); + ok( r == 0, "send message failed\n"); + + r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 ); + ok( r == 20, "height wrong\n"); + + r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0, 30 )); + ok( r == -1, "send message failed\n"); + + r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 ); + ok( r == 20, "height wrong\n"); + + r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0x100, 0 )); + ok( r == -1, "send message failed\n"); + + r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 ); + ok( r == 20, "height wrong\n"); + + r = SendMessage( hList, LB_SETITEMHEIGHT, 0, MAKELPARAM( 0xff, 0 )); + ok( r == 0, "send message failed\n"); + + r = SendMessage(hList, LB_GETITEMHEIGHT, 0, 0 ); + ok( r == 0xff, "height wrong\n"); + + DestroyWindow( hList ); }
START_TEST(listbox) @@ -360,4 +501,6 @@
check_item_height(); test_ownerdraw(); -} + test_selection(); + test_listbox_height(); +}
Propchange: trunk/reactos/regtests/winetests/user32/listbox.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/menu.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/me... ============================================================================== --- trunk/reactos/regtests/winetests/user32/menu.c (original) +++ trunk/reactos/regtests/winetests/user32/menu.c Wed Apr 5 06:34:10 2006 @@ -23,8 +23,10 @@
#include <stdlib.h> #include <stdarg.h> +#include <stdio.h> #include <assert.h> - +#define _WIN32_WINNT 0x0500 +#define WINVER 0x0500 #include "windef.h" #include "winbase.h" #include "wingdi.h" @@ -33,6 +35,9 @@ #include "wine/test.h"
static ATOM atomMenuCheckClass; + +static BOOL (WINAPI *pSetMenuInfo)(HMENU,LPCMENUINFO); +static BOOL (WINAPI *pGetMenuInfo)(HMENU,LPCMENUINFO);
static LRESULT WINAPI menu_check_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { @@ -49,11 +54,30 @@ }
/* globals to communicate between test and wndproc */ + +#define MOD_SIZE 10 +#define MOD_NRMENUS 8 + + /* menu texts with their sizes */ +static struct { + char *text; + SIZE size; /* size of text up to any \t */ + SIZE sc_size; /* size of the short-cut */ +} MOD_txtsizes[] = { + { "Pinot &Noir" }, + { "&Merlot\bF4" }, + { "Shira&z\tAlt+S" }, + { "" }, + { NULL } +}; + unsigned int MOD_maxid; -RECT MOD_rc[4]; +RECT MOD_rc[MOD_NRMENUS]; int MOD_avec, MOD_hic; int MOD_odheight; -#define MOD_SIZE 10 +SIZE MODsizes[MOD_NRMENUS]= { {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}, + {MOD_SIZE, MOD_SIZE},{MOD_SIZE, MOD_SIZE}}; +int MOD_GotDrawItemMsg = FALSE; /* wndproc used by test_menu_ownerdraw() */ static LRESULT WINAPI menu_ownerdraw_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) @@ -64,11 +88,11 @@ { MEASUREITEMSTRUCT* pmis = (MEASUREITEMSTRUCT*)lparam; if( winetest_debug) - trace("WM_MEASUREITEM received %d,%d\n", - pmis->itemWidth, pmis->itemHeight); + trace("WM_MEASUREITEM received data %lx size %dx%d\n", + pmis->itemData, pmis->itemWidth, pmis->itemHeight); MOD_odheight = pmis->itemHeight; - pmis->itemWidth = MOD_SIZE; - pmis->itemHeight = MOD_SIZE; + pmis->itemWidth = MODsizes[pmis->itemData].cx; + pmis->itemHeight = MODsizes[pmis->itemData].cy; return TRUE; } case WM_DRAWITEM: @@ -78,18 +102,41 @@ HPEN oldpen; char chrs[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; SIZE sz; + int i; pdis = (DRAWITEMSTRUCT *) lparam; if( winetest_debug) { - trace("WM_DRAWITEM received itemdata %ld item %d rc %ld,%ld-%ld,%ld \n", - pdis->itemData, + RECT rc; + GetMenuItemRect( hwnd, (HMENU)pdis->hwndItem, pdis->itemData ,&rc); + trace("WM_DRAWITEM received hwnd %p hmenu %p itemdata %ld item %d rc %ld,%ld-%ld,%ld itemrc: %ld,%ld-%ld,%ld\n", + hwnd, (HMENU)pdis->hwndItem, pdis->itemData, pdis->itemID, pdis->rcItem.left, pdis->rcItem.top, - pdis->rcItem.right,pdis->rcItem.bottom ); + pdis->rcItem.right,pdis->rcItem.bottom, + rc.left,rc.top,rc.right,rc.bottom); oldpen=SelectObject( pdis->hDC, GetStockObject( pdis->itemState & ODS_SELECTED ? WHITE_PEN :BLACK_PEN)); Rectangle( pdis->hDC, pdis->rcItem.left,pdis->rcItem.top, pdis->rcItem.right,pdis->rcItem.bottom ); SelectObject( pdis->hDC, oldpen); } + /* calculate widths of some menu texts */ + if( ! MOD_txtsizes[0].size.cx) + for(i = 0; MOD_txtsizes[i].text; i++) { + char buf[100], *p; + RECT rc={0,0,0,0}; + strcpy( buf, MOD_txtsizes[i].text); + if( ( p = strchr( buf, '\t'))) { + *p = '\0'; + DrawText( pdis->hDC, p + 1, -1, &rc, + DT_SINGLELINE|DT_CALCRECT); + MOD_txtsizes[i].sc_size.cx= rc.right - rc.left; + MOD_txtsizes[i].sc_size.cy= rc.bottom - rc.top; + } + DrawText( pdis->hDC, buf, -1, &rc, + DT_SINGLELINE|DT_CALCRECT); + MOD_txtsizes[i].size.cx= rc.right - rc.left; + MOD_txtsizes[i].size.cy= rc.bottom - rc.top; + } + if( pdis->itemData > MOD_maxid) return TRUE; /* store the rectangl */ MOD_rc[pdis->itemData] = pdis->rcItem; @@ -98,7 +145,12 @@ MOD_avec = (sz.cx + 26)/52; GetTextMetrics( pdis->hDC, &tm); MOD_hic = tm.tmHeight; - if( pdis->itemData == MOD_maxid) PostMessage(hwnd, WM_CANCELMODE, 0, 0); + MOD_GotDrawItemMsg = TRUE; + return TRUE; + } + case WM_ENTERIDLE: + { + PostMessage(hwnd, WM_CANCELMODE, 0, 0); return TRUE; }
@@ -125,7 +177,7 @@ atomMenuCheckClass = RegisterClass(&wc); }
-/* demonstrates that windows lock the menu object so that it is still valid +/* demonstrates that windows locks the menu object so that it is still valid * even after a client calls DestroyMenu on it */ static void test_menu_locked_by_window(void) { @@ -172,7 +224,7 @@ NULL, NULL, NULL, NULL); ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError()); if( !hwnd) return; - SetWindowLong( hwnd, GWL_WNDPROC, (LONG)menu_ownerdraw_wnd_proc); + SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG)menu_ownerdraw_wnd_proc); hmenu = CreatePopupMenu(); ok(hmenu != NULL, "CreateMenu failed with error %ld\n", GetLastError()); if( !hmenu) { DestroyWindow(hwnd);return;} @@ -225,7 +277,7 @@ "Height is incorrect. Got %ld expected %d\n", MOD_rc[0].bottom - MOD_rc[0].top, MOD_SIZE);
- /* test width/height of a OD menu bar as well */ + /* test width/height of an ownerdraw menu bar as well */ ret = DestroyMenu(hmenu); ok(ret, "DestroyMenu failed with error %ld\n", GetLastError()); hmenu = CreateMenu(); @@ -236,7 +288,7 @@ ret = AppendMenu( hmenu, MF_OWNERDRAW , i, 0); ok( ret, "AppendMenu failed for %d\n", i); } - SetMenu( hwnd, hmenu); + ret = SetMenu( hwnd, hmenu); UpdateWindow( hwnd); /* hack for wine to draw the window + menu */ ok(ret, "SetMenu failed with error %ld\n", GetLastError()); /* test width */ @@ -247,14 +299,1133 @@ ok( MOD_rc[0].bottom - MOD_rc[0].top == GetSystemMetrics( SM_CYMENU) - 1, "Height of owner drawn menu item is wrong. Got %ld expected %d\n", MOD_rc[0].bottom - MOD_rc[0].top, GetSystemMetrics( SM_CYMENU) - 1); + + /* clean up */ + ret = DestroyMenu(hmenu); + ok(ret, "DestroyMenu failed with error %ld\n", GetLastError()); + DestroyWindow(hwnd); +} + +/* helper for test_menu_bmp_and_string() */ +static void test_mbs_help( int ispop, int hassub, int mnuopt, + HWND hwnd, int arrowwidth, int count, HBITMAP hbmp, + SIZE bmpsize, char *text, SIZE size, SIZE sc_size) +{ + BOOL ret; + HMENU hmenu, submenu; + MENUITEMINFO mii={ sizeof( MENUITEMINFO )}; + MENUINFO mi; + RECT rc; + int hastab, expect; + int failed = 0; + + MOD_GotDrawItemMsg = FALSE; + mii.fMask = MIIM_FTYPE | MIIM_DATA | MIIM_STATE; + mii.fType = 0; + mii.fState = MF_CHECKED; + mii.dwItemData =0; + MODsizes[0] = bmpsize; + hastab = 0; + if( text ) { + char *p; + mii.fMask |= MIIM_STRING; + mii.dwTypeData = text; + if( ( p = strchr( text, '\t'))) { + hastab = *(p + 1) ? 2 : 1; + } + } + /* tabs don't make sense in menubars */ + if(hastab && !ispop) return; + if( hbmp) { + mii.fMask |= MIIM_BITMAP; + mii.hbmpItem = hbmp; + } + submenu = CreateMenu(); + ok( submenu != 0, "CreateMenu failed with error %ld\n", GetLastError()); + if( ispop) + hmenu = CreatePopupMenu(); + else + hmenu = CreateMenu(); + ok( hmenu != 0, "Create{Popup}Menu failed with error %ld\n", GetLastError()); + if( hassub) { + mii.fMask |= MIIM_SUBMENU; + mii.hSubMenu = submenu; + } + if( mnuopt) { + mi.cbSize = sizeof(mi); + mi.fMask = MIM_STYLE; + pGetMenuInfo( hmenu, &mi); + mi.dwStyle |= mnuopt == 1 ? MNS_NOCHECK : MNS_CHECKORBMP; + ret = pSetMenuInfo( hmenu, &mi); + ok( ret, "SetMenuInfo failed with error %ld\n", GetLastError()); + } + ret = InsertMenuItem( hmenu, 0, FALSE, &mii); + ok( ret, "InsertMenuItem failed with error %ld\n", GetLastError()); + failed = !ret; + if( winetest_debug) { + HDC hdc=GetDC(hwnd); + RECT rc = {100, 50, 400, 70}; + char buf[100]; + + sprintf( buf,"%d text "%s" mnuopt %d", count, text ? text: "(nil)", mnuopt); + FillRect( hdc, &rc, (HBRUSH) COLOR_WINDOW); + TextOut( hdc, 100, 50, buf, strlen( buf)); + ReleaseDC( hwnd, hdc); + } + if(ispop) + ret = TrackPopupMenu( hmenu, 0x100, 100,100, 0, hwnd, NULL); + else { + ret = SetMenu( hwnd, hmenu); + ok(ret, "SetMenu failed with error %ld\n", GetLastError()); + DrawMenuBar( hwnd); + } + ret = GetMenuItemRect( hwnd, hmenu, 0, &rc); + /* check menu width */ + if( ispop) + expect = ( text || hbmp ? + 4 + (mnuopt != 1 ? GetSystemMetrics(SM_CXMENUCHECK) : 0) + : 0) + + arrowwidth + MOD_avec + (hbmp ? bmpsize.cx + 2 : 0) + + (text && hastab ? /* TAB space */ + MOD_avec + ( hastab==2 ? sc_size.cx : 0) : 0) + + (text ? 2 + (text[0] ? size.cx :0): 0) ; + else + expect = !(text || hbmp) ? 0 : + ( hbmp ? (text ? 2:0) + bmpsize.cx : 0 ) + + (text ? 2 * MOD_avec + (text[0] ? size.cx :0): 0) ; + ok( rc.right - rc.left == expect, + "menu width wrong, got %ld expected %d\n", rc.right - rc.left, expect); + failed = failed || !(rc.right - rc.left == expect); + /* check menu height */ + if( ispop) + expect = max( ( !(text || hbmp) ? GetSystemMetrics( SM_CYMENUSIZE)/2 : 0), + max( (text ? max( 2 + size.cy, MOD_hic + 4) : 0), + (hbmp ? bmpsize.cy + 2 : 0))); + else + expect = ( !(text || hbmp) ? GetSystemMetrics( SM_CYMENUSIZE)/2 : + max( GetSystemMetrics( SM_CYMENU) - 1, (hbmp ? bmpsize.cy : 0))); + ok( rc.bottom - rc.top == expect, + "menu height wrong, got %ld expected %d (%d)\n", + rc.bottom - rc.top, expect, GetSystemMetrics( SM_CYMENU)); + failed = failed || !(rc.bottom - rc.top == expect); + if( hbmp == HBMMENU_CALLBACK && MOD_GotDrawItemMsg) { + /* check the position of the bitmap */ + /* horizontal */ + expect = ispop ? (4 + ( mnuopt ? 0 : GetSystemMetrics(SM_CXMENUCHECK))) + : 3; + ok( expect == MOD_rc[0].left, + "bitmap left is %ld expected %d\n", MOD_rc[0].left, expect); + failed = failed || !(expect == MOD_rc[0].left); + /* vertical */ + expect = (rc.bottom - rc.top - MOD_rc[0].bottom + MOD_rc[0].top) / 2; + ok( expect == MOD_rc[0].top, + "bitmap top is %ld expected %d\n", MOD_rc[0].top, expect); + failed = failed || !(expect == MOD_rc[0].top); + } + /* if there was a failure, report details */ + if( failed) { + trace("*** count %d text "%s" bitmap %p bmsize %ld,%ld textsize %ld+%ld,%ld mnuopt %d hastab %d\n", + count, text ? text: "(nil)", hbmp, bmpsize.cx, bmpsize.cy, + size.cx, size.cy, sc_size.cx, mnuopt, hastab); + trace(" check %d,%d arrow %d avechar %d\n", + GetSystemMetrics(SM_CXMENUCHECK ), + GetSystemMetrics(SM_CYMENUCHECK ),arrowwidth, MOD_avec); + if( hbmp == HBMMENU_CALLBACK) + trace( " rc %ld,%ld-%ld,%ld bmp.rc %ld,%ld-%ld,%ld\n", + rc.left, rc.top, rc.top, rc.bottom, MOD_rc[0].left, + MOD_rc[0].top,MOD_rc[0].right, MOD_rc[0].bottom); + } + /* clean up */ + ret = DestroyMenu(submenu); + ok(ret, "DestroyMenu failed with error %ld\n", GetLastError()); + ret = DestroyMenu(hmenu); + ok(ret, "DestroyMenu failed with error %ld\n", GetLastError()); +} + + +static void test_menu_bmp_and_string(void) +{ + BYTE bmfill[300]; + HBITMAP hbm_arrow; + BITMAP bm; + INT arrowwidth; + HWND hwnd; + int count, szidx, txtidx, bmpidx, hassub, mnuopt, ispop; + + if( !pGetMenuInfo) return; + + memset( bmfill, 0x55, sizeof( bmfill)); + hwnd = CreateWindowEx(0, MAKEINTATOM(atomMenuCheckClass), NULL, + WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, NULL, NULL); + hbm_arrow=LoadBitmap( 0, (CHAR*)OBM_MNARROW); + GetObject( hbm_arrow, sizeof(bm), &bm); + arrowwidth = bm.bmWidth; + + ok(hwnd != NULL, "CreateWindowEx failed with error %ld\n", GetLastError()); + if( !hwnd) return; + SetWindowLongPtr( hwnd, GWLP_WNDPROC, (LONG)menu_ownerdraw_wnd_proc); + + if( winetest_debug) + trace(" check %d,%d arrow %d avechar %d\n", + GetSystemMetrics(SM_CXMENUCHECK ), + GetSystemMetrics(SM_CYMENUCHECK ),arrowwidth, MOD_avec); + count = 0; + MOD_maxid = 0; + for( ispop=1; ispop >= 0; ispop--){ + static SIZE bmsizes[]= { + {10,10},{38,38},{1,30},{55,5}}; + for( szidx=0; szidx < sizeof( bmsizes) / sizeof( SIZE); szidx++) { + HBITMAP hbm = CreateBitmap( bmsizes[szidx].cx, bmsizes[szidx].cy,1,1,bmfill); + HBITMAP bitmaps[] = { HBMMENU_CALLBACK, hbm, NULL }; + ok( (int)hbm, "CreateBitmap failed err %ld\n", GetLastError()); + for( txtidx = 0; txtidx < sizeof(MOD_txtsizes)/sizeof(MOD_txtsizes[0]); txtidx++) { + for( hassub = 0; hassub < 2 ; hassub++) { /* add submenu item */ + for( mnuopt = 0; mnuopt < 3 ; mnuopt++){ /* test MNS_NOCHECK/MNS_CHECKORBMP */ + for( bmpidx = 0; bmpidx <sizeof(bitmaps)/sizeof(HBITMAP); bmpidx++) { + /* no need to test NULL bitmaps of several sizes */ + if( !bitmaps[bmpidx] && szidx > 0) continue; + if( !ispop && hassub) continue; + test_mbs_help( ispop, hassub, mnuopt, + hwnd, arrowwidth, ++count, + bitmaps[bmpidx], + bmsizes[szidx], + MOD_txtsizes[txtidx].text, + MOD_txtsizes[txtidx].size, + MOD_txtsizes[txtidx].sc_size); + } + } + } + } + DeleteObject( hbm); + } + } /* clean up */ DestroyWindow(hwnd); }
+static void test_menu_add_string( void ) +{ + HMENU hmenu; + MENUITEMINFO info; + BOOL rc; + + char string[0x80]; + char string2[0x80]; + + char strback[0x80]; + WCHAR strbackW[0x80]; + static const WCHAR expectedString[] = {'D', 'u', 'm', 'm', 'y', ' ', + 's', 't', 'r', 'i', 'n', 'g', 0}; + + hmenu = CreateMenu(); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_ID; + info.dwTypeData = "blah"; + info.cch = 6; + info.dwItemData = 0; + info.wID = 1; + info.fState = 0; + InsertMenuItem(hmenu, 0, TRUE, &info ); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_DATA | MIIM_ID; + info.dwTypeData = string; + info.cch = sizeof string; + string[0] = 0; + GetMenuItemInfo( hmenu, 0, TRUE, &info ); + + ok( !strcmp( string, "blah" ), "menu item name differed\n"); + + /* Test combination of ownerdraw and strings with GetMenuItemString(A/W) */ + strcpy(string, "Dummy string"); + memset(&info, 0x00, sizeof(info)); + info.cbSize= sizeof(MENUITEMINFO); + info.fMask= MIIM_FTYPE | MIIM_STRING; /* Set OwnerDraw + typeData */ + info.fType= MFT_OWNERDRAW; + info.dwTypeData= string; + rc = InsertMenuItem( hmenu, 0, TRUE, &info ); + ok (rc, "InsertMenuItem failed\n"); + + strcpy(string,"Garbage"); + ok (GetMenuString( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n"); + ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n"); + + ok (GetMenuStringW( hmenu, 0, (WCHAR *)strbackW, 99, MF_BYPOSITION), "GetMenuStringW on ownerdraw entry failed\n"); + ok (!lstrcmpW( strbackW, expectedString ), "Menu text from Unicode version incorrect\n"); + + /* Just change ftype to string and see what text is stored */ + memset(&info, 0x00, sizeof(info)); + info.cbSize= sizeof(MENUITEMINFO); + info.fMask= MIIM_FTYPE; /* Set string type */ + info.fType= MFT_STRING; + info.dwTypeData= (char *)0xdeadbeef; + rc = SetMenuItemInfo( hmenu, 0, TRUE, &info ); + ok (rc, "SetMenuItemInfo failed\n"); + + /* Did we keep the old dwTypeData? */ + ok (GetMenuString( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n"); + ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n"); + + /* Ensure change to bitmap type fails */ + memset(&info, 0x00, sizeof(info)); + info.cbSize= sizeof(MENUITEMINFO); + info.fMask= MIIM_FTYPE; /* Set as bitmap type */ + info.fType= MFT_BITMAP; + info.dwTypeData= (char *)0xdeadbee2; + rc = SetMenuItemInfo( hmenu, 0, TRUE, &info ); + ok (!rc, "SetMenuItemInfo unexpectedly worked\n"); + + /* Just change ftype back and ensure data hasn't been freed */ + info.fType= MFT_OWNERDRAW; /* Set as ownerdraw type */ + info.dwTypeData= (char *)0xdeadbee3; + rc = SetMenuItemInfo( hmenu, 0, TRUE, &info ); + ok (rc, "SetMenuItemInfo failed\n"); + + /* Did we keep the old dwTypeData? */ + ok (GetMenuString( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n"); + ok (!strcmp( strback, "Dummy string" ), "Menu text from Ansi version incorrect\n"); + + /* Just change string value (not type) */ + memset(&info, 0x00, sizeof(info)); + info.cbSize= sizeof(MENUITEMINFO); + info.fMask= MIIM_STRING; /* Set typeData */ + strcpy(string2, "string2"); + info.dwTypeData= string2; + rc = SetMenuItemInfo( hmenu, 0, TRUE, &info ); + ok (rc, "SetMenuItemInfo failed\n"); + + ok (GetMenuString( hmenu, 0, strback, 99, MF_BYPOSITION), "GetMenuString on ownerdraw entry failed\n"); + ok (!strcmp( strback, "string2" ), "Menu text from Ansi version incorrect\n"); + + /* crashes with wine 0.9.5 */ + memset(&info, 0x00, sizeof(info)); + info.cbSize= sizeof(MENUITEMINFO); + info.fMask= MIIM_FTYPE | MIIM_STRING; /* Set OwnerDraw + typeData */ + info.fType= MFT_OWNERDRAW; + rc = InsertMenuItem( hmenu, 0, TRUE, &info ); + ok (rc, "InsertMenuItem failed\n"); + ok (!GetMenuString( hmenu, 0, NULL, 0, MF_BYPOSITION), + "GetMenuString on ownerdraw entry succeeded.\n"); + ok (!GetMenuStringW( hmenu, 0, NULL, 0, MF_BYPOSITION), + "GetMenuStringW on ownerdraw entry succeeded.\n"); + + + DestroyMenu( hmenu ); +} + +/* define building blocks for the menu item info tests */ +static int strncmpW( const WCHAR *str1, const WCHAR *str2, int n ) +{ + if (n <= 0) return 0; + while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; } + return *str1 - *str2; +} + +static WCHAR *strcpyW( WCHAR *dst, const WCHAR *src ) +{ + WCHAR *p = dst; + while ((*p++ = *src++)); + return dst; +} + + +#define DMIINFF( i, e, field)\ + ok((int)((i)->field)==(int)((e)->field) || (int)((i)->field)==(0xffff & (int)((e)->field)), \ + "%s got 0x%x expected 0x%x\n", #field, (int)((i)->field), (int)((e)->field)); + +#define DUMPMIINF(s,i,e)\ +{\ + DMIINFF( i, e, fMask)\ + DMIINFF( i, e, fType)\ + DMIINFF( i, e, fState)\ + DMIINFF( i, e, wID)\ + DMIINFF( i, e, hSubMenu)\ + DMIINFF( i, e, hbmpChecked)\ + DMIINFF( i, e, hbmpUnchecked)\ + DMIINFF( i, e, dwItemData)\ + DMIINFF( i, e, dwTypeData)\ + DMIINFF( i, e, cch)\ + if( s==sizeof(MENUITEMINFOA)) DMIINFF( i, e, hbmpItem)\ +} + +/* insert menu item */ +#define TMII_INSMI( a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,\ + eret1)\ +{\ + MENUITEMINFOA info1=a1 b1,c1,d1,e1,f1,(void*)g1,(void*)h1,(void*)i1,j1,(void*)k1,l1,(void*)m1 n1;\ + HMENU hmenu = CreateMenu();\ + BOOL ret, stop = FALSE;\ + SetLastError( 0xdeadbeef);\ + if(ansi)strcpy( string, init);\ + else strcpyW( (WCHAR*)string, (WCHAR*)init);\ + if( ansi) ret = InsertMenuItemA(hmenu, 0, TRUE, &info1 );\ + else ret = InsertMenuItemW(hmenu, 0, TRUE, (MENUITEMINFOW*)&info1 );\ + if( !(eret1)) { ok( (eret1)==ret,"InsertMenuItem should have failed.\n");\ + stop = TRUE;\ + } else ok( (eret1)==ret,"InsertMenuItem failed, err %ld\n",GetLastError());\ + + +/* GetMenuItemInfo + GetMenuString */ +#define TMII_GMII( a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,\ + a3,b3,c3,d3,e3,f3,g3,h3,i3,j3,k3,l3,m3,n3,\ + expname, eret2, eret3)\ +{\ + MENUITEMINFOA info2A=a2 b2,c2,d2,e2,f2,(void*)g2,(void*)h2,(void*)i2,j2,(void*)k2,l2,(void*)m2 n2;\ + MENUITEMINFOA einfoA=a3 b3,c3,d3,e3,f3,(void*)g3,(void*)h3,(void*)i3,j3,(void*)k3,l3,(void*)m3 n3;\ + MENUITEMINFOA *info2 = &info2A;\ + MENUITEMINFOA *einfo = &einfoA;\ + MENUITEMINFOW *info2W = (MENUITEMINFOW *)&info2A;\ + if( !stop) {\ + ret = ansi ? GetMenuItemInfoA( hmenu, 0, TRUE, info2 ) :\ + GetMenuItemInfoW( hmenu, 0, TRUE, info2W );\ + if( !(eret2)) ok( (eret2)==ret,"GetMenuItemInfo should have failed.\n");\ + else { \ + ok( (eret2)==ret,"GetMenuItemInfo failed, err %ld\n",GetLastError());\ + ret = memcmp( info2, einfo, sizeof einfoA);\ + /* ok( ret==0, "Got wrong menu item info data\n");*/\ + if( ret) DUMPMIINF(info2A.cbSize, &info2A, &einfoA)\ + if( einfo->dwTypeData == string) {\ + if(ansi) ok( !strncmp( expname, info2->dwTypeData, einfo->cch ), "menu item name differed "%s"\n",\ + einfo->dwTypeData ? einfo->dwTypeData: "");\ + else ok( !strncmpW( (WCHAR*)expname, (WCHAR*)info2->dwTypeData, einfo->cch ), "menu item name differed "%s"\n",\ + einfo->dwTypeData ? einfo->dwTypeData: "");\ + ret = ansi ? GetMenuStringA( hmenu, 0, string, 80, MF_BYPOSITION) :\ + GetMenuStringW( hmenu, 0, string, 80, MF_BYPOSITION);\ + if( (eret3)){\ + ok( ret, "GetMenuString failed, err %ld\n",GetLastError());\ + }else\ + ok( !ret, "GetMenuString should have failed\n");\ + }\ + }\ + }\ +} + +#define TMII_DONE \ + RemoveMenu(hmenu, 0, TRUE );\ + DestroyMenu( hmenu );\ + DestroyMenu( submenu );\ +submenu = CreateMenu();\ +} +/* modify menu */ +#define TMII_MODM( flags, id, data, eret )\ +if( !stop) {\ + if(ansi)ret = ModifyMenuA( hmenu, 0, flags, (UINT_PTR)id, (char*)data);\ + else ret = ModifyMenuW( hmenu, 0, flags, (UINT_PTR)id, (WCHAR*)data);\ + if( !(eret)) ok( (eret)==ret,"ModifyMenuA should have failed.\n");\ + else ok( (eret)==ret,"ModifyMenuA failed, err %ld\n",GetLastError());\ +} + +/* SetMenuItemInfo */ +#define TMII_SMII( a1,b1,c1,d1,e1,f1,g1,h1,i1,j1,k1,l1,m1,n1,\ + eret1)\ +if( !stop) {\ + MENUITEMINFOA info1=a1 b1,c1,d1,e1,f1,(void*)g1,(void*)h1,(void*)i1,j1,(void*)k1,l1,(void*)m1 n1;\ + SetLastError( 0xdeadbeef);\ + if(ansi)strcpy( string, init);\ + else strcpyW( (WCHAR*)string, (WCHAR*)init);\ + if( ansi) ret = SetMenuItemInfoA(hmenu, 0, TRUE, &info1 );\ + else ret = SetMenuItemInfoW(hmenu, 0, TRUE, (MENUITEMINFOW*)&info1 );\ + if( !(eret1)) { ok( (eret1)==ret,"InsertMenuItem should have failed.\n");\ + stop = TRUE;\ + } else ok( (eret1)==ret,"InsertMenuItem failed, err %ld\n",GetLastError());\ +} + + + +#define OK 1 +#define ER 0 + + +static void test_menu_iteminfo( void ) +{ + int S=sizeof( MENUITEMINFOA); + int ansi = TRUE; + char txtA[]="wine"; + char initA[]="XYZ"; + char emptyA[]=""; + WCHAR txtW[]={'W','i','n','e',0}; + WCHAR initW[]={'X','Y','Z',0}; + WCHAR emptyW[]={0}; + void *txt, *init, *empty, *string; + HBITMAP hbm = CreateBitmap(1,1,1,1,NULL); + char stringA[0x80]; + HMENU submenu=CreateMenu(); + + do { + if( ansi) {txt=txtA;init=initA;empty=emptyA;string=stringA;} + else {txt=txtW;init=initW;empty=emptyW;string=stringA;} + trace( "%s string %p hbm %p txt %p\n", ansi ? "ANSI tests: " : "Unicode tests:", string, hbm, txt); + /* test all combinations of MFT_STRING, MFT_OWNERDRAW and MFT_BITMAP */ + /* (since MFT_STRING is zero, there are four of them) */ + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, 0, 0, 0, 0, 0, 0, txt, 0, 0, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, 0, 0, 0, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_BITMAP, -1, -1, -1, -1, -1, -1, hbm, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, hbm, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, }, + empty, OK, ER ) + TMII_DONE + /* not enough space for name*/ + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, NULL, 0, -9, }, + {, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, NULL, 4, 0, }, + empty, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 5, -9, }, + {, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 4, -9, }, + {, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 3, 0, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, NULL, 0, -9, }, + {, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 0, 0, }, + empty, OK, ER ) + TMII_DONE + /* cannot combine MIIM_TYPE with some other flags */ + TMII_INSMI( {, S, MIIM_TYPE|MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, ER) + TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + empty, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_STRING, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + empty, ER, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE|MIIM_FTYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, ER) + TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + empty, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + empty, ER, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE|MIIM_BITMAP, MFT_BITMAP, -1, -1, -1, -1, -1, -1, hbm, 6, hbm, }, ER) + TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + empty, OK, OK ) + TMII_DONE + /* but succeeds with some others */ + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE|MIIM_SUBMENU, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_STATE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE|MIIM_STATE, MFT_STRING, 0, -9, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE|MIIM_ID, MFT_STRING, -1, 888, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE|MIIM_ID, MFT_STRING, -9, 888, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING, -1, -1, -1, -1, -1, 999, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING, -9, -9, 0, -9, -9, 999, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + /* to be continued */ + /* set text with MIIM_TYPE and retrieve with MIIM_STRING */ + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, -9, }, + txt, OK, OK ) + TMII_DONE + /* set text with MIIM_TYPE and retrieve with MIIM_STRING; MFT_OWNERDRAW causes an empty string */ + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 0, -9, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 0, -9, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 80, -9, }, + init, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, 0, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, 0, -9, -9, -9, 0, -9, -9, -9, string, 80, -9, }, + init, OK, OK ) + TMII_DONE + /* contrary to MIIM_TYPE,you can set the text for an owner draw menu */ + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 4, -9, }, + txt, OK, OK ) + TMII_DONE + /* same but retrieve with MIIM_TYPE */ + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 0, -9, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 0, -9, }, + empty, OK, ER ) + TMII_DONE + + /* How is that with bitmaps? */ + TMII_INSMI( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_BITMAP|MIIM_FTYPE, 0, -9, -9, 0, -9, -9, -9, string, 80, hbm, }, + init, OK, ER ) + TMII_DONE + /* MIIM_BITMAP does not like MFT_BITMAP */ + TMII_INSMI( {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, ER) + TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + init, OK, OK ) + TMII_DONE + /* no problem with OWNERDRAWN */ + TMII_INSMI( {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 80, hbm, }, + init, OK, ER ) + TMII_DONE + /* setting MFT_BITMAP with MFT_FTYPE fails anyway */ + TMII_INSMI( {, S, MIIM_FTYPE, MFT_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, ER) + TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + empty, OK, OK ) + TMII_DONE + + /* menu with submenu */ + TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_SUBMENU, -9, -9, -9, submenu, -9, -9, -9, string, 80, -9, }, + init, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, -1, -1, -1, empty, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_SUBMENU, -9, -9, -9, submenu, -9, -9, -9, string, 80, -9, }, + init, OK, ER ) + TMII_DONE + /* menu with submenu, without MIIM_SUBMENU the submenufield is cleared */ + TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, submenu, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING|MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 0, -9, }, + empty, OK, ER ) + TMII_GMII ( {, S, MIIM_SUBMENU|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, submenu, -9, -9, -9, string, 80, -9, }, + empty, OK, ER ) + TMII_DONE + /* menu with invalid submenu */ + TMII_INSMI( {, S, MIIM_SUBMENU|MIIM_FTYPE, MFT_STRING, -1, -1, 999, -1, -1, -1, txt, 0, -1, }, ER) + TMII_GMII ( {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + {, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, + init, OK, ER ) + TMII_DONE + + TMII_INSMI( {, S, MIIM_TYPE, MFT_SEPARATOR, 0, 0, 0, 0, 0, 0, txt, 0, 0, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, 0, 0, 0, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_BITMAP|MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, hbm, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_BITMAP|MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, hbm, 0, hbm, }, + empty, OK, ER ) + TMII_DONE + /* SEPARATOR and STRING go well together */ + /* BITMAP and STRING go well together */ + TMII_INSMI( {, S, MIIM_STRING|MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, hbm, }, + txt, OK, OK ) + TMII_DONE + /* BITMAP, SEPARATOR and STRING go well together */ + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 4, hbm, }, + txt, OK, OK ) + TMII_DONE + /* last two tests, but use MIIM_TYPE to retrieve info */ + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_STRING|MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR|MFT_BITMAP, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, }, + txt, OK, OK ) + TMII_DONE + /* same three with MFT_OWNERDRAW */ + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_BITMAP|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR|MFT_BITMAP|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, hbm, 4, hbm, }, + txt, OK, OK ) + TMII_DONE + + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE|MIIM_ID, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + /* test with modifymenu: string is preserved after seting OWNERDRAW */ + TMII_INSMI( {, S, MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_MODM( MFT_OWNERDRAW, -1, 787, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_DATA, MFT_OWNERDRAW, -9, -9, 0, -9, -9, 787, string, 4, -9, }, + txt, OK, OK ) + TMII_DONE + /* same with bitmap: now the text is cleared */ + TMII_INSMI( {, S, MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_MODM( MFT_BITMAP, 545, hbm, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_BITMAP, -9, 545, 0, -9, -9, -9, string, 0, hbm, }, + empty, OK, ER ) + TMII_DONE + /* start with bitmap: now setting text clears it (though he flag is raised) */ + TMII_INSMI( {, S, MIIM_BITMAP, MFT_STRING, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_STRING, -9, 0, 0, -9, -9, -9, string, 0, hbm, }, + empty, OK, ER ) + TMII_MODM( MFT_STRING, 545, txt, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_STRING, -9, 545, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + /*repeat with text NULL */ + TMII_INSMI( {, S, MIIM_BITMAP, MFT_STRING, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_MODM( MFT_STRING, 545, NULL, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_SEPARATOR, -9, 545, 0, -9, -9, -9, string, 0, 0, }, + empty, OK, ER ) + TMII_DONE + /* repeat with text "" */ + TMII_INSMI( {, S, MIIM_BITMAP, -1 , -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_MODM( MFT_STRING, 545, empty, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_ID, MFT_STRING, -9, 545, 0, -9, -9, -9, string, 0, 0, }, + empty, OK, ER ) + TMII_DONE + /* start with bitmap: set ownerdraw */ + TMII_INSMI( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_MODM( MFT_OWNERDRAW, -1, 232, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP|MIIM_DATA, MFT_OWNERDRAW, -9, -9, 0, -9, -9, 232, string, 0, hbm, }, + empty, OK, ER ) + TMII_DONE + /* ask nothing */ + TMII_INSMI( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, 0, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, 0, -9, -9, -9, 0, -9, -9, -9, string, 80, -9, }, + init, OK, OK ) + TMII_DONE + /* some tests with small cbSize: the hbmpItem is to be ignored */ + TMII_INSMI( {, S - 4, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, NULL, 0, NULL, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S - 4, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 80, NULL, }, + init, OK, ER ) + TMII_DONE + TMII_INSMI( {, S - 4, MIIM_STRING|MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S - 4, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S - 4, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + TMII_INSMI( {, S - 4, MIIM_FTYPE|MIIM_STRING|MIIM_BITMAP, MFT_SEPARATOR|MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, txt, 6, hbm, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_SEPARATOR|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, NULL, 4, NULL, }, + txt, OK, OK ) + TMII_DONE + /* MIIM_TYPE by itself does not get/set the dwItemData for OwnerDrawn menus */ + TMII_INSMI( {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, 343, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, 343, 0, 0, 0, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, 343, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, 0, 0, 0, }, + empty, OK, ER ) + TMII_DONE + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING|MFT_OWNERDRAW, -1, -1, -1, -1, -1, 343, txt, 0, -1, }, OK) + TMII_GMII ( {, S, MIIM_TYPE|MIIM_DATA, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE|MIIM_DATA, MFT_STRING|MFT_OWNERDRAW, -9, -9, 0, -9, -9, 0, 0, 0, 0, }, + empty, OK, ER ) + TMII_DONE + /* set a string menu to ownerdraw with MIIM_TYPE */ + TMII_INSMI( {, S, MIIM_TYPE, MFT_STRING, -2, -2, -2, -2, -2, -2, txt, -2, -2, }, OK) + TMII_SMII( {, S, MIIM_TYPE, MFT_OWNERDRAW, -1, -1, -1, -1, -1, -1, -1, -1, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_OWNERDRAW, -9, -9, 0, -9, -9, -9, string, 4, -9, }, + txt, OK, OK ) + TMII_DONE + /* test with modifymenu add submenu */ + TMII_INSMI( {, S, MIIM_STRING, MFT_STRING, -1, -1, -1, -1, -1, -1, txt, 0, -1, }, OK) + TMII_MODM( MF_POPUP, submenu, txt, OK) + TMII_GMII ( {, S, MIIM_FTYPE|MIIM_STRING|MIIM_SUBMENU, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_FTYPE|MIIM_STRING|MIIM_SUBMENU, MFT_STRING, -9, -9, submenu, -9, -9, -9, string, 4, -9, }, + txt, OK, OK ) + TMII_GMII ( {, S, MIIM_TYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_TYPE, MFT_STRING, -9, -9, 0, -9, -9, -9, string, 4, 0, }, + txt, OK, OK ) + TMII_DONE + /* MFT_SEPARATOR bit is kept when the text is added */ + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_SMII( {, S, MIIM_STRING, -1, -1, -1, -1, -1, -1, -1, txt, -1, -1, }, OK) + TMII_GMII ( {, S, MIIM_STRING|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_STRING|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 4, -9, }, + txt, OK, OK ) + TMII_DONE + /* MFT_SEPARATOR bit is kept when bitmap is added */ + TMII_INSMI( {, S, MIIM_STRING|MIIM_FTYPE, MFT_STRING, -1, -1, -1, -1, -1, -1, NULL, 0, -1, }, OK) + TMII_SMII( {, S, MIIM_BITMAP, -1, -1, -1, -1, -1, -1, -1, -1, -1, hbm, }, OK) + TMII_GMII ( {, S, MIIM_BITMAP|MIIM_FTYPE, -9, -9, -9, -9, -9, -9, -9, string, 80, -9, }, + {, S, MIIM_BITMAP|MIIM_FTYPE, MFT_SEPARATOR, -9, -9, 0, -9, -9, -9, string, 80, hbm, }, + init, OK, ER ) + TMII_DONE + + } while( !(ansi = !ansi) ); + DeleteObject( hbm); +} + +/* + The following tests try to confirm the algorithm used to return the menu items + when there is a collision between a menu item and a popup menu + */ +void test_menu_search_bycommand( void ) +{ + HMENU hmenu, hmenuSub, hmenuSub2; + MENUITEMINFO info; + BOOL rc; + UINT id; + char strback[0x80]; + char strIn[0x80]; + + /* Case 1: Menu containing a menu item */ + hmenu = CreateMenu(); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + strcpy(strIn, "Case 1 MenuItem"); + info.dwTypeData = strIn; + info.wID = (UINT) 0x1234; + + rc = InsertMenuItem(hmenu, 0, TRUE, &info ); + ok (rc, "Inserting the menuitem failed\n"); + + id = GetMenuItemID(hmenu, 0); + ok (id == 0x1234, "Getting the menuitem id failed(gave %x)\n", id); + + /* Confirm the menuitem was given the id supplied (getting by position) */ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; + info.dwTypeData = strback; + info.cch = sizeof(strback); + + rc = GetMenuItemInfo(hmenu, 0, TRUE, &info); /* Get by position */ + ok (rc, "Getting the menu items info failed\n"); + ok (info.wID == 0x1234, "IDs differ for the menuitem\n"); + ok (!strcmp(info.dwTypeData, "Case 1 MenuItem"), "Returned item has wrong label\n"); + + /* Search by id - Should return the item */ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; + info.dwTypeData = strback; + info.cch = sizeof(strback); + rc = GetMenuItemInfo(hmenu, 0x1234, FALSE, &info); /* Get by ID */ + + ok (rc, "Getting the menu items info failed\n"); + ok (info.wID == 0x1234, "IDs differ for the menuitem\n"); + ok (!strcmp(info.dwTypeData, "Case 1 MenuItem"), "Returned item has wrong label\n"); + + DestroyMenu( hmenu ); + + /* Case 2: Menu containing a popup menu */ + hmenu = CreateMenu(); + hmenuSub = CreateMenu(); + + strcpy(strIn, "Case 2 SubMenu"); + rc = InsertMenu(hmenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, strIn); + ok (rc, "Inserting the popup menu into the main menu failed\n"); + + id = GetMenuItemID(hmenu, 0); + ok (id == -1, "Getting the menuitem id unexpectedly worked (gave %x)\n", id); + + /* Confirm the menuitem itself was given an id the same as the HMENU, (getting by position) */ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; + info.dwTypeData = strback; + info.cch = sizeof(strback); + info.wID = 0xdeadbeef; + + rc = GetMenuItemInfo(hmenu, 0, TRUE, &info); /* Get by position */ + ok (rc, "Getting the menu items info failed\n"); + ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the menuitem\n"); + ok (!strcmp(info.dwTypeData, "Case 2 SubMenu"), "Returned item has wrong label\n"); + + /* Search by id - returns the popup menu itself */ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; + info.dwTypeData = strback; + info.cch = sizeof(strback); + rc = GetMenuItemInfo(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); /* Get by ID */ + + ok (rc, "Getting the menu items info failed\n"); + ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the popup menu\n"); + ok (!strcmp(info.dwTypeData, "Case 2 SubMenu"), "Returned item has wrong label\n"); + + /* + Now add an item after it with the same id + */ + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + strcpy(strIn, "Case 2 MenuItem 1"); + info.dwTypeData = strIn; + info.wID = (UINT_PTR) hmenuSub; + rc = InsertMenuItem(hmenu, -1, TRUE, &info ); + ok (rc, "Inserting the menuitem failed\n"); + + /* Search by id - returns the item which follows the popup menu */ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; + info.dwTypeData = strback; + info.cch = sizeof(strback); + rc = GetMenuItemInfo(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); /* Get by ID */ + + ok (rc, "Getting the menu items info failed\n"); + ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the popup menu\n"); + ok (!strcmp(info.dwTypeData, "Case 2 MenuItem 1"), "Returned item has wrong label (%s)\n", info.dwTypeData); + + /* + Now add an item before the popup (with the same id) + */ + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + strcpy(strIn, "Case 2 MenuItem 2"); + info.dwTypeData = strIn; + info.wID = (UINT_PTR) hmenuSub; + rc = InsertMenuItem(hmenu, 0, TRUE, &info ); + ok (rc, "Inserting the menuitem failed\n"); + + /* Search by id - returns the item which precedes the popup menu */ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING; + info.dwTypeData = strback; + info.cch = sizeof(strback); + rc = GetMenuItemInfo(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); /* Get by ID */ + + ok (rc, "Getting the menu items info failed\n"); + ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for the popup menu\n"); + ok (!strcmp(info.dwTypeData, "Case 2 MenuItem 2"), "Returned item has wrong label (%s)\n", info.dwTypeData); + + DestroyMenu( hmenu ); + DestroyMenu( hmenuSub ); + + /* + Case 3: Menu containing a popup menu which in turn + contains 2 items with the same id as the popup itself + */ + + hmenu = CreateMenu(); + hmenuSub = CreateMenu(); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + info.dwTypeData = "MenuItem"; + info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/ + + rc = InsertMenu(hmenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, "Submenu"); + ok (rc, "Inserting the popup menu into the main menu failed\n"); + + rc = InsertMenuItem(hmenuSub, 0, TRUE, &info ); + ok (rc, "Inserting the sub menu menuitem failed\n"); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + info.dwTypeData = "MenuItem 2"; + info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/ + + rc = InsertMenuItem(hmenuSub, 1, TRUE, &info ); + ok (rc, "Inserting the sub menu menuitem 2 failed\n"); + + /* Prove that you can't query the id of a popup directly (By position) */ + id = GetMenuItemID(hmenu, 0); + ok (id == -1, "Getting the sub menu id should have failed because its a popup (gave %x)\n", id); + + /* Prove getting the item info via ID returns the first item (not the popup or 2nd item)*/ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_STRING | MIIM_ID; + info.dwTypeData = strback; + info.cch = sizeof(strback); + + rc = GetMenuItemInfo(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); + ok (rc, "Getting the menus info failed\n"); + ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for popup menu\n"); + ok (!strcmp(info.dwTypeData, "MenuItem"), "Returned item has wrong label (%s)\n", info.dwTypeData); + DestroyMenu( hmenu ); + DestroyMenu( hmenuSub ); + + /* + Case 4: Menu containing 2 popup menus, the second + contains 2 items with the same id as the first popup menu + */ + hmenu = CreateMenu(); + hmenuSub = CreateMenu(); + hmenuSub2 = CreateMenu(); + + rc = InsertMenu(hmenu, 0, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub, "Submenu"); + ok (rc, "Inserting the popup menu into the main menu failed\n"); + + rc = InsertMenu(hmenu, 1, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT_PTR)hmenuSub2, "Submenu2"); + ok (rc, "Inserting the popup menu into the main menu failed\n"); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + info.dwTypeData = "MenuItem"; + info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/ + + rc = InsertMenuItem(hmenuSub2, 0, TRUE, &info ); + ok (rc, "Inserting the sub menu menuitem failed\n"); + + memset( &info, 0, sizeof info ); + info.cbSize = sizeof info; + info.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_ID; + info.fType = MFT_STRING; + info.dwTypeData = "MenuItem 2"; + info.wID = (UINT_PTR) hmenuSub; /* Enforce id collisions with the hmenu of the popup submenu*/ + + rc = InsertMenuItem(hmenuSub2, 1, TRUE, &info ); + ok (rc, "Inserting the sub menu menuitem 2 failed\n"); + + /* Prove getting the item info via ID returns the first item (not the popup or 2nd item)*/ + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_STRING | MIIM_ID; + info.dwTypeData = strback; + info.cch = sizeof(strback); + + rc = GetMenuItemInfo(hmenu, (UINT_PTR)hmenuSub, FALSE, &info); + ok (rc, "Getting the menus info failed\n"); + ok (info.wID == (UINT_PTR)hmenuSub, "IDs differ for popup menu\n"); + ok (!strcmp(info.dwTypeData, "MenuItem"), "Returned item has wrong label (%s)\n", info.dwTypeData); + + memset( &info, 0, sizeof info ); + strback[0] = 0x00; + info.cbSize = sizeof(MENUITEMINFO); + info.fMask = MIIM_STRING | MIIM_ID; + info.dwTypeData = strback; + info.cch = sizeof(strback); + + rc = GetMenuItemInfo(hmenu, (UINT_PTR)hmenuSub2, FALSE, &info); + ok (rc, "Getting the menus info failed\n"); + ok (info.wID == (UINT)hmenuSub2, "IDs differ for popup menu\n"); + ok (!strcmp(info.dwTypeData, "Submenu2"), "Returned item has wrong label (%s)\n", info.dwTypeData); +} + START_TEST(menu) { + pSetMenuInfo = + (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "SetMenuInfo" ); + pGetMenuInfo = + (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetMenuInfo" ); + register_menu_check_class();
test_menu_locked_by_window(); test_menu_ownerdraw(); -} + test_menu_add_string(); + test_menu_iteminfo(); + test_menu_search_bycommand(); + test_menu_bmp_and_string(); +}
Propchange: trunk/reactos/regtests/winetests/user32/menu.c ------------------------------------------------------------------------------ native = class.c
Added: trunk/reactos/regtests/winetests/user32/monitor.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/mo... ============================================================================== --- trunk/reactos/regtests/winetests/user32/monitor.c (added) +++ trunk/reactos/regtests/winetests/user32/monitor.c Wed Apr 5 06:34:10 2006 @@ -1,0 +1,106 @@ +/* + * Unit tests for monitor APIs + * + * Copyright 2005 Huw Davies + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#define _WIN32_WINNT 0x0500 + +#include "wine/test.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" + +static HMODULE hdll; +static BOOL (WINAPI *pEnumDisplayDevicesA)(LPCSTR,DWORD,LPDISPLAY_DEVICEA,DWORD); +static BOOL (WINAPI *pEnumDisplayMonitors)(HDC,LPRECT,MONITORENUMPROC,LPARAM); +static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO); + +static void init_function_pointers(void) +{ + hdll = GetModuleHandleA("user32.dll"); + + if(hdll) + { + pEnumDisplayDevicesA = (void*)GetProcAddress(hdll, "EnumDisplayDevicesA"); + pEnumDisplayMonitors = (void*)GetProcAddress(hdll, "EnumDisplayMonitors"); + pGetMonitorInfoA = (void*)GetProcAddress(hdll, "GetMonitorInfoA"); + } +} + +static BOOL CALLBACK monitor_enum_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, + LPARAM lparam) +{ + MONITORINFOEXA mi; + char *primary = (char *)lparam; + + mi.cbSize = sizeof(mi); + + ok(pGetMonitorInfoA(hmon, (MONITORINFO*)&mi), "GetMonitorInfo failed\n"); + if(mi.dwFlags == MONITORINFOF_PRIMARY) + strcpy(primary, mi.szDevice); + + return TRUE; +} + +static void test_enumdisplaydevices(void) +{ + DISPLAY_DEVICEA dd; + char primary_device_name[32]; + char primary_monitor_device_name[32]; + DWORD primary_num = -1, num = 0; + + dd.cb = sizeof(dd); + if(pEnumDisplayDevicesA == NULL) return; + while(1) + { + BOOL ret; + HDC dc; + ret = pEnumDisplayDevicesA(NULL, num, &dd, 0); + ok(ret || num != 0, "EnumDisplayDevices fails with num == 0\n"); + if(!ret) break; + if(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) + { + strcpy(primary_device_name, dd.DeviceName); + primary_num = num; + } + if(dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) + { + /* test creating DC */ + dc = CreateDCA(dd.DeviceName, NULL, NULL, NULL); + ok(dc != NULL, "Failed to CreateDC("%s") err=%ld\n", dd.DeviceName, GetLastError()); + DeleteDC(dc); + } + num++; + } + ok(primary_num != -1, "Didn't get the primary device\n"); + + if(pEnumDisplayMonitors && pGetMonitorInfoA) { + ok(pEnumDisplayMonitors(NULL, NULL, monitor_enum_proc, (LPARAM)primary_monitor_device_name), + "EnumDisplayMonitors failed\n"); + + ok(!strcmp(primary_monitor_device_name, primary_device_name), + "monitor device name %s, device name %s\n", primary_monitor_device_name, + primary_device_name); + } +} + + +START_TEST(monitor) +{ + init_function_pointers(); + test_enumdisplaydevices(); +}
Propchange: trunk/reactos/regtests/winetests/user32/monitor.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/msg.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/ms... ============================================================================== --- trunk/reactos/regtests/winetests/user32/msg.c (original) +++ trunk/reactos/regtests/winetests/user32/msg.c Wed Apr 5 06:34:10 2006 @@ -25,18 +25,20 @@ #include <stdio.h>
#define WINVER 0x0500 -#define _WIN32_WINNT 0x0500 /* For WM_CHANGEUISTATE */ +#define _WIN32_WINNT 0x0501 /* For WM_CHANGEUISTATE,QS_RAWINPUT */
#include "windef.h" #include "winbase.h" #include "wingdi.h" #include "winuser.h" +#include "winnls.h"
#include "wine/test.h"
+#define OBJID_QUERYCLASSNAMEIDX -12 +#define OBJID_NATIVEOM -16 + #define MDI_FIRST_CHILD_ID 2004 -#define OBJID_QUERYCLASSNAMEIDX -12 // Fixme w32api -#define OBJID_NATIVEOM -16 // ditto
/* undocumented SWP flags - from SDK 3.1 */ #define SWP_NOCLIENTSIZE 0x0800 @@ -127,6 +129,7 @@ { WM_NCCALCSIZE, sent|wparam|optional, 1 }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { 0 } }; /* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE) @@ -156,6 +159,7 @@ { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */ { 0 } };
@@ -189,6 +193,59 @@ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOCLIENTSIZE }, { WM_MOVE, sent|defwinproc|wparam, 0 }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { 0 } +}; + +/* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE| + SWP_NOZORDER|SWP_FRAMECHANGED) + * for a visible overlapped window with WS_CLIPCHILDREN style set. + */ +static const struct message WmSWP_FrameChanged_clip[] = { + { WM_WINDOWPOSCHANGING, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED }, + { WM_NCCALCSIZE, sent|wparam|parent, 1 }, + { WM_NCPAINT, sent|parent }, /* wparam != 1 */ + { WM_GETTEXT, sent|parent|defwinproc|optional }, + { WM_ERASEBKGND, sent|parent|optional }, /* FIXME: remove optional once Wine is fixed */ + { WM_NCPAINT, sent }, /* wparam != 1 */ + { WM_ERASEBKGND, sent }, + { WM_WINDOWPOSCHANGED, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { 0 } +}; +/* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE| + SWP_NOZORDER|SWP_FRAMECHANGED) + * for a visible overlapped window. + */ +static const struct message WmSWP_FrameChangedDeferErase[] = { + { WM_WINDOWPOSCHANGING, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED }, + { WM_NCCALCSIZE, sent|wparam|parent, 1 }, + { WM_WINDOWPOSCHANGED, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { WM_PAINT, sent|parent }, + { WM_NCPAINT, sent|beginpaint|parent }, /* wparam != 1 */ + { WM_GETTEXT, sent|beginpaint|parent|defwinproc|optional }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */ + { WM_ERASEBKGND, sent|beginpaint }, + { 0 } +}; + +/* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE| + SWP_NOZORDER|SWP_FRAMECHANGED) + * for a visible overlapped window without WS_CLIPCHILDREN style set. + */ +static const struct message WmSWP_FrameChanged_noclip[] = { + { WM_WINDOWPOSCHANGING, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED }, + { WM_NCCALCSIZE, sent|wparam|parent, 1 }, + { WM_NCPAINT, sent|parent }, /* wparam != 1 */ + { WM_GETTEXT, sent|parent|defwinproc|optional }, + { WM_ERASEBKGND, sent|parent|optional }, /* FIXME: remove optional once Wine is fixed */ + { WM_WINDOWPOSCHANGED, sent|wparam|parent, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_FRAMECHANGED|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { WM_PAINT, sent }, + { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */ + { WM_ERASEBKGND, sent|beginpaint }, { 0 } };
@@ -231,14 +288,49 @@ #endif { 0 } }; +/* ShowWindow(SW_SHOWMAXIMIZED) for a not visible overlapped window */ +static const struct message WmShowMaxOverlappedSeq[] = { + { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED|0x8000 }, + { WM_GETMINMAXINFO, sent|defwinproc }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, + { HCBT_ACTIVATE, hook }, + { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 }, + { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ACTIVATE, sent|wparam, 1 }, + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, + { WM_IME_NOTIFY, sent|defwinproc|optional }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ERASEBKGND, sent|optional }, + /* Win9x adds SWP_NOZORDER below */ + { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, + { WM_NCCALCSIZE, sent|optional }, + { WM_NCPAINT, sent|optional }, + { WM_ERASEBKGND, sent|optional }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { 0 } +}; /* ShowWindow(SW_HIDE) for a visible overlapped window */ static const struct message WmHideOverlappedSeq[] = { { WM_SHOWWINDOW, sent|wparam, 0 }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, - { WM_SIZE, sent }, - { WM_MOVE, sent }, + { WM_SIZE, sent|optional }, /* XP doesn't send it */ + { WM_MOVE, sent|optional }, /* XP doesn't send it */ { WM_NCACTIVATE, sent|wparam, 0 }, { WM_ACTIVATE, sent|wparam, 0 }, { WM_ACTIVATEAPP, sent|wparam, 0 }, @@ -262,6 +354,137 @@ { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, { WM_DESTROY, sent }, { WM_NCDESTROY, sent }, + { 0 } +}; +/* CreateWindow(WS_MAXIMIZE|WS_VISIBLE) for popup window */ +static const struct message WmCreateMaxPopupSeq[] = { + { HCBT_CREATEWND, hook }, + { WM_NCCREATE, sent }, + { WM_NCCALCSIZE, sent|wparam, 0 }, + { WM_CREATE, sent }, + { WM_SIZE, sent }, + { WM_MOVE, sent }, + { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent /*|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|0x8000*/ }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { WM_WINDOWPOSCHANGED, sent /*|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOREDRAW|SWP_NOZORDER|0x8000*/ }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, + { WM_SHOWWINDOW, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE }, + { HCBT_ACTIVATE, hook }, + { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_ACTIVATE, sent|wparam, 1 }, + { HCBT_SETFOCUS, hook }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_SYNCPAINT, sent|wparam|optional, 4 }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE|SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOZORDER|SWP_NOSIZE }, + { 0 } +}; +/* CreateWindow(WS_MAXIMIZE) for popup window, not initially visible */ +static const struct message WmCreateInvisibleMaxPopupSeq[] = { + { HCBT_CREATEWND, hook }, + { WM_NCCREATE, sent }, + { WM_NCCALCSIZE, sent|wparam, 0 }, + { WM_CREATE, sent }, + { WM_SIZE, sent }, + { WM_MOVE, sent }, + { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent /*|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|0x8000*/ }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { WM_WINDOWPOSCHANGED, sent /*|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOREDRAW|SWP_NOZORDER|0x8000*/ }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, + { 0 } +}; +/* ShowWindow(SW_SHOWMAXIMIZED) for a resized not visible popup window */ +static const struct message WmShowMaxPopupResizedSeq[] = { + { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { HCBT_ACTIVATE, hook }, + { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_ACTIVATE, sent|wparam, 1 }, + { HCBT_SETFOCUS, hook }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOCLIENTMOVE|SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOZORDER }, + /* WinNT4.0 sends WM_MOVE */ + { WM_MOVE, sent|defwinproc|optional }, + { WM_SIZE, sent|defwinproc }, + { 0 } +}; +/* ShowWindow(SW_SHOWMAXIMIZED) for a not visible popup window */ +static const struct message WmShowMaxPopupSeq[] = { + { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE }, + { WM_GETMINMAXINFO, sent }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_FRAMECHANGED }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { HCBT_ACTIVATE, hook }, + { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_ACTIVATE, sent|wparam, 1 }, + { HCBT_SETFOCUS, hook }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_SYNCPAINT, sent|wparam|optional, 4 }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE|SWP_SHOWWINDOW|SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER }, + { 0 } +}; +/* CreateWindow(WS_VISIBLE) for popup window */ +static const struct message WmCreatePopupSeq[] = { + { HCBT_CREATEWND, hook }, + { WM_NCCREATE, sent }, + { WM_NCCALCSIZE, sent|wparam, 0 }, + { WM_CREATE, sent }, + { WM_SIZE, sent }, + { WM_MOVE, sent }, + { WM_SHOWWINDOW, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE }, + { HCBT_ACTIVATE, hook }, + { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_ERASEBKGND, sent|optional }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_ACTIVATE, sent|wparam, 1 }, + { HCBT_SETFOCUS, hook }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_SYNCPAINT, sent|wparam|optional, 4 }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOCLIENTMOVE|SWP_NOCLIENTSIZE|SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOZORDER|SWP_NOSIZE }, + { 0 } +}; +/* ShowWindow(SW_SHOWMAXIMIZED) for a visible popup window */ +static const struct message WmShowVisMaxPopupSeq[] = { + { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE }, + { WM_GETMINMAXINFO, sent }, + { WM_GETTEXT, sent|optional }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|0x8000 }, + { WM_NCCALCSIZE, sent|wparam, TRUE }, + { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, + { WM_NCPAINT, sent|wparam|optional, 1 }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOZORDER|0x8000 }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, { 0 } }; /* CreateWindow (for a child popup window, not initially visible) */ @@ -367,6 +590,7 @@ { WM_ERASEBKGND, sent|parent|optional }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* WinXP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { 0 } }; /* ShowWindow(SW_SHOW) for a not visible child window */ @@ -460,6 +684,16 @@ { WM_NCDESTROY, sent }, { 0 } }; +/* DestroyWindow for a visible child window with invisible parent */ +static const struct message WmDestroyInvisibleChildSeq[] = { + { HCBT_DESTROYWND, hook }, + { WM_PARENTNOTIFY, sent|parent|wparam, WM_DESTROY }, + { WM_SHOWWINDOW, sent|wparam, 0 }, + { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, + { WM_DESTROY, sent }, + { WM_NCDESTROY, sent }, + { 0 } +}; /* Moving the mouse in nonclient area */ static const struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */ { WM_NCHITTEST, sent }, @@ -584,11 +818,8 @@ { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, @@ -610,13 +841,11 @@ { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, + { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_ERASEBKGND, sent }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_CTLCOLORDLG, sent|defwinproc }, @@ -625,11 +854,8 @@ { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, @@ -639,16 +865,16 @@ { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, - { WM_GETICON, sent|optional|defwinproc }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, + { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_ERASEBKGND, sent|optional }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 }, { WM_CTLCOLORDLG, sent|optional|defwinproc }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_SIZE, sent }, { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, { WM_MOVE, sent }, @@ -660,15 +886,9 @@ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { WM_GETTEXT, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { HCBT_ACTIVATE, hook }, { WM_NCACTIVATE, sent|wparam, 0 }, { WM_GETTEXT, sent|optional|defwinproc }, - { WM_GETICON, sent|optional|defwinproc }, - { WM_GETICON, sent|optional|defwinproc }, - { WM_GETICON, sent|optional|defwinproc }, { WM_GETTEXT, sent|optional|defwinproc }, { WM_ACTIVATE, sent|wparam, 0 }, { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 }, @@ -748,33 +968,22 @@ { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE }, { WM_NCACTIVATE, sent|wparam, 1 }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { WM_ACTIVATE, sent|wparam, 1 }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE }, { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, { WM_NCPAINT, sent }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { WM_ERASEBKGND, sent }, { WM_CTLCOLORDLG, sent }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { WM_NCCALCSIZE, sent|optional }, { WM_NCPAINT, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { WM_ERASEBKGND, sent|optional }, { WM_CTLCOLORDLG, sent|optional }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { WM_PAINT, sent|optional }, { WM_CTLCOLORBTN, sent }, { WM_ENTERIDLE, sent|parent|optional }, @@ -797,24 +1006,15 @@ { WM_ENTERIDLE, sent|parent|optional }, { WM_ENTERIDLE, sent|parent|optional }, { WM_ENTERIDLE, sent|parent|optional }, - { WM_GETICON, sent|parent|optional }, - { WM_GETICON, sent|parent|optional }, - { WM_GETICON, sent|parent|optional }, { WM_TIMER, sent }, { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 }, { WM_ENABLE, sent|parent|wparam, 1 }, { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE }, { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { HCBT_ACTIVATE, hook }, { WM_NCACTIVATE, sent|wparam, 0 }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { WM_ACTIVATE, sent|wparam, 0 }, { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 }, @@ -867,10 +1067,9 @@ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOREDRAW }, { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, + { WM_NCCALCSIZE,sent|wparam|optional, 1 }, /* XP */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */ { WM_GETTEXT, sent|optional }, { WM_NCCALCSIZE, sent|wparam|optional, 1 }, { 0 } @@ -888,24 +1087,25 @@ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, { WM_NCCALCSIZE, sent|wparam, 1 }, { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 }, - { WM_NCPAINT, sent|wparam, 1 }, + { WM_NCPAINT, sent }, /* wparam != 1 */ { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, { WM_ACTIVATE, sent|optional }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, { WM_MOVE, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, + { WM_NCCALCSIZE, sent|wparam|optional, 1 }, + { WM_NCPAINT, sent|optional }, /* wparam != 1 */ + { WM_ERASEBKGND, sent|optional }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, - { WM_NCCALCSIZE, sent|wparam|optional, 1 }, - { WM_NCPAINT, sent|wparam|optional, 1 }, - { WM_ERASEBKGND, sent|optional }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */ { 0 } }; /* SetMenu for Visible windows with no size change */ static const struct message WmSetMenuVisibleNoSizeChangeSeq[] = { { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, { WM_NCCALCSIZE, sent|wparam, 1 }, - { WM_NCPAINT, sent|wparam, 1 }, + { WM_NCPAINT, sent }, /* wparam != 1 */ { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, { WM_ACTIVATE, sent|optional }, @@ -918,7 +1118,7 @@ { { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, { WM_NCCALCSIZE, sent|wparam, 1 }, - { WM_NCPAINT, sent|wparam, 1 }, + { WM_NCPAINT, sent }, /* wparam != 1 */ { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, @@ -990,6 +1190,7 @@ { WM_ERASEBKGND, sent|optional }, { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam|optional, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 }, { 0 } }; /* SetScrollRange for a window with a non-client area */ @@ -1000,27 +1201,16 @@ { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 }, { WM_NCPAINT, sent|optional }, { WM_GETTEXT, sent|defwinproc|optional }, - { WM_GETICON, sent|optional|defwinproc }, - { WM_GETICON, sent|optional|defwinproc }, - { WM_GETICON, sent|optional|defwinproc }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, { WM_CTLCOLORDLG, sent|defwinproc|optional }, /* sent to a parent of the dialog */ { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|0x1000*/ }, { WM_SIZE, sent|defwinproc }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam|optional, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 }, { WM_GETTEXT, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|optional }, { 0 } }; @@ -1057,15 +1247,13 @@ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE }, { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, { WM_NCPAINT, sent|wparam, 1 }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, - { WM_GETICON, sent|optional }, { WM_GETTEXT, sent|defwinproc|optional }, { WM_ERASEBKGND, sent|optional }, - { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_NOZORDER|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, { WM_NCCALCSIZE, sent|wparam|optional, 1 }, { WM_NCPAINT, sent|wparam|optional, 1 }, { WM_ERASEBKGND, sent|optional }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { WM_SIZE, sent }, { WM_MOVE, sent }, { 0 } @@ -1096,6 +1284,21 @@ sequence[sequence_cnt].lParam = msg->lParam;
sequence_cnt++; +} + +/* try to make sure pending X events have been processed before continuing */ +static void flush_events(void) +{ + MSG msg; + int diff = 100; + DWORD time = GetTickCount() + diff; + + while (diff > 0) + { + MsgWaitForMultipleObjects( 0, NULL, FALSE, diff, QS_ALLINPUT ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + diff = time - GetTickCount(); + } }
static void flush_sequence(void) @@ -1240,8 +1443,6 @@ { WM_ACTIVATEAPP, sent|wparam, 1 }, { WM_NCACTIVATE, sent|wparam, 1 }, { WM_GETTEXT, sent|defwinproc|optional }, - { WM_GETICON, sent|defwinproc|optional }, - { WM_GETICON, sent|defwinproc|optional }, { WM_ACTIVATE, sent|wparam, 1 }, { HCBT_SETFOCUS, hook }, { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, @@ -1249,6 +1450,8 @@ { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, /* Win9x adds SWP_NOZORDER below */ { WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, + { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* XP */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, { WM_SIZE, sent }, { WM_MOVE, sent }, { 0 } @@ -1659,7 +1862,9 @@
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */ + { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* XP sends it to MDI frame */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* XP sends a duplicate */
{ 0 } }; @@ -1826,10 +2031,14 @@ { WM_SIZE, sent|defwinproc }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */ + + { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, 1 }, /* XP sends it to MDI frame */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* XP sends a duplicate */
/* in MDI frame */ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER }, @@ -1869,8 +2078,10 @@ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER|SWP_NOCLIENTMOVE }, { WM_SIZE, sent }, { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */ + { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* XP */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */ + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* XP sends a duplicate */
{ HCBT_SETFOCUS, hook }, { WM_KILLFOCUS, sent }, @@ -1997,6 +2208,7 @@ message != WM_NCHITTEST && message != WM_GETTEXT && message != WM_MDIGETACTIVE && + message != WM_GETICON && message != WM_DEVICECHANGE) { trace("mdi client: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); @@ -2043,6 +2255,7 @@ message != WM_NCPAINT && message != WM_NCHITTEST && message != WM_GETTEXT && + message != WM_GETICON && message != WM_DEVICECHANGE) { trace("mdi child: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); @@ -2107,6 +2320,7 @@ message != WM_NCPAINT && message != WM_NCHITTEST && message != WM_GETTEXT && + message != WM_GETICON && message != WM_DEVICECHANGE) { trace("mdi frame: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); @@ -2582,6 +2796,9 @@
trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
+ /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0; + switch (message) { case WM_WINDOWPOSCHANGING: @@ -2798,6 +3015,7 @@ static void test_showwindow(void) { HWND hwnd, hchild; + RECT rc;
hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL); @@ -2825,14 +3043,14 @@ /* ShowWindow(SW_SHOWNA) with child and parent invisible */ trace("calling ShowWindow( SW_SHOWNA) for invisible child with invisible parent\n"); ok( ShowWindow(hchild, SW_SHOWNA) == FALSE, "ShowWindow: window was visible\n" ); - ok_sequence(WmSHOWNAChildInvisParInvis, "ShowWindow(SW_SHOWNA) invisible child and parent", TRUE); + ok_sequence(WmSHOWNAChildInvisParInvis, "ShowWindow(SW_SHOWNA) invisible child and parent", FALSE); trace("done\n"); /* ShowWindow(SW_SHOWNA) with child visible and parent invisible */ ok( ShowWindow(hchild, SW_SHOW) != FALSE, "ShowWindow: window was invisible\n" ); flush_sequence(); trace("calling ShowWindow( SW_SHOWNA) for the visible child and invisible parent\n"); ok( ShowWindow(hchild, SW_SHOWNA) != FALSE, "ShowWindow: window was invisible\n" ); - ok_sequence(WmSHOWNAChildVisParInvis, "ShowWindow(SW_SHOWNA) visible child and invisible parent", TRUE); + ok_sequence(WmSHOWNAChildVisParInvis, "ShowWindow(SW_SHOWNA) visible child and invisible parent", FALSE); trace("done\n"); /* ShowWindow(SW_SHOWNA) with child visible and parent visible */ ShowWindow( hwnd, SW_SHOW); @@ -2855,6 +3073,89 @@ DestroyWindow(hchild); ok(!GetCapture(), "wrong capture window %p\n", GetCapture());
+ DestroyWindow(hwnd); + flush_sequence(); + + /* Popup windows */ + /* Test 1: + * 1. Create invisible maximized popup window. + * 2. Move and resize it. + * 3. Show it maximized. + */ + trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n"); + hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create popup window\n"); + ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE); + trace("done\n"); + + GetWindowRect(hwnd, &rc); + ok( rc.right-rc.left == GetSystemMetrics(SM_CXSCREEN) && + rc.bottom-rc.top == GetSystemMetrics(SM_CYSCREEN), + "Invalid maximized size before ShowWindow (%ld,%ld)-(%ld,%ld)\n", + rc.left, rc.top, rc.right, rc.bottom); + /* Reset window's size & position */ + SetWindowPos(hwnd, 0, 10, 10, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE); + flush_sequence(); + + trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible popup window\n"); + ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok_sequence(WmShowMaxPopupResizedSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE); + trace("done\n"); + + GetWindowRect(hwnd, &rc); + ok( rc.right-rc.left == GetSystemMetrics(SM_CXSCREEN) && + rc.bottom-rc.top == GetSystemMetrics(SM_CYSCREEN), + "Invalid maximized size after ShowWindow (%ld,%ld)-(%ld,%ld)\n", + rc.left, rc.top, rc.right, rc.bottom); + DestroyWindow(hwnd); + flush_sequence(); + + /* Test 2: + * 1. Create invisible maximized popup window. + * 2. Show it maximized. + */ + trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n"); + hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create popup window\n"); + ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE); + trace("done\n"); + + trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible popup window\n"); + ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok_sequence(WmShowMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE); + trace("done\n"); + DestroyWindow(hwnd); + flush_sequence(); + + /* Test 3: + * 1. Create visible maximized popup window. + */ + trace("calling CreateWindowExA( WS_MAXIMIZE ) for maximized popup window\n"); + hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create popup window\n"); + ok_sequence(WmCreateMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE); + trace("done\n"); + DestroyWindow(hwnd); + flush_sequence(); + + /* Test 4: + * 1. Create visible popup window. + * 2. Maximize it. + */ + trace("calling CreateWindowExA( WS_VISIBLE ) for popup window\n"); + hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create popup window\n"); + ok_sequence(WmCreatePopupSeq, "CreateWindow(WS_VISIBLE):popup", TRUE); + trace("done\n"); + + trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n"); + ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok_sequence(WmShowVisMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", TRUE); + trace("done\n"); DestroyWindow(hwnd); flush_sequence(); } @@ -2931,9 +3232,19 @@ ok(GetFocus() == hwnd, "window should have input focus\n"); ShowWindow(hwnd, SW_HIDE); ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped", TRUE); - + ShowWindow(hwnd, SW_SHOW); ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped", TRUE); + + ShowWindow(hwnd, SW_HIDE); + ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped", FALSE); + + ShowWindow(hwnd, SW_SHOWMAXIMIZED); + ok_sequence(WmShowMaxOverlappedSeq, "ShowWindow(SW_SHOWMAXIMIZED):overlapped", TRUE); + + ShowWindow(hwnd, SW_RESTORE); + /* FIXME: add ok_sequence() here */ + flush_sequence();
ShowWindow(hwnd, SW_SHOW); ok_sequence(WmEmptySeq, "ShowWindow(SW_SHOW):overlapped already visible", FALSE); @@ -3136,12 +3447,12 @@ ok_sequence(WmCreateChildSeq, "CreateWindow:child", FALSE);
ShowWindow( hchild, SW_SHOW ); - ok_sequence(WmShowChildInvisibleParentSeq, "ShowWindow:show child with invisible parent", TRUE); + ok_sequence(WmShowChildInvisibleParentSeq, "ShowWindow:show child with invisible parent", FALSE); ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
ShowWindow( hchild, SW_HIDE ); - ok_sequence(WmHideChildInvisibleParentSeq, "ShowWindow:hide child with invisible parent", TRUE); + ok_sequence(WmHideChildInvisibleParentSeq, "ShowWindow:hide child with invisible parent", FALSE); ok(!(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should be not set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
@@ -3155,7 +3466,11 @@ ok(!(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should not be set\n"); ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
+ SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER); + flush_sequence(); DestroyWindow(hchild); + ok_sequence(WmDestroyInvisibleChildSeq, "DestroyInvisibleChildSeq", FALSE); + DestroyWindow(hparent); flush_sequence();
@@ -3174,14 +3489,20 @@ ok (SetMenu(hwnd, 0), "SetMenu\n"); ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange", FALSE); ShowWindow(hwnd, SW_SHOW); + UpdateWindow( hwnd ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); flush_sequence(); ok (SetMenu(hwnd, 0), "SetMenu\n"); - ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange", TRUE); + ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange", FALSE); ok (SetMenu(hwnd, hmenu), "SetMenu\n"); - ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange", TRUE); - + ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange", FALSE); + + UpdateWindow( hwnd ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); ok(DrawMenuBar(hwnd), "DrawMenuBar\n"); - ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", TRUE); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", FALSE);
DestroyWindow(hwnd); flush_sequence(); @@ -3312,6 +3633,9 @@ struct message msg;
trace("button: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0;
msg.message = message; msg.flags = sent|wparam|lparam; @@ -3620,6 +3944,7 @@
static void test_paint_messages(void) { + BOOL ret; RECT rect; POINT pt; MSG msg; @@ -3632,22 +3957,82 @@
ShowWindow( hwnd, SW_SHOW ); UpdateWindow( hwnd ); - - /* try to flush pending X expose events */ - MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT ); - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_events();
check_update_rgn( hwnd, 0 ); SetRectRgn( hrgn, 10, 10, 20, 20 ); - RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE ); + ret = RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE ); + ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret); check_update_rgn( hwnd, hrgn ); SetRectRgn( hrgn2, 20, 20, 30, 30 ); - RedrawWindow( hwnd, NULL, hrgn2, RDW_INVALIDATE ); + ret = RedrawWindow( hwnd, NULL, hrgn2, RDW_INVALIDATE ); + ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret); CombineRgn( hrgn, hrgn, hrgn2, RGN_OR ); check_update_rgn( hwnd, hrgn ); /* validate everything */ + ret = RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret); + check_update_rgn( hwnd, 0 ); + + /* test empty region */ + SetRectRgn( hrgn, 10, 10, 10, 15 ); + ret = RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE ); + ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret); + check_update_rgn( hwnd, 0 ); + /* test empty rect */ + SetRect( &rect, 10, 10, 10, 15 ); + ret = RedrawWindow( hwnd, &rect, NULL, RDW_INVALIDATE ); + ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret); + check_update_rgn( hwnd, 0 ); + + /* flush pending messages */ + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + + GetClientRect( hwnd, &rect ); + SetRectRgn( hrgn, 0, 0, rect.right - rect.left, rect.bottom - rect.top ); + /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws + * all windows and sends WM_ERASEBKGND and WM_NCPAINT. + */ + trace("testing InvalidateRect(0, NULL, FALSE)\n"); + SetRectEmpty( &rect ); + ok(InvalidateRect(0, &rect, FALSE), "InvalidateRect(0, &rc, FALSE) should fail\n"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmPaint, "Paint", FALSE ); RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); check_update_rgn( hwnd, 0 ); + + /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws + * all windows and sends WM_ERASEBKGND and WM_NCPAINT. + */ + trace("testing ValidateRect(0, NULL)\n"); + SetRectEmpty( &rect ); + ok(ValidateRect(0, &rect), "ValidateRect(0, &rc) should not fail\n"); + check_update_rgn( hwnd, hrgn ); + ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmPaint, "Paint", FALSE ); + RedrawWindow( hwnd, NULL, NULL, RDW_VALIDATE ); + check_update_rgn( hwnd, 0 ); + + trace("testing InvalidateRgn(0, NULL, FALSE)\n"); + SetLastError(0xdeadbeef); + ok(!InvalidateRgn(0, NULL, FALSE), "InvalidateRgn(0, NULL, FALSE) should fail\n"); + ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error code %ld\n", GetLastError()); + check_update_rgn( hwnd, 0 ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + + trace("testing ValidateRgn(0, NULL)\n"); + SetLastError(0xdeadbeef); + ok(!ValidateRgn(0, NULL), "ValidateRgn(0, NULL) should fail\n"); + ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error code %ld\n", GetLastError()); + check_update_rgn( hwnd, 0 ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + /* now with frame */ SetRectRgn( hrgn, -5, -5, 20, 20 );
@@ -3773,10 +4158,7 @@ ShowWindow( hparent, SW_SHOW ); UpdateWindow( hparent ); UpdateWindow( hchild ); - /* try to flush pending X expose events */ - MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT ); - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); - + flush_events(); flush_sequence(); log_all_parent_messages++;
@@ -3956,11 +4338,53 @@ while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); ok_sequence( WmParentOnlyPaint, "WmParentOnlyPaint", FALSE );
+ assert( GetWindowLong(hparent, GWL_STYLE) & WS_CLIPCHILDREN ); + UpdateWindow( hparent ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + trace("testing SWP_FRAMECHANGED on parent with WS_CLIPCHILDREN\n"); + RedrawWindow( hchild, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME ); + SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(WmSWP_FrameChanged_clip, "SetWindowPos:FrameChanged_clip", FALSE ); + + UpdateWindow( hparent ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent with WS_CLIPCHILDREN\n"); + RedrawWindow( hchild, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME ); + SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_DEFERERASE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(WmSWP_FrameChangedDeferErase, "SetWindowPos:FrameChangedDeferErase", FALSE ); + SetWindowLong( hparent, GWL_STYLE, GetWindowLong(hparent,GWL_STYLE) & ~WS_CLIPCHILDREN ); ok_sequence( WmSetParentStyle, "WmSetParentStyle", FALSE ); RedrawWindow( hparent, NULL, 0, RDW_INTERNALPAINT ); while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); ok_sequence( WmParentPaint, "WmParentPaint", FALSE ); + + assert( !(GetWindowLong(hparent, GWL_STYLE) & WS_CLIPCHILDREN) ); + UpdateWindow( hparent ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + trace("testing SWP_FRAMECHANGED on parent without WS_CLIPCHILDREN\n"); + RedrawWindow( hchild, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME ); + SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(WmSWP_FrameChanged_noclip, "SetWindowPos:FrameChanged_noclip", FALSE ); + + UpdateWindow( hparent ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent without WS_CLIPCHILDREN\n"); + RedrawWindow( hchild, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME ); + SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_DEFERERASE | + SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(WmSWP_FrameChangedDeferErase, "SetWindowPos:FrameChangedDeferErase", FALSE );
log_all_parent_messages--; DestroyWindow( hparent ); @@ -4124,6 +4548,8 @@ { HCBT_SYSCOMMAND, hook }, { WM_ENTERMENULOOP, sent|defwinproc|wparam|lparam, 0, 0 }, { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 }, + { 0x00AE, sent|defwinproc|optional }, /* XP */ + { WM_GETTEXT, sent|defwinproc|optional }, /* XP */ { WM_INITMENU, sent|defwinproc }, { EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 }, { WM_MENUCHAR, sent|defwinproc|wparam, MAKEWPARAM('n',MF_SYSMENU) }, @@ -4237,6 +4663,16 @@ { WM_SYSKEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 }, { 0 } }; +static const struct message WmF1Seq[] = { + { WM_KEYDOWN, wparam|lparam, VK_F1, 1 }, + { WM_KEYDOWN, sent|wparam|lparam, VK_F1, 0x00000001 }, + { 0x4d, wparam|lparam, 0, 0 }, + { 0x4d, sent|wparam|lparam, 0, 0 }, + { WM_HELP, sent|defwinproc }, + { WM_KEYUP, wparam|lparam, VK_F1, 0xc0000001 }, + { WM_KEYUP, sent|wparam|lparam, VK_F1, 0xc0000001 }, + { 0 } +};
static void pump_msg_loop(HWND hwnd, HACCEL hAccel) { @@ -4250,6 +4686,7 @@
/* ignore some unwanted messages */ if (msg.message == WM_MOUSEMOVE || + msg.message == WM_GETICON || msg.message == WM_DEVICECHANGE) continue;
@@ -4278,6 +4715,7 @@
assert(hwnd != 0); UpdateWindow(hwnd); + flush_events(); SetFocus(hwnd); ok(GetFocus() == hwnd, "wrong focus window %p\n", GetFocus());
@@ -4442,12 +4880,18 @@ pump_msg_loop(hwnd, 0); ok_sequence(WmAltMouseButton, "Alt+MouseButton press/release", FALSE);
+ keybd_event(VK_F1, 0, 0, 0); + keybd_event(VK_F1, 0, KEYEVENTF_KEYUP, 0); + pump_msg_loop(hwnd, 0); + ok_sequence(WmF1Seq, "F1 press/release", TRUE); + DestroyWindow(hwnd); }
/************* window procedures ********************/
-static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam) { static long defwndproc_counter = 0; static long beginpaint_counter = 0; @@ -4455,6 +4899,9 @@ struct message msg;
trace("%p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0;
switch (message) { @@ -4471,7 +4918,7 @@ { DWORD style = GetWindowLongA(hwnd, GWL_STYLE); if (style & WS_CHILD) - lParam = GetWindowLongA(hwnd, GWL_ID); + lParam = GetWindowLongPtrA(hwnd, GWLP_ID); else if (style & WS_POPUP) lParam = WND_POPUP_ID; else @@ -4500,7 +4947,7 @@ { DWORD style = GetWindowLongA(hwnd, GWL_STYLE); if (style & WS_CHILD) - lParam = GetWindowLongA(hwnd, GWL_ID); + lParam = GetWindowLongPtrA(hwnd, GWLP_ID); else if (style & WS_POPUP) lParam = WND_POPUP_ID; else @@ -4581,10 +5028,21 @@ }
defwndproc_counter++; - ret = DefWindowProcA(hwnd, message, wParam, lParam); + ret = unicode ? DefWindowProcW(hwnd, message, wParam, lParam) + : DefWindowProcA(hwnd, message, wParam, lParam); defwndproc_counter--;
return ret; +} + +static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + return MsgCheckProc (FALSE, hwnd, message, wParam, lParam); +} + +static LRESULT WINAPI MsgCheckProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + return MsgCheckProc (TRUE, hwnd, message, wParam, lParam); }
static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) @@ -4594,6 +5052,9 @@ struct message msg;
trace("popup: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0;
msg.message = message; msg.flags = sent|wparam|lparam; @@ -4624,12 +5085,45 @@
trace("parent: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
+ /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0; + if (log_all_parent_messages || message == WM_PARENTNOTIFY || message == WM_CANCELMODE || message == WM_SETFOCUS || message == WM_KILLFOCUS || message == WM_ENABLE || message == WM_ENTERIDLE || message == WM_IME_SETCONTEXT) { + switch (message) + { + case WM_ERASEBKGND: + { + RECT rc; + INT ret = GetClipBox((HDC)wParam, &rc); + + trace("WM_ERASEBKGND: GetClipBox()=%d, (%ld,%ld-%ld,%ld)\n", + ret, rc.left, rc.top, rc.right, rc.bottom); + break; + } + + case WM_WINDOWPOSCHANGING: + case WM_WINDOWPOSCHANGED: + { + WINDOWPOS *winpos = (WINDOWPOS *)lParam; + + trace("%s\n", (message == WM_WINDOWPOSCHANGING) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED"); + trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n", + winpos->hwnd, winpos->hwndInsertAfter, + winpos->x, winpos->y, winpos->cx, winpos->cy, winpos->flags); + + /* Log only documented flags, win2k uses 0x1000 and 0x2000 + * in the high word for internal purposes + */ + wParam = winpos->flags & 0xffff; + break; + } + } + msg.message = message; msg.flags = sent|parent|wparam|lparam; if (defwndproc_counter) msg.flags |= defwinproc; @@ -4663,6 +5157,9 @@ struct message msg;
trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0;
DefDlgProcA(hwnd, DM_SETDEFID, 1, 0); ret = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0); @@ -4791,7 +5288,7 @@ { DWORD style = GetWindowLongA((HWND)wParam, GWL_STYLE); if (style & WS_CHILD) - lParam = GetWindowLongA((HWND)wParam, GWL_ID); + lParam = GetWindowLongPtrA((HWND)wParam, GWLP_ID); else if (style & WS_POPUP) lParam = WND_POPUP_ID; else @@ -4813,6 +5310,7 @@ !lstrcmpiA(buf, "MDI_client_class") || !lstrcmpiA(buf, "MDI_child_class") || !lstrcmpiA(buf, "my_button_class") || + !lstrcmpiA(buf, "my_edit_class") || !lstrcmpiA(buf, "static") || !lstrcmpiA(buf, "#32770")) { @@ -4858,6 +5356,7 @@ !lstrcmpiA(buf, "MDI_client_class") || !lstrcmpiA(buf, "MDI_child_class") || !lstrcmpiA(buf, "my_button_class") || + !lstrcmpiA(buf, "my_edit_class") || !lstrcmpiA(buf, "static") || !lstrcmpiA(buf, "#32770")) { @@ -4890,6 +5389,32 @@ return DefWindowProcW(hwnd, uMsg, wParam, lParam); }
+static const struct message WmGetTextLengthAfromW[] = { + { WM_GETTEXTLENGTH, sent }, + { WM_GETTEXT, sent }, + { 0 } +}; + +static const WCHAR testWindowClassW[] = +{ 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 }; + +static const WCHAR dummy_window_text[] = {'d','u','m','m','y',' ','t','e','x','t',0}; + +/* dummy window proc for WM_GETTEXTLENGTH test */ +static LRESULT CALLBACK get_text_len_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) +{ + switch(msg) + { + case WM_GETTEXTLENGTH: + return lstrlenW(dummy_window_text) + 37; /* some random length */ + case WM_GETTEXT: + lstrcpynW( (LPWSTR)lp, dummy_window_text, wp ); + return lstrlenW( (LPWSTR)lp ); + default: + return DefWindowProcW( hwnd, msg, wp, lp ); + } +} + static void test_message_conversion(void) { static const WCHAR wszMsgConversionClass[] = @@ -4897,7 +5422,8 @@ WNDCLASSW cls; LRESULT lRes; HWND hwnd; - WNDPROC wndproc; + WNDPROC wndproc, newproc; + BOOL ret;
cls.style = 0; cls.lpfnWndProc = MsgConversionProcW; @@ -4911,6 +5437,18 @@ cls.lpszClassName = wszMsgConversionClass; /* this call will fail on Win9x, but that doesn't matter as this test is * meaningless on those platforms */ + if(!RegisterClassW(&cls)) return; + + cls.style = 0; + cls.lpfnWndProc = MsgCheckProcW; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleW(0); + cls.hIcon = 0; + cls.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = testWindowClassW; if(!RegisterClassW(&cls)) return;
hwnd = CreateWindowExW(0, wszMsgConversionClass, NULL, WS_OVERLAPPED, @@ -4974,14 +5512,49 @@ lRes = SendMessageCallbackW(hwnd, CB_FINDSTRINGEXACT, 0, (LPARAM)wszUnicode, NULL, 0); ok(lRes == 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY || GetLastError() == ERROR_INVALID_PARAMETER), "SendMessageCallback on sync only message returned %ld, last error %ld\n", lRes, GetLastError()); -} - -typedef struct _thread_info + + /* Check WM_GETTEXTLENGTH A->W behaviour, whether WM_GETTEXT is also sent or not */ + + hwnd = CreateWindowW (testWindowClassW, wszUnicode, + WS_OVERLAPPEDWINDOW, + 100, 100, 200, 200, 0, 0, 0, NULL); + assert(hwnd); + flush_sequence(); + lRes = SendMessageA (hwnd, WM_GETTEXTLENGTH, 0, 0); + ok_sequence(WmGetTextLengthAfromW, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE); + ok( lRes == WideCharToMultiByte( CP_ACP, 0, wszUnicode, lstrlenW(wszUnicode), NULL, 0, NULL, NULL ), + "got bad length %ld\n", lRes ); + + flush_sequence(); + lRes = CallWindowProcA( (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ), + hwnd, WM_GETTEXTLENGTH, 0, 0); + ok_sequence(WmGetTextLengthAfromW, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE); + ok( lRes == WideCharToMultiByte( CP_ACP, 0, wszUnicode, lstrlenW(wszUnicode), NULL, 0, NULL, NULL ), + "got bad length %ld\n", lRes ); + + wndproc = (WNDPROC)SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)get_text_len_proc ); + newproc = (WNDPROC)GetWindowLongPtrA( hwnd, GWLP_WNDPROC ); + lRes = CallWindowProcA( newproc, hwnd, WM_GETTEXTLENGTH, 0, 0 ); + ok( lRes == WideCharToMultiByte( CP_ACP, 0, dummy_window_text, lstrlenW(dummy_window_text), + NULL, 0, NULL, NULL ), + "got bad length %ld\n", lRes ); + + SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc ); /* restore old wnd proc */ + lRes = CallWindowProcA( newproc, hwnd, WM_GETTEXTLENGTH, 0, 0 ); + ok( lRes == WideCharToMultiByte( CP_ACP, 0, dummy_window_text, lstrlenW(dummy_window_text), + NULL, 0, NULL, NULL ), + "got bad length %ld\n", lRes ); + + ret = DestroyWindow(hwnd); + ok( ret, "DestroyWindow() error %ld\n", GetLastError()); +} + +struct timer_info { HWND hWnd; HANDLE handles[2]; DWORD id; -} thread_info; +};
static VOID CALLBACK tfunc(HWND hwnd, UINT uMsg, UINT id, DWORD dwTime) { @@ -4991,7 +5564,7 @@
static DWORD WINAPI timer_thread_proc(LPVOID x) { - thread_info *info = x; + struct timer_info *info = x; DWORD r;
r = KillTimer(info->hWnd, 0x19); @@ -5006,7 +5579,7 @@
static void test_timers(void) { - thread_info info; + struct timer_info info; DWORD id;
info.hWnd = CreateWindow ("TestWindowClass", NULL, @@ -5100,6 +5673,13 @@ { 0 } };
+static const struct message WmMouseLLHookSeq[] = { + { WM_MOUSEMOVE, hook }, + { WM_LBUTTONDOWN, hook }, + { WM_LBUTTONUP, hook }, + { 0 } +}; + static void CALLBACK win_event_global_hook_proc(HWINEVENTHOOK hevent, DWORD event, HWND hwnd, @@ -5149,6 +5729,21 @@ msg.lParam = (cbt_global_hook_thread_id == GetCurrentThreadId()) ? 1 : 2; add_message(&msg);
+ return CallNextHookEx(hCBT_global_hook, nCode, wParam, lParam); + } + /* WH_MOUSE_LL hook */ + if (nCode == HC_ACTION) + { + struct message msg; + MSLLHOOKSTRUCT *mhll = (MSLLHOOKSTRUCT *)lParam; + + /* we can't test for real mouse events */ + if (mhll->flags & LLMHF_INJECTED) + { + msg.message = wParam; + msg.flags = hook; + add_message(&msg); + } return CallNextHookEx(hCBT_global_hook, nCode, wParam, lParam); }
@@ -5235,6 +5830,33 @@ { TranslateMessage(&msg); DispatchMessage(&msg); + } + return 0; +} + +static DWORD WINAPI mouse_ll_global_thread_proc(void *param) +{ + HWND hwnd; + MSG msg; + HANDLE hevent = *(HANDLE *)param; + + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL); + assert(hwnd); + trace("created thread window %p\n", hwnd); + + *(HWND *)param = hwnd; + + flush_sequence(); + + mouse_event(MOUSEEVENTF_MOVE, 100, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + + SetEvent(hevent); + while (GetMessage(&msg, 0, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); } return 0; } @@ -5401,6 +6023,39 @@ ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n"); /****** end of out of context event test *************/
+ /****** start of MOUSE_LL hook test *************/ + hCBT_global_hook = SetWindowsHookExA(WH_MOUSE_LL, cbt_global_hook_proc, GetModuleHandleA(0), 0); + assert(hCBT_global_hook); + + hevent = CreateEventA(NULL, 0, 0, NULL); + assert(hevent); + hwnd2 = (HWND)hevent; + + hthread = CreateThread(NULL, 0, mouse_ll_global_thread_proc, &hwnd2, 0, &tid); + ok(hthread != NULL, "CreateThread failed, error %ld\n", GetLastError()); + + while (WaitForSingleObject(hevent, 100) == WAIT_TIMEOUT) + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + + ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook other thread", FALSE); + flush_sequence(); + + mouse_event(MOUSEEVENTF_MOVE, 0, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); + mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); + + ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook same thread", FALSE); + + ret = UnhookWindowsHookEx(hCBT_global_hook); + ok( ret, "UnhookWindowsHookEx error %ld\n", GetLastError()); + + PostThreadMessageA(tid, WM_QUIT, 0, 0); + ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n"); + CloseHandle(hthread); + CloseHandle(hevent); + ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n"); + /****** end of MOUSE_LL hook test *************/ + ok(DestroyWindow(hwnd), "failed to destroy window\n"); }
@@ -5530,7 +6185,7 @@ 10, 10, 150, 150, hwnd, 0, 0, NULL); ok (hchild != 0, "Failed to create child\n"); UpdateWindow(hwnd); - while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_events(); flush_sequence();
/* scroll without the child window */ @@ -5727,11 +6382,7 @@
static LRESULT WINAPI DispatchMessageCheckProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - if (message == WM_PAINT) - { - trace( "Got WM_PAINT, ignoring\n" ); - return 0; - } + if (message == WM_PAINT) return 0; return MsgCheckProcA( hwnd, message, wParam, lParam ); }
@@ -5746,7 +6397,7 @@ UpdateWindow( hwnd ); while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); flush_sequence(); - SetWindowLongPtrA( hwnd, GWL_WNDPROC, (LONG_PTR)DispatchMessageCheckProc ); + SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)DispatchMessageCheckProc );
SetRect( &rect, -5, -5, 5, 5 ); RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE|RDW_ERASE|RDW_FRAME ); @@ -5787,8 +6438,673 @@ if (++count > 10) break; } } -} - + DestroyWindow(hwnd); +} + + +static const struct message WmUser[] = { + { WM_USER, sent }, + { 0 } +}; + +struct sendmsg_info +{ + HWND hwnd; + DWORD timeout; + DWORD ret; +}; + +static DWORD CALLBACK send_msg_thread( LPVOID arg ) +{ + struct sendmsg_info *info = arg; + info->ret = SendMessageTimeoutA( info->hwnd, WM_USER, 0, 0, 0, info->timeout, NULL ); + if (!info->ret) ok( GetLastError() == ERROR_TIMEOUT, "unexpected error %ld\n", GetLastError()); + return 0; +} + +static void wait_for_thread( HANDLE thread ) +{ + while (MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_SENDMESSAGE) != WAIT_OBJECT_0) + { + MSG msg; + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage(&msg); + } +} + +static LRESULT WINAPI send_msg_delay_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + if (message == WM_USER) Sleep(200); + return MsgCheckProcA( hwnd, message, wParam, lParam ); +} + +static void test_SendMessageTimeout(void) +{ + MSG msg; + HANDLE thread; + struct sendmsg_info info; + DWORD tid; + + info.hwnd = CreateWindowA( "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW, + 100, 100, 200, 200, 0, 0, 0, NULL); + while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + + info.timeout = 1000; + info.ret = 0xdeadbeef; + thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); + wait_for_thread( thread ); + CloseHandle( thread ); + ok( info.ret == 1, "SendMessageTimeout failed\n" ); + ok_sequence( WmUser, "WmUser", FALSE ); + + info.timeout = 1; + info.ret = 0xdeadbeef; + thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); + Sleep(100); /* SendMessageTimeout should timeout here */ + wait_for_thread( thread ); + CloseHandle( thread ); + ok( info.ret == 0, "SendMessageTimeout succeeded\n" ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + + /* 0 means infinite timeout */ + info.timeout = 0; + info.ret = 0xdeadbeef; + thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); + Sleep(100); + wait_for_thread( thread ); + CloseHandle( thread ); + ok( info.ret == 1, "SendMessageTimeout failed\n" ); + ok_sequence( WmUser, "WmUser", FALSE ); + + /* timeout is treated as signed despite the prototype */ + info.timeout = 0x7fffffff; + info.ret = 0xdeadbeef; + thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); + Sleep(100); + wait_for_thread( thread ); + CloseHandle( thread ); + ok( info.ret == 1, "SendMessageTimeout failed\n" ); + ok_sequence( WmUser, "WmUser", FALSE ); + + info.timeout = 0x80000000; + info.ret = 0xdeadbeef; + thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); + Sleep(100); + wait_for_thread( thread ); + CloseHandle( thread ); + ok( info.ret == 0, "SendMessageTimeout succeeded\n" ); + ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE ); + + /* now check for timeout during message processing */ + SetWindowLongPtrA( info.hwnd, GWLP_WNDPROC, (LONG_PTR)send_msg_delay_proc ); + info.timeout = 100; + info.ret = 0xdeadbeef; + thread = CreateThread( NULL, 0, send_msg_thread, &info, 0, &tid ); + wait_for_thread( thread ); + CloseHandle( thread ); + /* we should timeout but still get the message */ + ok( info.ret == 0, "SendMessageTimeout failed\n" ); + ok_sequence( WmUser, "WmUser", FALSE ); + + DestroyWindow( info.hwnd ); +} + + +/****************** edit message test *************************/ +#define ID_EDIT 0x1234 +static const struct message sl_edit_setfocus[] = +{ + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent|wparam, 0 }, + { WM_CTLCOLOREDIT, sent|parent }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) }, + { 0 } +}; +static const struct message ml_edit_setfocus[] = +{ + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent|wparam, 0 }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) }, + { 0 } +}; +static const struct message sl_edit_killfocus[] = +{ + { HCBT_SETFOCUS, hook }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_KILLFOCUS, sent|wparam, 0 }, + { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_KILLFOCUS) }, + { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, + { 0 } +}; +static const struct message sl_edit_lbutton_dblclk[] = +{ + { WM_LBUTTONDBLCLK, sent }, + { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 }, + { 0 } +}; +static const struct message sl_edit_lbutton_down[] = +{ + { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 }, + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { WM_CTLCOLOREDIT, sent|parent }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) }, + { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { 0 } +}; +static const struct message ml_edit_lbutton_down[] = +{ + { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 }, + { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 }, + { HCBT_SETFOCUS, hook }, + { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, + { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) }, + { 0 } +}; +static const struct message sl_edit_lbutton_up[] = +{ + { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 }, + { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 }, + { WM_CAPTURECHANGED, sent|defwinproc }, + { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, + { 0 } +}; +static const struct message ml_edit_lbutton_up[] = +{ + { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 }, + { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 }, + { WM_CAPTURECHANGED, sent|defwinproc }, + { 0 } +}; + +static WNDPROC old_edit_proc; + +static LRESULT CALLBACK edit_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static long defwndproc_counter = 0; + LRESULT ret; + struct message msg; + + trace("edit: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + /* explicitly ignore WM_GETICON message */ + if (message == WM_GETICON) return 0; + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + add_message(&msg); + + defwndproc_counter++; + ret = CallWindowProcA(old_edit_proc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + +static void subclass_edit(void) +{ + WNDCLASSA cls; + + if (!GetClassInfoA(0, "edit", &cls)) assert(0); + + old_edit_proc = cls.lpfnWndProc; + + cls.hInstance = GetModuleHandle(0); + cls.lpfnWndProc = edit_hook_proc; + cls.lpszClassName = "my_edit_class"; + if (!RegisterClassA(&cls)) assert(0); +} + +static void test_edit_messages(void) +{ + HWND hwnd, parent; + DWORD dlg_code; + + subclass_edit(); + log_all_parent_messages++; + + parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (parent != 0, "Failed to create parent window\n"); + + /* test single line edit */ + hwnd = CreateWindowExA(0, "my_edit_class", "test", WS_CHILD, + 0, 0, 80, 20, parent, (HMENU)ID_EDIT, 0, NULL); + ok(hwnd != 0, "Failed to create edit window\n"); + + dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0); + ok(dlg_code == (DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTARROWS), "wrong dlg_code %08lx\n", dlg_code); + + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + SetFocus(0); + flush_sequence(); + + SetFocus(hwnd); + ok_sequence(sl_edit_setfocus, "SetFocus(hwnd) on an edit", FALSE); + + SetFocus(0); + ok_sequence(sl_edit_killfocus, "SetFocus(0) on an edit", FALSE); + + SetFocus(0); + ReleaseCapture(); + flush_sequence(); + + SendMessageA(hwnd, WM_LBUTTONDBLCLK, 0, 0); + ok_sequence(sl_edit_lbutton_dblclk, "WM_LBUTTONDBLCLK on an edit", FALSE); + + SetFocus(0); + ReleaseCapture(); + flush_sequence(); + + SendMessageA(hwnd, WM_LBUTTONDOWN, 0, 0); + ok_sequence(sl_edit_lbutton_down, "WM_LBUTTONDOWN on an edit", FALSE); + + SendMessageA(hwnd, WM_LBUTTONUP, 0, 0); + ok_sequence(sl_edit_lbutton_up, "WM_LBUTTONUP on an edit", FALSE); + + DestroyWindow(hwnd); + + /* test multiline edit */ + hwnd = CreateWindowExA(0, "my_edit_class", "test", WS_CHILD | ES_MULTILINE, + 0, 0, 80, 20, parent, (HMENU)ID_EDIT, 0, NULL); + ok(hwnd != 0, "Failed to create edit window\n"); + + dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0); + ok(dlg_code == (DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTARROWS|DLGC_WANTALLKEYS), + "wrong dlg_code %08lx\n", dlg_code); + + ShowWindow(hwnd, SW_SHOW); + UpdateWindow(hwnd); + SetFocus(0); + flush_sequence(); + + SetFocus(hwnd); + ok_sequence(ml_edit_setfocus, "SetFocus(hwnd) on multiline edit", FALSE); + + SetFocus(0); + ok_sequence(sl_edit_killfocus, "SetFocus(0) on multiline edit", FALSE); + + SetFocus(0); + ReleaseCapture(); + flush_sequence(); + + SendMessageA(hwnd, WM_LBUTTONDBLCLK, 0, 0); + ok_sequence(sl_edit_lbutton_dblclk, "WM_LBUTTONDBLCLK on multiline edit", FALSE); + + SetFocus(0); + ReleaseCapture(); + flush_sequence(); + + SendMessageA(hwnd, WM_LBUTTONDOWN, 0, 0); + ok_sequence(ml_edit_lbutton_down, "WM_LBUTTONDOWN on multiline edit", FALSE); + + SendMessageA(hwnd, WM_LBUTTONUP, 0, 0); + ok_sequence(ml_edit_lbutton_up, "WM_LBUTTONUP on multiline edit", FALSE); + + DestroyWindow(hwnd); + DestroyWindow(parent); + + log_all_parent_messages--; +} + +/**************************** End of Edit test ******************************/ + +static const struct message WmChar[] = { + { WM_CHAR, sent|wparam, 'z' }, + { 0 } +}; + +static const struct message WmKeyDownUp[] = { + { WM_KEYDOWN, sent|wparam|lparam, 'N', 0x00000001 }, + { WM_KEYUP, sent|wparam|lparam, 'N', 0xc0000001 }, + { 0 } +}; + +static const struct message WmUserChar[] = { + { WM_USER, sent }, + { WM_CHAR, sent|wparam, 'z' }, + { 0 } +}; + +#define EV_START_STOP 0 +#define EV_SENDMSG 1 +#define EV_ACK 2 + +struct peekmsg_info +{ + HWND hwnd; + HANDLE hevent[3]; /* 0 - start/stop, 1 - SendMessage, 2 - ack */ +}; + +static DWORD CALLBACK send_msg_thread_2(void *param) +{ + DWORD ret; + struct peekmsg_info *info = param; + + trace("thread: waiting for start\n"); + WaitForSingleObject(info->hevent[EV_START_STOP], INFINITE); + trace("thread: looping\n"); + + while (1) + { + ret = WaitForMultipleObjects(2, info->hevent, FALSE, INFINITE); + + switch (ret) + { + case WAIT_OBJECT_0 + EV_START_STOP: + trace("thread: exiting\n"); + return 0; + + case WAIT_OBJECT_0 + EV_SENDMSG: + trace("thread: sending message\n"); + SendNotifyMessageA(info->hwnd, WM_USER, 0, 0); + SetEvent(info->hevent[EV_ACK]); + break; + + default: + trace("unexpected return: %04lx\n", ret); + assert(0); + break; + } + } + return 0; +} + +static void test_PeekMessage(void) +{ + MSG msg; + HANDLE hthread; + DWORD tid, qstatus; + UINT qs_all_input = QS_ALLINPUT; + UINT qs_input = QS_INPUT; + struct peekmsg_info info; + + info.hwnd = CreateWindowA("TestWindowClass", NULL, WS_OVERLAPPEDWINDOW, + 100, 100, 200, 200, 0, 0, 0, NULL); + ShowWindow(info.hwnd, SW_SHOW); + UpdateWindow(info.hwnd); + + info.hevent[EV_START_STOP] = CreateEventA(NULL, 0, 0, NULL); + info.hevent[EV_SENDMSG] = CreateEventA(NULL, 0, 0, NULL); + info.hevent[EV_ACK] = CreateEventA(NULL, 0, 0, NULL); + + hthread = CreateThread(NULL, 0, send_msg_thread_2, &info, 0, &tid); + + trace("signalling to start looping\n"); + SetEvent(info.hevent[EV_START_STOP]); + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + flush_sequence(); + + SetLastError(0xdeadbeef); + qstatus = GetQueueStatus(qs_all_input); + if (GetLastError() == ERROR_INVALID_FLAGS) + { + trace("QS_RAWINPUT not supported on this platform\n"); + qs_all_input &= ~QS_RAWINPUT; + qs_input &= ~QS_RAWINPUT; + } + ok(qstatus == 0, "wrong qstatus %08lx\n", qstatus); + + trace("signalling to send message\n"); + SetEvent(info.hevent[EV_SENDMSG]); + WaitForSingleObject(info.hevent[EV_ACK], INFINITE); + + /* pass invalid QS_xxxx flags */ + SetLastError(0xdeadbeef); + qstatus = GetQueueStatus(0xffffffff); + ok(qstatus == 0, "GetQueueStatus should fail: %08lx\n", qstatus); + ok(GetLastError() == ERROR_INVALID_FLAGS, "wrong error %ld\n", GetLastError()); + + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE), + "wrong qstatus %08lx\n", qstatus); + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + ok_sequence(WmUser, "WmUser", FALSE); + + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == 0, "wrong qstatus %08lx\n", qstatus); + + keybd_event('N', 0, 0, 0); + keybd_event('N', 0, KEYEVENTF_KEYUP, 0); + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == MAKELONG(QS_KEY, QS_KEY), + "wrong qstatus %08lx\n", qstatus); + + PostMessageA(info.hwnd, WM_CHAR, 'z', 0); + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); + + InvalidateRect(info.hwnd, NULL, FALSE); + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == MAKELONG(QS_PAINT, QS_PAINT|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); + + trace("signalling to send message\n"); + SetEvent(info.hevent[EV_SENDMSG]); + WaitForSingleObject(info.hevent[EV_ACK], INFINITE); + + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_PAINT|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (qs_input << 16))) DispatchMessageA(&msg); + ok_sequence(WmUser, "WmUser", TRUE); /* todo_wine */ + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_PAINT|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + trace("signalling to send message\n"); + SetEvent(info.hevent[EV_SENDMSG]); + WaitForSingleObject(info.hevent[EV_ACK], INFINITE); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_PAINT|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE)) DispatchMessageA(&msg); + ok_sequence(WmUser, "WmUser", FALSE); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_PAINT|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE)) DispatchMessageA(&msg); + ok_sequence(WmChar, "WmChar", TRUE); /* todo_wine */ + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_PAINT|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_PAINT)) DispatchMessageA(&msg); + ok_sequence(WmPaint, "WmPaint", TRUE); /* todo_wine */ + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + trace("signalling to send message\n"); + SetEvent(info.hevent[EV_SENDMSG]); + WaitForSingleObject(info.hevent[EV_ACK], INFINITE); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + PostMessageA(info.hwnd, WM_CHAR, 'z', 0); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, WM_CHAR, WM_CHAR, PM_REMOVE)) DispatchMessage(&msg); + ok_sequence(WmUserChar, "WmUserChar", FALSE); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + PostMessageA(info.hwnd, WM_CHAR, 'z', 0); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + trace("signalling to send message\n"); + SetEvent(info.hevent[EV_SENDMSG]); + WaitForSingleObject(info.hevent[EV_ACK], INFINITE); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_KEY << 16))) DispatchMessage(&msg); + ok_sequence(WmUser, "WmUser", TRUE); /* todo_wine */ + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_POSTMESSAGE|QS_KEY), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_RAWINPUT << 16))) DispatchMessage(&msg); + ok_sequence(WmKeyDownUp, "WmKeyDownUp", TRUE); /* todo_wine */ + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_POSTMESSAGE), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE)) DispatchMessage(&msg); + ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE); + + qstatus = GetQueueStatus(qs_all_input); +todo_wine { + ok(qstatus == MAKELONG(0, QS_POSTMESSAGE), + "wrong qstatus %08lx\n", qstatus); +} + + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); + ok_sequence(WmChar, "WmChar", TRUE); /* todo_wine */ + + qstatus = GetQueueStatus(qs_all_input); + ok(qstatus == 0, + "wrong qstatus %08lx\n", qstatus); + + trace("signalling to exit\n"); + SetEvent(info.hevent[EV_START_STOP]); + + WaitForSingleObject(hthread, INFINITE); + + CloseHandle(hthread); + CloseHandle(info.hevent[0]); + CloseHandle(info.hevent[1]); + CloseHandle(info.hevent[2]); + + DestroyWindow(info.hwnd); +} + + +static void test_quit_message(void) +{ + MSG msg; + BOOL ret; + + /* test using PostQuitMessage */ + PostQuitMessage(0xbeef); + + ret = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); + ok(ret, "PeekMessage failed with error %ld\n", GetLastError()); + ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message); + ok(msg.wParam == 0xbeef, "wParam was 0x%x instead of 0xbeef\n", msg.wParam); + + ret = PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0); + ok(ret, "PostMessage failed with error %ld\n", GetLastError()); + + ret = GetMessage(&msg, NULL, 0, 0); + ok(ret > 0, "GetMessage failed with error %ld\n", GetLastError()); + ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message); + + /* note: WM_QUIT message received after WM_USER message */ + ret = GetMessage(&msg, NULL, 0, 0); + ok(!ret, "GetMessage return %d with error %ld instead of FALSE\n", ret, GetLastError()); + ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message); + ok(msg.wParam == 0xbeef, "wParam was 0x%x instead of 0xbeef\n", msg.wParam); + + ret = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); + ok( !ret || msg.message != WM_QUIT, "Received WM_QUIT again\n" ); + + /* now test with PostThreadMessage - different behaviour! */ + PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0xdead, 0); + + ret = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); + ok(ret, "PeekMessage failed with error %ld\n", GetLastError()); + ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message); + ok(msg.wParam == 0xdead, "wParam was 0x%x instead of 0xdead\n", msg.wParam); + + ret = PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0); + ok(ret, "PostMessage failed with error %ld\n", GetLastError()); + + /* note: we receive the WM_QUIT message first this time */ + ret = GetMessage(&msg, NULL, 0, 0); + ok(!ret, "GetMessage return %d with error %ld instead of FALSE\n", ret, GetLastError()); + ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message); + ok(msg.wParam == 0xdead, "wParam was 0x%x instead of 0xdead\n", msg.wParam); + + ret = GetMessage(&msg, NULL, 0, 0); + ok(ret > 0, "GetMessage failed with error %ld\n", GetLastError()); + ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message); +}
START_TEST(msg) { @@ -5825,12 +7141,15 @@
test_winevents();
- /* Fix message sequences before removing 3 lines below */ + /* Fix message sequences before removing 4 lines below */ +#if 1 ret = pUnhookWinEvent(hEvent_hook); ok( ret, "UnhookWinEvent error %ld\n", GetLastError()); pUnhookWinEvent = 0; hEvent_hook = 0; - +#endif + + test_PeekMessage(); test_scrollwindowex(); test_messages(); test_mdi_messages(); @@ -5843,6 +7162,9 @@ test_set_hook(); test_DestroyWindow(); test_DispatchMessage(); + test_SendMessageTimeout(); + test_edit_messages(); + test_quit_message();
UnhookWindowsHookEx(hCBT_hook); if (pUnhookWinEvent)
Propchange: trunk/reactos/regtests/winetests/user32/msg.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/resource.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/re... ============================================================================== --- trunk/reactos/regtests/winetests/user32/resource.c (original) +++ trunk/reactos/regtests/winetests/user32/resource.c Wed Apr 5 06:34:10 2006 @@ -23,6 +23,16 @@
#include "wine/test.h"
+static UINT (WINAPI *pPrivateExtractIconsA)(LPCTSTR, int, int, int, HICON *, UINT *, UINT, UINT) = NULL; + +static void init_function_pointers(void) +{ + HMODULE hmod = GetModuleHandleA("user32.dll"); + if (hmod) { + pPrivateExtractIconsA = (void*)GetProcAddress(hmod, "PrivateExtractIconsA"); + } +} + static void test_LoadStringA (void) { HINSTANCE hInst = GetModuleHandle (NULL); @@ -247,9 +257,50 @@ ok( DestroyAcceleratorTable( hac ), "destroy failed\n"); }
+static void test_PrivateExtractIcons(void) { + CONST CHAR szShell32Dll[] = "shell32.dll"; + HICON ahIcon[256]; + UINT aIconId[256]; + UINT cIcons, cIcons2; + + if (!pPrivateExtractIconsA) return; + + cIcons = pPrivateExtractIconsA(szShell32Dll, 0, 16, 16, NULL, NULL, 0, 0); + cIcons2 = pPrivateExtractIconsA(szShell32Dll, 4, MAKELONG(32,16), MAKELONG(32,16), + NULL, NULL, 256, 0); + ok((cIcons == cIcons2) && (cIcons > 0), + "Icon count should be independent of requested icon sizes and base icon index! " + "(cIcons=%d, cIcons2=%d)\n", cIcons, cIcons2); + + cIcons = pPrivateExtractIconsA(szShell32Dll, 0, 16, 16, ahIcon, aIconId, 0, 0); + ok(cIcons == 0, "Zero icons requested, got cIcons=%d\n", cIcons); + + cIcons = pPrivateExtractIconsA(szShell32Dll, 0, 16, 16, ahIcon, aIconId, 3, 0); + ok(cIcons == 3, "Three icons requested got cIcons=%d\n", cIcons); + + cIcons = pPrivateExtractIconsA(szShell32Dll, 0, MAKELONG(32,16), MAKELONG(32,16), + ahIcon, aIconId, 3, 0); + ok(cIcons == 4, "Three icons requested, four expected, got cIcons=%d\n", cIcons); +} + +static void test_LoadImage(void) { + HBITMAP bmp; + + bmp = LoadBitmapA(NULL, MAKEINTRESOURCE(OBM_CHECK)); + ok(bmp != NULL, "Could not load the OBM_CHECK bitmap\n"); + if (bmp) DeleteObject(bmp); + + bmp = LoadBitmapA(NULL, "#32760"); /* Value of OBM_CHECK */ + ok(bmp != NULL, "Could not load the OBM_CHECK bitmap\n"); + if (bmp) DeleteObject(bmp); +} + START_TEST(resource) { + init_function_pointers(); test_LoadStringA (); test_accel1(); test_accel2(); -} + test_PrivateExtractIcons(); + test_LoadImage(); +}
Propchange: trunk/reactos/regtests/winetests/user32/resource.c ------------------------------------------------------------------------------ native = class.c
Propchange: trunk/reactos/regtests/winetests/user32/resource.rc ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/sysparams.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/sy... ============================================================================== --- trunk/reactos/regtests/winetests/user32/sysparams.c (original) +++ trunk/reactos/regtests/winetests/user32/sysparams.c Wed Apr 5 06:34:10 2006 @@ -22,6 +22,7 @@ #include <stdarg.h> #include <stdio.h>
+#undef _WIN32_WINNT #define _WIN32_WINNT 0x0500 /* For SPI_GETMOUSEHOVERWIDTH and more */
#include "wine/test.h" @@ -30,12 +31,16 @@ #include "wingdi.h" #include "winreg.h" #include "winuser.h" +#include "winnls.h"
#ifndef SPI_GETDESKWALLPAPER # define SPI_GETDESKWALLPAPER 0x0073 #endif
static int strict; +static int dpi; +static int iswin9x; +static HDC hdc;
#define eq(received, expected, label, type) \ ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected)) @@ -48,9 +53,36 @@ #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2" #define SPI_SETMOUSE_VALNAME3 "MouseSpeed" #define SPI_SETBORDER_REGKEY "Control Panel\Desktop\WindowMetrics" +#define SPI_SETBORDER_REGKEY2 "Control Panel\Desktop" #define SPI_SETBORDER_VALNAME "BorderWidth" +#define SPI_METRIC_REGKEY "Control Panel\Desktop\WindowMetrics" +#define SPI_SCROLLWIDTH_VALNAME "ScrollWidth" +#define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight" +#define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth" +#define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight" +#define SPI_CAPTIONFONT_VALNAME "CaptionFont" +#define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth" +#define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight" +#define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont" +#define SPI_MENUWIDTH_VALNAME "MenuWidth" +#define SPI_MENUHEIGHT_VALNAME "MenuHeight" +#define SPI_MENUFONT_VALNAME "MenuFont" +#define SPI_STATUSFONT_VALNAME "StatusFont" +#define SPI_MESSAGEFONT_VALNAME "MessageFont" + #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\Keyboard" #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed" +#define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\Desktop\WindowMetrics" +#define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\Desktop" +#define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing" +#define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\Desktop\WindowMetrics" +#define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\Desktop" +#define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing" +#define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\Desktop\WindowMetrics" +#define SPI_MINWIDTH_VALNAME "MinWidth" +#define SPI_MINHORZGAP_VALNAME "MinHorzGap" +#define SPI_MINVERTGAP_VALNAME "MinVertGap" +#define SPI_MINARRANGE_VALNAME "MinArrange" #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\Desktop" #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut" #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\Desktop" @@ -87,6 +119,8 @@ #define SPI_SETSCREENREADER_VALNAME "On" #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\Accessibility" #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access" +#define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\Desktop" +#define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing" #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\Desktop" #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive" #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\Desktop" @@ -123,7 +157,13 @@ switch (msg) {
case WM_SETTINGCHANGE: - if (change_counter>0) { + if (change_counter>0) { + /* ignore these messages caused by resizing of toolbars */ + if( wParam == SPI_SETWORKAREA) break; + if( change_last_param == SPI_SETWORKAREA) { + change_last_param = wParam; + break; + } ok(0,"too many changes counter=%d last change=%d\n", change_counter,change_last_param); } @@ -294,6 +334,98 @@ #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \ _test_reg_key( subKey1, subKey2, valName1, valName2, testValue )
+/* get a metric from the registry. If the value is negative + * it is assumed to be in twips and converted to pixels */ +static UINT metricfromreg( char *keyname, char *valname, int dpi) +{ + HKEY hkey; + char buf[64]; + DWORD ret; + DWORD size, type; + int value; + + RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); + size = sizeof(buf); + ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size ); + RegCloseKey( hkey ); + if( ret != ERROR_SUCCESS) return -1; + value = atoi( buf); + if( value < 0) + value = ( -value * dpi + 720) / 1440; + return value; +} + +typedef struct +{ + INT16 lfHeight; + INT16 lfWidth; + INT16 lfEscapement; + INT16 lfOrientation; + INT16 lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + CHAR lfFaceName[LF_FACESIZE]; +} LOGFONT16, *LPLOGFONT16; + +/* get logfont from the registry */ +static int lffromreg( char *keyname, char *valname, LOGFONTA *plf) +{ + HKEY hkey; + LOGFONTW lfw; + DWORD ret, size, type; + + RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); + size = sizeof( lfw); + ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size ); + RegCloseKey( hkey ); + ok( ret == ERROR_SUCCESS, "Key "%s" value "%s" not found\n", keyname, valname); + if( ret != ERROR_SUCCESS) + return FALSE; + if( size <= sizeof( LOGFONT16)) { + LOGFONT16 *plf16 = (LOGFONT16*) &lfw; + plf->lfHeight = plf16->lfHeight; + plf->lfWidth = plf16->lfWidth; + plf->lfEscapement = plf16->lfEscapement; + plf->lfOrientation = plf16->lfOrientation; + plf->lfWeight = plf16->lfWeight; + plf->lfItalic = plf16->lfItalic; + plf->lfUnderline = plf16->lfUnderline; + plf->lfStrikeOut = plf16->lfStrikeOut; + plf->lfCharSet = plf16->lfCharSet; + plf->lfOutPrecision = plf16->lfOutPrecision; + plf->lfClipPrecision = plf16->lfClipPrecision; + plf->lfQuality = plf16->lfQuality; + plf->lfPitchAndFamily = plf16->lfPitchAndFamily; + memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE ); + } else if( size <= sizeof( LOGFONTA)) { + plf = (LOGFONTA*) &lfw; + } else { + plf->lfHeight = lfw.lfHeight; + plf->lfWidth = lfw.lfWidth; + plf->lfEscapement = lfw.lfEscapement; + plf->lfOrientation = lfw.lfOrientation; + plf->lfWeight = lfw.lfWeight; + plf->lfItalic = lfw.lfItalic; + plf->lfUnderline = lfw.lfUnderline; + plf->lfStrikeOut = lfw.lfStrikeOut; + plf->lfCharSet = lfw.lfCharSet; + plf->lfOutPrecision = lfw.lfOutPrecision; + plf->lfClipPrecision = lfw.lfClipPrecision; + plf->lfQuality = lfw.lfQuality; + plf->lfPitchAndFamily = lfw.lfPitchAndFamily; + WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName, + LF_FACESIZE, NULL, NULL); + + } + return TRUE; +} + static void test_SPI_SETBEEP( void ) /* 2 */ { BOOL rc; @@ -497,26 +629,44 @@ ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); }
-#if 0 -static void test_setborder(UINT curr_val) -{ - BOOL rc; - UINT border; +static void test_setborder(UINT curr_val, int usesetborder, int dpi) +{ + BOOL rc; + UINT border, regval; INT frame; - char buf[10]; - - rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - test_change_message( SPI_SETBORDER, 1 ); - sprintf( buf, "%d", curr_val ); - test_reg_key( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, buf ); - - if (curr_val == 0) - curr_val = 1; + NONCLIENTMETRICSA ncm; + + ncm.cbSize = sizeof( ncm); + rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + if( usesetborder) { + rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_SETBORDER, 1 ); + } else { /* set non client metrics */ + ncm.iBorderWidth = curr_val; + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE| + SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_SETNONCLIENTMETRICS, 1 ); + } + if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */ + regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi); + if( regval != curr_val) + regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi); + ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val); + } + /* minimum border width is 1 */ + if (curr_val == 0) curr_val = 1; + /* should be the same as the non client metrics */ + rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d"); + /* and from SPI_GETBORDER */ rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 ); ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d"); - + /* test some SystemMetrics */ frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME ); eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" ); eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" ); @@ -528,6 +678,18 @@ { BOOL rc; UINT old_border; + NONCLIENTMETRICSA ncmsave; + INT CaptionWidth; + + ncmsave.cbSize = sizeof( ncmsave); + rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* CaptionWidth from the registry may have different value of iCaptionWidth + * from the non client metrics (observed on WinXP). + * Fix this so we can safely restore settings with the nonclientmetrics */ + CaptionWidth = metricfromreg( + "Control Panel\Desktop\WindowMetrics","CaptionWidth", dpi); + ncmsave.iCaptionWidth = CaptionWidth;
/* These tests hang when XFree86 4.0 for Windows is running (tested on * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is @@ -537,24 +699,33 @@ return;
trace("testing SPI_{GET,SET}BORDER\n"); + SetLastError(0xdeadbeef); rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 ); if (!test_error_msg(rc,"SPI_{GET,SET}BORDER")) return; - - test_setborder(1); - test_setborder(0); - test_setborder(7); - test_setborder(20); - /* This will restore sane values if the test hang previous run. */ if ( old_border == 7 || old_border == 20 ) - old_border = -15; - - rc=SystemParametersInfoA( SPI_SETBORDER, old_border, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); - ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); -} -#endif + old_border = 1; + + /* The SPI_SETBORDER seems to be buggy on Win9x/ME (looks like you need to + * do it twice to make the intended change). So skip parts of the tests on + * those platforms */ + if( !iswin9x) { + test_setborder(1, 1, dpi); + test_setborder(0, 1, dpi); + test_setborder(2, 1, dpi); + } + test_setborder(1, 0, dpi); + test_setborder(0, 0, dpi); + test_setborder(3, 0, dpi); + + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave, + SPIF_UPDATEINIFILE| SPIF_SENDCHANGE); + test_change_message( SPI_SETNONCLIENTMETRICS, 1 ); + ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n", + rc,GetLastError()); +}
static void test_SPI_SETKEYBOARDSPEED( void ) /* 10 */ { @@ -590,12 +761,43 @@ ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); }
+/* test_SPI_ICONHORIZONTALSPACING helper */ +static void dotest_spi_iconhorizontalspacing( INT curr_val) +{ + BOOL rc; + INT spacing, regval; + ICONMETRICSA im; + + rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0, + SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_ICONHORIZONTALSPACING, 0 ); + if( curr_val < 32) curr_val = 32; + /* The registry keys depend on the Windows version and the values too + * let's test (works on win95,ME,NT4,2k,XP) + */ + regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY2, SPI_ICONHORIZONTALSPACING_VALNAME, dpi); + if( regval != curr_val) + regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi); + ok( curr_val == regval, + "wrong value in registry %d, expected %d\n", regval, curr_val); + /* compare with what SPI_ICONHORIZONTALSPACING returns */ + rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d"); + /* and with a system metrics */ + eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" ); + /* and with what SPI_GETICONMETRICS returns */ + im.cbSize = sizeof(ICONMETRICSA); + rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + eq( im.iHorzSpacing, curr_val, "SPI_GETICONMETRICS", "%d" ); +} + static void test_SPI_ICONHORIZONTALSPACING( void ) /* 13 */ { BOOL rc; INT old_spacing; - INT spacing; - INT curr_val;
trace("testing SPI_ICONHORIZONTALSPACING\n"); SetLastError(0xdeadbeef); @@ -603,34 +805,10 @@ rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &old_spacing, 0 ); if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING")) return; - /* do not increase the value as it would upset the user's icon layout */ - curr_val = (old_spacing > 32 ? old_spacing-1 : 32); - rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0, - SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - test_change_message( SPI_ICONHORIZONTALSPACING, 0 ); - /* The registry keys depend on the Windows version and the values too - * => don't test them - */ - - rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 ); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d"); - eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" ); - - curr_val = 10; - rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0, - SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - curr_val = 32; /*min value*/ - test_change_message( SPI_ICONHORIZONTALSPACING, 0 ); - - rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 ); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d" ); - eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" ); - + dotest_spi_iconhorizontalspacing( old_spacing - 1); + dotest_spi_iconhorizontalspacing( 10); /* minimum is 32 */ + /* restore */ rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE ); ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); } @@ -745,12 +923,44 @@ ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); }
+ +/* test_SPI_ICONVERTICALSPACING helper */ +static void dotest_spi_iconverticalspacing( INT curr_val) +{ + BOOL rc; + INT spacing, regval; + ICONMETRICSA im; + + rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0, + SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_ICONVERTICALSPACING, 0 ); + if( curr_val < 32) curr_val = 32; + /* The registry keys depend on the Windows version and the values too + * let's test (works on win95,ME,NT4,2k,XP) + */ + regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY2, SPI_ICONVERTICALSPACING_VALNAME, dpi); + if( regval != curr_val) + regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi); + ok( curr_val == regval, + "wrong value in registry %d, expected %d\n", regval, curr_val); + /* compare with what SPI_ICONVERTICALSPACING returns */ + rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" ); + /* and with a system metrics */ + eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" ); + /* and with what SPI_GETICONMETRICS returns */ + im.cbSize = sizeof(ICONMETRICSA); + rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + eq( im.iVertSpacing, curr_val, "SPI_GETICONMETRICS", "%d" ); +} + static void test_SPI_ICONVERTICALSPACING( void ) /* 24 */ { BOOL rc; INT old_spacing; - INT spacing; - INT curr_val;
trace("testing SPI_ICONVERTICALSPACING\n"); SetLastError(0xdeadbeef); @@ -758,37 +968,15 @@ rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &old_spacing, 0 ); if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING")) return; - /* do not increase the value as it would upset the user's icon layout */ - curr_val = old_spacing-1; - rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0, - SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - test_change_message( SPI_ICONVERTICALSPACING, 0 ); - /* The registry keys depend on the Windows version and the values too - * => don't test them - */ - - rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 ); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" ); - eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" ); - - curr_val = 10; - rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0, - SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - curr_val = 32; /*min value*/ - test_change_message( SPI_ICONVERTICALSPACING, 0 ); - - rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 ); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" ); - eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" ); - + dotest_spi_iconverticalspacing( old_spacing - 1); + /* same tests with a value less than the minimum 32 */ + dotest_spi_iconverticalspacing( 10); + /* restore */ rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE ); - ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); + ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n", + rc,GetLastError()); }
static void test_SPI_SETICONTITLEWRAP( void ) /* 26 */ @@ -797,6 +985,7 @@ BOOL old_b; const UINT vals[]={TRUE,FALSE}; unsigned int i; + ICONMETRICSA im;
/* These tests hang when XFree86 4.0 for Windows is running (tested on * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is @@ -814,19 +1003,28 @@ for (i=0;i<sizeof(vals)/sizeof(*vals);i++) { UINT v; + UINT regval;
rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError()); test_change_message( SPI_SETICONTITLEWRAP, 1 ); - test_reg_key_ex( SPI_SETICONTITLEWRAP_REGKEY1, - SPI_SETICONTITLEWRAP_REGKEY2, - SPI_SETICONTITLEWRAP_VALNAME, - vals[i] ? "1" : "0" ); + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, + SPI_SETICONTITLEWRAP_VALNAME, dpi); + if( regval != vals[i]) + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, + SPI_SETICONTITLEWRAP_VALNAME, dpi); + ok( regval == vals[i], + "wrong value in registry %d, expected %d\n", regval, vals[i] );
rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 ); ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError()); eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" ); + /* and test with what SPI_GETICONMETRICS returns */ + im.cbSize = sizeof(ICONMETRICSA); + rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" ); }
rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE ); @@ -1011,7 +1209,7 @@ rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEBUTTONSWAP")) - return; + break;
test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 ); test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY, @@ -1019,6 +1217,10 @@ vals[i] ? "1" : "0" ); eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i], "SM_SWAPBUTTON", "%d" ); + rc=SwapMouseButton((BOOL)vals[i^1]); + eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1], + "SwapMouseButton", "%d" ); + ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc ); }
rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, old_b, 0, @@ -1078,9 +1280,179 @@ ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); }
+#define test_reg_metric( KEY, VAL, val) \ +{ INT regval;\ + regval = metricfromreg( KEY, VAL, dpi);\ + ok( regval==val, "wrong value "%s" in registry %d, expected %d\n", VAL, regval, val);\ +} + +#define test_reg_metric2( KEY1, KEY2, VAL, val) \ +{ INT regval;\ + regval = metricfromreg( KEY1, VAL, dpi);\ + if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\ + ok( regval==val, "wrong value "%s" in registry %d, expected %d\n", VAL, regval, val);\ +} + +#define test_reg_font( KEY, VAL, LF) \ +{ LOGFONTA lfreg;\ + lffromreg( KEY, VAL, &lfreg);\ + ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == lfreg.lfHeight :\ + MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\ + (LF).lfWidth == lfreg.lfWidth &&\ + (LF).lfWeight == lfreg.lfWeight &&\ + !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\ + , "wrong value "%s" in registry %ld, %ld\n", VAL, (LF).lfHeight, lfreg.lfHeight);\ +} + +#define TEST_NONCLIENTMETRICS_REG( ncm) \ +test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\ +/*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont); + +/* get text metric height value for the specified logfont */ +static int get_tmheight( LOGFONTA *plf, int flag) +{ + TEXTMETRICA tm; + HFONT hfont = CreateFontIndirectA( plf); + hfont = SelectObject( hdc, hfont); + GetTextMetricsA( hdc, &tm); + hfont = SelectObject( hdc, hfont); + return tm.tmHeight + (flag ? tm.tmExternalLeading : 0); +} + +void test_GetSystemMetrics( void); + +static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */ +{ + BOOL rc; + INT expect; + NONCLIENTMETRICSA Ncmorig; + NONCLIENTMETRICSA Ncmnew; + NONCLIENTMETRICSA Ncmcur; + NONCLIENTMETRICSA Ncmstart; + + Ncmorig.cbSize = sizeof(NONCLIENTMETRICSA); + Ncmnew.cbSize = sizeof(NONCLIENTMETRICSA); + Ncmcur.cbSize = sizeof(NONCLIENTMETRICSA); + Ncmstart.cbSize = sizeof(NONCLIENTMETRICSA); + + trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n"); + SetLastError(0xdeadbeef); + rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmorig, FALSE ); + if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS")) + return; + Ncmstart = Ncmorig; + /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if + the caption font height is higher than the CaptionHeight field, + the latter is adjusted accordingly. To be able to restore these setting + accurately be restore the raw values. */ + Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, dpi); + Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi); + Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi); + Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi); + /* test registry entries */ + TEST_NONCLIENTMETRICS_REG( Ncmorig) + /* make small changes */ + Ncmnew = Ncmstart; + Ncmnew.iBorderWidth += 1; + Ncmnew.iScrollWidth += 1; + Ncmnew.iScrollHeight -= 1; + Ncmnew.iCaptionWidth -= 2; + Ncmnew.iCaptionHeight += 2; + Ncmnew.lfCaptionFont.lfHeight +=1; + Ncmnew.lfCaptionFont.lfWidth +=2; + Ncmnew.lfCaptionFont.lfWeight +=1; + Ncmnew.iSmCaptionWidth += 1; + Ncmnew.iSmCaptionHeight += 2; + Ncmnew.lfSmCaptionFont.lfHeight +=3; + Ncmnew.lfSmCaptionFont.lfWidth -=1; + Ncmnew.lfSmCaptionFont.lfWeight +=3; + Ncmnew.iMenuWidth += 1; + Ncmnew.iMenuHeight += 2; + Ncmnew.lfMenuFont.lfHeight +=1; + Ncmnew.lfMenuFont.lfWidth +=1; + Ncmnew.lfMenuFont.lfWeight +=2; + Ncmnew.lfStatusFont.lfHeight -=1; + Ncmnew.lfStatusFont.lfWidth -=1; + Ncmnew.lfStatusFont.lfWeight +=3; + Ncmnew.lfMessageFont.lfHeight -=2; + Ncmnew.lfMessageFont.lfWidth -=1; + Ncmnew.lfMessageFont.lfWeight +=4; + + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE| + SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_SETNONCLIENTMETRICS, 1 ); + /* get them back */ + rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmcur, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* test registry entries */ + TEST_NONCLIENTMETRICS_REG( Ncmcur) + /* test the systemm metrics with these settings */ + test_GetSystemMetrics(); + /* now for something invalid: increase the {menu|caption|smcaption} fonts + by a large amount will increase the {menu|caption|smcaption} height*/ + Ncmnew = Ncmstart; + Ncmnew.lfMenuFont.lfHeight -= 8; + Ncmnew.lfCaptionFont.lfHeight =-4; + Ncmnew.lfSmCaptionFont.lfHeight -=10; + /* also show that a few values are lo limited */ + Ncmnew.iCaptionWidth = 0; + Ncmnew.iCaptionHeight = 0; + Ncmnew.iScrollHeight = 0; + Ncmnew.iScrollWidth = 0; + + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE| + SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_SETNONCLIENTMETRICS, 1 ); + /* raw values are in registry */ + TEST_NONCLIENTMETRICS_REG( Ncmnew) + /* get them back */ + rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmcur, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* cooked values are returned */ + expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1)); + ok( Ncmcur.iMenuHeight == expect, + "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect); + expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0)); + ok( Ncmcur.iCaptionHeight == expect, + "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect); + expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0)); + ok( Ncmcur.iSmCaptionHeight == expect, + "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect); + + ok( Ncmcur.iCaptionWidth == 8 || + Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */ + "CaptionWidth: %d expected 8\n", Ncmcur.iCaptionWidth); + ok( Ncmcur.iScrollWidth == 8, + "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth); + ok( Ncmcur.iScrollHeight == 8, + "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight); + /* test the systemm metrics with these settings */ + test_GetSystemMetrics(); + /* restore */ + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), + &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); + test_change_message( SPI_SETNONCLIENTMETRICS, 0 ); + ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); +} + static void test_SPI_SETMINIMIZEDMETRICS( void ) /* 44 */ { BOOL rc; + INT regval; MINIMIZEDMETRICS lpMm_orig; MINIMIZEDMETRICS lpMm_new; MINIMIZEDMETRICS lpMm_cur; @@ -1094,23 +1466,49 @@ rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE ); if (!test_error_msg(rc,"SPI_{GET,SET}MINIMIZEDMETRICS")) return; - + /* test registry */ + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi); + ok( regval == lpMm_orig.iWidth, "wrong value in registry %d, expected %d\n", + regval, lpMm_orig.iWidth); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi); + ok( regval == lpMm_orig.iHorzGap, "wrong value in registry %d, expected %d\n", + regval, lpMm_orig.iHorzGap); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi); + ok( regval == lpMm_orig.iVertGap, "wrong value in registry %d, expected %d\n", + regval, lpMm_orig.iVertGap); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi); + ok( regval == lpMm_orig.iArrange, "wrong value in registry %d, expected %d\n", + regval, lpMm_orig.iArrange); + /* set some new values */ lpMm_cur.iWidth = 180; lpMm_cur.iHorzGap = 1; lpMm_cur.iVertGap = 1; lpMm_cur.iArrange = 5; - - rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_cur, FALSE ); - ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - + rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), + &lpMm_cur, SPIF_UPDATEINIFILE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* read them back */ rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE ); ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - + /* and compare */ eq( lpMm_new.iWidth, lpMm_cur.iWidth, "iWidth", "%d" ); eq( lpMm_new.iHorzGap, lpMm_cur.iHorzGap, "iHorzGap", "%d" ); eq( lpMm_new.iVertGap, lpMm_cur.iVertGap, "iVertGap", "%d" ); eq( lpMm_new.iArrange, lpMm_cur.iArrange, "iArrange", "%d" ); - + /* test registry */ + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi); + ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iWidth); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi); + ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iHorzGap); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi); + ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iVertGap); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi); + ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iArrange); + /* test some system metrics */ eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6, lpMm_new.iWidth, "iWidth", "%d" ); eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ), @@ -1119,13 +1517,53 @@ lpMm_new.iVertGap, "iVertGap", "%d" ); eq( GetSystemMetrics( SM_ARRANGE ), lpMm_new.iArrange, "iArrange", "%d" ); - - rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE ); - ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); - + /* now some realy invalid settings */ + lpMm_cur.iWidth = -1; + lpMm_cur.iHorzGap = -1; + lpMm_cur.iVertGap = -1; + lpMm_cur.iArrange = - 1; + rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), + &lpMm_cur, SPIF_UPDATEINIFILE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* read back */ rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE ); ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - + /* the width and H/V gaps have minimum 0, arrange is and'd with 0xf */ + eq( lpMm_new.iWidth, 0, "iWidth", "%d" ); + eq( lpMm_new.iHorzGap, 0, "iHorzGap", "%d" ); + eq( lpMm_new.iVertGap, 0, "iVertGap", "%d" ); + eq( lpMm_new.iArrange, 0xf & lpMm_cur.iArrange, "iArrange", "%d" ); + /* test registry */ +#if 0 /* FIXME: cannot understand the results of this (11, 11, 11, 0) */ + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi); + ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iWidth); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi); + ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iHorzGap); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi); + ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iVertGap); + regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi); + ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n", + regval, lpMm_new.iArrange); +#endif + /* test some system metrics */ + eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6, + lpMm_new.iWidth, "iWidth", "%d" ); + eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ), + lpMm_new.iHorzGap, "iHorzGap", "%d" ); + eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ), + lpMm_new.iVertGap, "iVertGap", "%d" ); + eq( GetSystemMetrics( SM_ARRANGE ), + lpMm_new.iArrange, "iArrange", "%d" ); + /* restore */ + rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), + &lpMm_orig, SPIF_UPDATEINIFILE ); + ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); + /* check that */ + rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); eq( lpMm_new.iWidth, lpMm_orig.iWidth, "iWidth", "%d" ); eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" ); eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" ); @@ -1134,10 +1572,12 @@
static void test_SPI_SETICONMETRICS( void ) /* 46 */ { - BOOL rc; + BOOL rc, wrap; + INT spacing; ICONMETRICSA im_orig; ICONMETRICSA im_new; ICONMETRICSA im_cur; + INT regval;
im_orig.cbSize = sizeof(ICONMETRICSA); im_new.cbSize = sizeof(ICONMETRICSA); @@ -1148,33 +1588,50 @@ rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE ); if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS")) return; - - im_cur.iHorzSpacing = 65; - im_cur.iVertSpacing = 65; - im_cur.iTitleWrap = 0; - im_cur.lfFont.lfHeight = 1; - im_cur.lfFont.lfWidth = 1; + /* check some registry values */ + regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi); + ok( regval==im_orig.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing); + regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi); + ok( regval==im_orig.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing); + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi); + if( regval != im_orig.iTitleWrap) + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi); + ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap); + + /* change everything without creating something invalid ( Win9x would ignore + * an invalid font for instance) */ + im_cur = im_orig; + im_cur.iHorzSpacing += 10; + im_cur.iVertSpacing += 6; + im_cur.iTitleWrap = !im_cur.iTitleWrap; + im_cur.lfFont.lfHeight += 1; + im_cur.lfFont.lfWidth += 2; im_cur.lfFont.lfEscapement = 1; - im_cur.lfFont.lfWeight = 1; - im_cur.lfFont.lfItalic = 1; - im_cur.lfFont.lfStrikeOut = 1; - im_cur.lfFont.lfUnderline = 1; - im_cur.lfFont.lfCharSet = 1; - im_cur.lfFont.lfOutPrecision = 1; - im_cur.lfFont.lfClipPrecision = 1; - im_cur.lfFont.lfPitchAndFamily = 1; - im_cur.lfFont.lfQuality = 1; - - rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, FALSE ); + im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314; + im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic; + im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut; + im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline; + im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1; + im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ? + OUT_TT_PRECIS : OUT_DEFAULT_PRECIS; + im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES; + im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1; + im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ? + DRAFT_QUALITY : DEFAULT_QUALITY; + if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif")) + strcpy( im_cur.lfFont.lfFaceName, "MS Serif"); + else + strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif"); + + rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE ); ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError());
rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE ); ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); - + /* test GET <-> SETICONMETRICS */ eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" ); eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" ); eq( im_new.iTitleWrap, im_cur.iTitleWrap, "iTitleWrap", "%d" ); - eq( im_new.lfFont.lfHeight, im_cur.lfFont.lfHeight, "lfHeight", "%ld" ); eq( im_new.lfFont.lfWidth, im_cur.lfFont.lfWidth, "lfWidth", "%ld" ); eq( im_new.lfFont.lfEscapement, im_cur.lfFont.lfEscapement, "lfEscapement", "%ld" ); @@ -1187,13 +1644,38 @@ eq( im_new.lfFont.lfClipPrecision, im_cur.lfFont.lfClipPrecision, "lfClipPrecision", "%d" ); eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" ); eq( im_new.lfFont.lfQuality, im_cur.lfFont.lfQuality, "lfQuality", "%d" ); - + ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName), + "wrong facename "%s", should be "%s"\n", im_new.lfFont.lfFaceName, + im_cur.lfFont.lfFaceName); + /* test some system metrics */ eq( GetSystemMetrics( SM_CXICONSPACING ), im_new.iHorzSpacing, "iHorzSpacing", "%d" ); eq( GetSystemMetrics( SM_CYICONSPACING ), im_new.iVertSpacing, "iVertSpacing", "%d" ); - - rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE ); + /* check some registry values */ + regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi); + ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing); + regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi); + ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing); + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi); + if( regval != im_cur.iTitleWrap) + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi); + ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap); + /* test some values from other SPI_GETxxx calls */ + rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 ); + ok( rc && spacing == im_cur.iHorzSpacing, + "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n", + spacing, im_cur.iHorzSpacing); + rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 ); + ok( rc && spacing == im_cur.iVertSpacing, + "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n", + spacing, im_cur.iVertSpacing); + rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 ); + ok( rc && wrap == im_cur.iTitleWrap, + "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n", + wrap, im_cur.iTitleWrap); + /* restore old values */ + rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE ); ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError());
rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE ); @@ -1314,7 +1796,7 @@
rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 ); ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError()); - eq( v, vals[i], "SPI_GETKEYBOARDPREF", "%d" ); + eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" ); }
rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, old_b, 0, SPIF_UPDATEINIFILE ); @@ -1348,10 +1830,45 @@
rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 ); ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError()); - eq( v, vals[i], "SPI_GETSCREENREADER", "%d" ); + eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" ); }
rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE ); + ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); +} + +static void test_SPI_SETFONTSMOOTHING( void ) /* 75 */ +{ + BOOL rc; + BOOL old_b; + const UINT vals[]={0xffffffff,0,1,2}; + unsigned int i; + + trace("testing SPI_{GET,SET}FONTSMOOTHING\n"); + if( iswin9x) return; /* 95/98/ME don't seem to implement this fully */ + SetLastError(0xdeadbeef); + rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 ); + if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING")) + return; + + for (i=0;i<sizeof(vals)/sizeof(*vals);i++) + { + UINT v; + + rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0, + SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); + ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError()); + test_change_message( SPI_SETFONTSMOOTHING, 0 ); + test_reg_key( SPI_SETFONTSMOOTHING_REGKEY, + SPI_SETFONTSMOOTHING_VALNAME, + vals[i] ? "2" : "0" ); + + rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 ); + ok(rc!=0,"%d: rc=%d err=%ld\n",i,rc,GetLastError()); + eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" ); + } + + rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE ); ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); }
@@ -1655,8 +2172,7 @@ { test_SPI_SETBEEP(); /* 1 */ test_SPI_SETMOUSE(); /* 4 */ - /* Messes up systems settings on Win9x */ - /*test_SPI_SETBORDER();*/ /* 6 */ + test_SPI_SETBORDER(); /* 6 */ test_SPI_SETKEYBOARDSPEED(); /* 10 */ test_SPI_ICONHORIZONTALSPACING(); /* 13 */ test_SPI_SETSCREENSAVETIMEOUT(); /* 14 */ @@ -1672,12 +2188,14 @@ test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */ test_SPI_SETFASTTASKSWITCH(); /* 36 */ test_SPI_SETDRAGFULLWINDOWS(); /* 37 */ + test_SPI_SETNONCLIENTMETRICS(); /* 42 */ test_SPI_SETMINIMIZEDMETRICS(); /* 44 */ test_SPI_SETICONMETRICS(); /* 46 */ test_SPI_SETWORKAREA(); /* 47 */ test_SPI_SETSHOWSOUNDS(); /* 57 */ test_SPI_SETKEYBOARDPREF(); /* 69 */ test_SPI_SETSCREENREADER(); /* 71 */ + test_SPI_SETFONTSMOOTHING(); /* 75 */ test_SPI_SETLOWPOWERACTIVE(); /* 85 */ test_SPI_SETPOWEROFFACTIVE(); /* 86 */ test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */ @@ -1690,6 +2208,227 @@ return 0; }
+/* test calculation of GetSystemMetrics values (mostly) from non client metrics, + * icon metrics and minimized metrics. + */ + +/* copied from wine's GdiGetCharDimensions, which is not available on most + * windows versions */ +static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height) +{ + SIZE sz; + static const CHAR alphabet[] = { + 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q', + 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0}; + + if(lptm && !GetTextMetricsA(hdc, lptm)) return 0; + + if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0; + + if (height) *height = sz.cy; + return (sz.cx / 26 + 1) / 2; +} + +/* get text metrics and/or "average" char width of the specified logfont + * for the specified dc */ +void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz) +{ + HFONT hfont, hfontsav; + TEXTMETRICA tm; + if( !ptm) ptm = &tm; + hfont = CreateFontIndirectA( plf); + if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) { + ptm->tmHeight = -1; + if( psz) *psz = 10; + if( hfont) DeleteObject( hfont); + return; + } + GetTextMetricsA( hdc, ptm); + if( psz) + if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL))) + *psz = 10; + SelectObject( hdc, hfontsav); + DeleteObject( hfont); +} + +static int gsm_error_ctr; +static UINT smcxsmsize = 999999999; + +#define ok_gsm( i, e)\ +{\ + int exp = (e);\ + int act = GetSystemMetrics( (i));\ + if( exp != act) gsm_error_ctr++;\ + ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\ +} +#define ok_gsm_2( i, e1, e2)\ +{\ + int exp1 = (e1);\ + int exp2 = (e2);\ + int act = GetSystemMetrics( (i));\ + if( exp1 != act && exp2 != act) gsm_error_ctr++;\ + ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\ +} +#define ok_gsm_3( i, e1, e2, e3)\ +{\ + int exp1 = (e1);\ + int exp2 = (e2);\ + int exp3 = (e3);\ + int act = GetSystemMetrics( (i));\ + if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\ + ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\ +} + +void test_GetSystemMetrics( void) +{ + TEXTMETRICA tmMenuFont; + UINT IconSpacing, IconVerticalSpacing; + + HDC hdc = CreateIC( "Display", 0, 0, 0); + UINT avcwCaption; + INT CaptionWidth; + MINIMIZEDMETRICS minim; + NONCLIENTMETRICS ncm; + minim.cbSize = sizeof( minim); + ncm.cbSize = sizeof( ncm); + SystemParametersInfo( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0); + SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); + + /* CaptionWidth from the registry may have different value of iCaptionWidth + * from the non client metrics (observed on WinXP) */ + CaptionWidth = metricfromreg( + "Control Panel\Desktop\WindowMetrics","CaptionWidth", dpi); + get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL); + get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption); + /* FIXME: use icon metric */ + if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0)) + IconVerticalSpacing = 0; + if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 )) + IconSpacing = 0; + /* reset error counters */ + gsm_error_ctr = 0; + + /* the tests: */ + + /* SM_CXSCREEN, cannot test these two */ + /* SM_CYSCREEN */ + ok_gsm( SM_CXVSCROLL, ncm.iScrollWidth); + ok_gsm( SM_CYHSCROLL, ncm.iScrollWidth); + ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1); + ok_gsm( SM_CXBORDER, 1); + ok_gsm( SM_CYBORDER, 1); + ok_gsm( SM_CXDLGFRAME, 3); + ok_gsm( SM_CYDLGFRAME, 3); + ok_gsm( SM_CYVTHUMB, ncm.iScrollHeight); + ok_gsm( SM_CXHTHUMB, ncm.iScrollHeight); + /* SM_CXICON */ + /* SM_CYICON */ + /* SM_CXCURSOR */ + /* SM_CYCURSOR */ + ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1); + ok_gsm( SM_CXFULLSCREEN, + GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME)); + ok_gsm( SM_CYFULLSCREEN, + GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN)); + /* SM_CYKANJIWINDOW */ + /* SM_MOUSEPRESENT */ + ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight); + ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight); + /* SM_DEBUG */ + /* SM_SWAPBUTTON */ + /* SM_RESERVED1 */ + /* SM_RESERVED2 */ + /* SM_RESERVED3 */ + /* SM_RESERVED4 */ + ok_gsm( SM_CXMIN, 3 * max( CaptionWidth, 8) + GetSystemMetrics( SM_CYSIZE) + + 4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME)); + ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) + + 2 * GetSystemMetrics( SM_CYFRAME)); + ok_gsm_2( SM_CXSIZE, + ncm.iCaptionWidth, /* classic/standard windows style */ + GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */ + ); + ok_gsm( SM_CYSIZE, ncm.iCaptionHeight); + ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3); + ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3); + ok_gsm( SM_CXMINTRACK, GetSystemMetrics( SM_CXMIN)); + ok_gsm( SM_CYMINTRACK, GetSystemMetrics( SM_CYMIN)); + /* SM_CXDOUBLECLK */ + /* SM_CYDOUBLECLK */ + if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing); + if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing); + /* SM_MENUDROPALIGNMENT */ + /* SM_PENWINDOWS */ + /* SM_DBCSENABLED */ + /* SM_CMOUSEBUTTONS */ + /* SM_SECURE */ + ok_gsm( SM_CXEDGE, 2); + ok_gsm( SM_CYEDGE, 2); + ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + minim.iHorzGap ); + ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + minim.iVertGap ); + /* SM_CXSMICON */ + /* SM_CYSMICON */ + ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1); + ok_gsm_3( SM_CXSMSIZE, + ncm.iSmCaptionWidth, /* classic/standard windows style */ + GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */ + smcxsmsize /* winXP seems to cache this value: setnonclientmetric + does not change it */ + ); + ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1); + ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth); + ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight); + /* SM_ARRANGE */ + ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6); + ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5); + ok_gsm( SM_CXMAXTRACK, GetSystemMetrics( SM_CXSCREEN) + + 4 + 2 * GetSystemMetrics( SM_CXFRAME)); + ok_gsm( SM_CYMAXTRACK, GetSystemMetrics( SM_CYSCREEN) + + 4 + 2 * GetSystemMetrics( SM_CYFRAME)); + /* the next two cannot really be tested as they depend on (application) + * toolbars */ + /* SM_CXMAXIMIZED */ + /* SM_CYMAXIMIZED */ + /* SM_NETWORK */ + /* */ + /* */ + /* */ + /* SM_CLEANBOOT */ + /* SM_CXDRAG */ + /* SM_CYDRAG */ + /* SM_SHOWSOUNDS */ + ok_gsm( SM_CXMENUCHECK, + ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1); + ok_gsm( SM_CYMENUCHECK, + ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1); + /* SM_SLOWMACHINE */ + /* SM_MIDEASTENABLED */ + /* SM_MOUSEWHEELPRESENT */ + /* SM_XVIRTUALSCREEN */ + /* SM_YVIRTUALSCREEN */ + /* SM_CXVIRTUALSCREEN */ + /* SM_CYVIRTUALSCREEN */ + /* SM_CMONITORS */ + /* SM_SAMEDISPLAYFORMAT */ + /* SM_IMMENABLED */ + /* SM_CXFOCUSBORDER */ + /* SM_CYFOCUSBORDER */ + /* SM_TABLETPC */ + /* SM_MEDIACENTER */ + /* SM_CMETRICS */ + /* end of tests */ + if( gsm_error_ctr ) { /* if any errors where found */ + trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n", + ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing); + trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n", + ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth); + trace( "Captionfontchar width %d MenuFont %ld,%ld CaptionWidth from registry: %d\n", + avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidth); + } + ReleaseDC( 0, hdc); +} + START_TEST(sysparams) { int argc; @@ -1700,6 +2439,10 @@ DWORD dwThreadId; HANDLE hInstance = GetModuleHandleA( NULL );
+ hdc = GetDC(0); + dpi = GetDeviceCaps( hdc, LOGPIXELSY); + iswin9x = GetVersion() & 0x80000000; + /* This test requires interactivity, if we don't have it, give up */ if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) && GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return; @@ -1707,6 +2450,9 @@ argc = winetest_get_mainargs(&argv); strict=(argc >= 3 && strcmp(argv[2],"strict")==0); trace("strict=%d\n",strict); + + trace("testing GetSystemMetrics with your current desktop settings\n"); + test_GetSystemMetrics( );
change_counter = 0; change_last_param = 0; @@ -1734,4 +2480,6 @@ TranslateMessage( &msg ); DispatchMessageA( &msg ); } -} + ReleaseDC( 0, hdc); + +}
Propchange: trunk/reactos/regtests/winetests/user32/sysparams.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/testlist.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/te... ============================================================================== --- trunk/reactos/regtests/winetests/user32/testlist.c (original) +++ trunk/reactos/regtests/winetests/user32/testlist.c Wed Apr 5 06:34:10 2006 @@ -22,6 +22,7 @@ extern void func_input(void); extern void func_listbox(void); extern void func_menu(void); +extern void func_monitor(void); extern void func_msg(void); extern void func_resource(void); extern void func_sysparams(void); @@ -41,6 +42,7 @@ { "input", func_input }, { "listbox", func_listbox }, { "menu", func_menu }, + { "monitor", func_monitor }, { "msg", func_msg }, { "resource", func_resource }, { "sysparams", func_sysparams },
Propchange: trunk/reactos/regtests/winetests/user32/testlist.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/text.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/te... ============================================================================== --- trunk/reactos/regtests/winetests/user32/text.c (original) +++ trunk/reactos/regtests/winetests/user32/text.c Wed Apr 5 06:34:10 2006 @@ -36,6 +36,9 @@ LOGFONTA lf; const char text[] = "Example text for testing DrawText in " "MM_HIENGLISH mode"; + const WCHAR textW[] = {'W','i','d','e',' ','c','h','a','r',' ', + 's','t','r','i','n','g','\0'}; + const WCHAR emptystringW[] = { 0 }; INT textlen,textheight; RECT rect = { 0, 0, 100, 0 }; BOOL ret; @@ -100,6 +103,49 @@ "should return a positive rectangle bottom. (bot=%ld)\n", rect.bottom);
+ /* empty or null text should in some cases calc an empty rectangle */ + /* note: testing the function's return value is useless, it differs + * ( 0 or 1) on every Windows version I tried */ + SetRect( &rect, 10,10, 100, 100); + textheight = DrawTextExA(hdc, (char *) text, 0, &rect, DT_CALCRECT, NULL ); + ok( !(rect.left == rect.right && rect.bottom == rect.top), + "rectangle should NOT be empty.\n"); + SetRect( &rect, 10,10, 100, 100); + SetLastError( 0); + textheight = DrawTextExA(hdc, "", -1, &rect, DT_CALCRECT, NULL ); + ok( (rect.left == rect.right && rect.bottom == rect.top), + "rectangle should be empty.\n"); + SetRect( &rect, 10,10, 100, 100); + SetLastError( 0); + textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL ); + ok( (rect.left == rect.right && rect.bottom == rect.top), + "rectangle should be empty.\n"); + SetRect( &rect, 10,10, 100, 100); + textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL ); + ok( !(rect.left == rect.right && rect.bottom == rect.top), + "rectangle should NOT be empty.\n"); + + /* Wide char versions */ + SetRect( &rect, 10,10, 100, 100); + SetLastError( 0); + textheight = DrawTextExW(hdc, (WCHAR *) textW, 0, &rect, DT_CALCRECT, NULL ); + if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) { + ok( !(rect.left == rect.right && rect.bottom == rect.top), + "rectangle should NOT be empty.\n"); + SetRect( &rect, 10,10, 100, 100); + textheight = DrawTextExW(hdc, (WCHAR *) emptystringW, -1, &rect, DT_CALCRECT, NULL ); + ok( (rect.left == rect.right && rect.bottom == rect.top), + "rectangle should be empty.\n"); + SetRect( &rect, 10,10, 100, 100); + textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL ); + ok( !(rect.left == rect.right && rect.bottom == rect.top), + "rectangle should NOT be empty.\n"); + SetRect( &rect, 10,10, 100, 100); + textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL ); + ok( !(rect.left == rect.right && rect.bottom == rect.top), + "rectangle should NOT be empty.\n"); + } + SelectObject(hdc, hOldFont); ret = DeleteObject(hFont); ok( ret, "DeleteObject error %lu\n", GetLastError()); @@ -111,7 +157,97 @@ ok( ret, "DestroyWindow error %lu\n", GetLastError()); }
+/* replace tabs by \t */ +static void strfmt( char *str, char *strout) +{ + unsigned int i,j ; + for(i=0,j=0;i<=strlen(str);i++,j++) + if((strout[j]=str[i])=='\t') { + strout[j++]='\'; + strout[j]='t'; + } +} + + +#define TABTEST( tabval, tabcount, string, _exp) \ +{ int i,x_act, x_exp; char strdisp[64];\ + for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \ + extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \ + strfmt( string, strdisp); \ + /* trace( "Extent is %08lx\n", extent); */\ + x_act = LOWORD( extent); \ + x_exp = (_exp); \ + ok( x_act == x_exp, "Test case "%s". Text extent is %d, expected %d tab %d tabcount %d\n", \ + strdisp, x_act, x_exp, tabval, tabcount); \ +} \ + + +static void test_TabbedText(void) +{ + HWND hwnd; + HDC hdc; + BOOL ret; + TEXTMETRICA tm; + DWORD extent; + INT tabs[8], cx, cy, tab, tabcount,t,align; + + /* Initialization */ + hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, + 0, 0, 200, 200, 0, 0, 0, NULL); + ok(hwnd != 0, "CreateWindowExA error %lu\n", GetLastError()); + hdc = GetDC(hwnd); + ok(hdc != 0, "GetDC error %lu\n", GetLastError()); + + ret = GetTextMetricsA( hdc, &tm); + ok( ret, "GetTextMetrics error %lu\n", GetLastError()); + + extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs); + cx = LOWORD( extent); + cy = HIWORD( extent); + trace( "cx is %d cy is %d\n", cx, cy); + + align=1; + for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to + catch the one off errors */ + tab = (cx *4 + t); + /* test the special case tabcount =1 and the general array (80 of tabs */ + for( tabcount = 1; tabcount <= 8; tabcount +=7) { + TABTEST( align * tab, tabcount, "\t", tab) + TABTEST( align * tab, tabcount, "xxx\t", tab) + TABTEST( align * tab, tabcount, "\tx", tab+cx) + TABTEST( align * tab, tabcount, "\t\t", tab*2) + TABTEST( align * tab, tabcount, "\tx\t", tab*2) + TABTEST( align * tab, tabcount, "x\tx", tab+cx) + TABTEST( align * tab, tabcount, "xx\tx", tab+cx) + TABTEST( align * tab, tabcount, "xxx\tx", tab+cx) + TABTEST( align * tab, tabcount, "xxxx\tx", t>0 ? tab + cx : 2*tab+cx) + TABTEST( align * tab, tabcount, "xxxxx\tx", 2*tab+cx) + } + } + align=-1; + for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to + catch the one off errors */ + tab = (cx *4 + t); + /* test the special case tabcount =1 and the general array (8) of tabs */ + for( tabcount = 1; tabcount <= 8; tabcount +=7) { + TABTEST( align * tab, tabcount, "\t", tab) + TABTEST( align * tab, tabcount, "xxx\t", tab) + TABTEST( align * tab, tabcount, "\tx", tab) + TABTEST( align * tab, tabcount, "\t\t", tab*2) + TABTEST( align * tab, tabcount, "\tx\t", tab*2) + TABTEST( align * tab, tabcount, "x\tx", tab) + TABTEST( align * tab, tabcount, "xx\tx", tab) + TABTEST( align * tab, tabcount, "xxx\tx", 4 * cx >= tab ? 2*tab :tab) + TABTEST( align * tab, tabcount, "xxxx\tx", 2*tab) + TABTEST( align * tab, tabcount, "xxxxx\tx", 2*tab) + } + } + + +} + START_TEST(text) { + test_TabbedText(); test_DrawTextCalcRect(); }
Propchange: trunk/reactos/regtests/winetests/user32/text.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/user32.rbuild URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/us... ============================================================================== --- trunk/reactos/regtests/winetests/user32/user32.rbuild (original) +++ trunk/reactos/regtests/winetests/user32/user32.rbuild Wed Apr 5 06:34:10 2006 @@ -4,6 +4,8 @@ <library>ntdll</library> <library>user32</library> <library>gdi32</library> + <library>advapi32</library> + <library>kernel32</library> <file>class.c</file> <file>clipboard.c</file> <file>dce.c</file> @@ -13,6 +15,7 @@ <file>input.c</file> <file>listbox.c</file> <file>menu.c</file> + <file>monitor.c</file> <file>msg.c</file> <file>resource.c</file> <file>sysparams.c</file>
Propchange: trunk/reactos/regtests/winetests/user32/user32.rbuild ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/win.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/wi... ============================================================================== --- trunk/reactos/regtests/winetests/user32/win.c (original) +++ trunk/reactos/regtests/winetests/user32/win.c Wed Apr 5 06:34:10 2006 @@ -42,6 +42,8 @@ #define SPI_GETDESKWALLPAPER 0x0073 #endif
+#define MAKEINTATOMA(atom) ((LPCSTR)((ULONG_PTR)((WORD)(atom)))) + #define LONG_PTR INT_PTR #define ULONG_PTR UINT_PTR
@@ -60,6 +62,21 @@
#define COUNTOF(arr) (sizeof(arr)/sizeof(arr[0]))
+/* try to make sure pending X events have been processed before continuing */ +static void flush_events(void) +{ + MSG msg; + int diff = 100; + DWORD time = GetTickCount() + diff; + + while (diff > 0) + { + MsgWaitForMultipleObjects( 0, NULL, FALSE, diff, QS_ALLINPUT ); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + diff = time - GetTickCount(); + } +} + /* check the values returned by the various parent/owner functions on a given window */ static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_parent, HWND gw_owner, HWND ga_root, HWND ga_root_owner ) @@ -71,7 +88,7 @@ res = pGetAncestor( hwnd, GA_PARENT ); ok( res == ga_parent, "Wrong result for GA_PARENT %p expected %p\n", res, ga_parent ); } - res = (HWND)GetWindowLongA( hwnd, GWL_HWNDPARENT ); + res = (HWND)GetWindowLongPtrA( hwnd, GWLP_HWNDPARENT ); ok( res == gwl_parent, "Wrong result for GWL_HWNDPARENT %p expected %p\n", res, gwl_parent ); res = GetParent( hwnd ); ok( res == get_parent, "Wrong result for GetParent %p expected %p\n", res, get_parent ); @@ -86,6 +103,21 @@ } }
+BOOL CALLBACK EnumChildProc( HWND hwndChild, LPARAM lParam) +{ + (*(LPINT)lParam)++; + trace("EnumChildProc on %p\n", hwndChild); + if (*(LPINT)lParam > 1) return FALSE; + return TRUE; +} + +/* will search for the given window */ +BOOL CALLBACK EnumChildProc1( HWND hwndChild, LPARAM lParam) +{ + trace("EnumChildProc1 on %p\n", hwndChild); + if ((HWND)lParam == hwndChild) return FALSE; + return TRUE; +}
static HWND create_tool_window( LONG style, HWND parent ) { @@ -102,6 +134,7 @@ HWND test, owner, ret; HWND desktop = GetDesktopWindow(); HWND child = create_tool_window( WS_CHILD, hwndMain ); + INT numChildren;
trace( "main window %p main2 %p desktop %p child %p\n", hwndMain, hwndMain2, desktop, child );
@@ -300,24 +333,24 @@ test = create_tool_window( WS_CHILD, hwndMain ); trace( "created child %p\n", test );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 ); ok( ret == hwndMain, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain ); check_parents( test, hwndMain2, hwndMain2, hwndMain2, 0, hwndMain2, hwndMain2 );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child ); ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 ); check_parents( test, child, child, child, 0, hwndMain, hwndMain );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)desktop ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)desktop ); ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child ); check_parents( test, desktop, 0, desktop, 0, test, desktop );
- /* window is now child of desktop so GWL_HWNDPARENT changes owner from now on */ - ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child ); + /* window is now child of desktop so GWLP_HWNDPARENT changes owner from now on */ + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child ); ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret ); check_parents( test, desktop, child, desktop, child, test, desktop );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, 0 ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, 0 ); ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child ); check_parents( test, desktop, 0, desktop, 0, test, desktop ); DestroyWindow( test ); @@ -326,15 +359,15 @@ test = create_tool_window( 0, 0 ); trace( "created top-level %p\n", test );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 ); ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret ); check_parents( test, desktop, hwndMain2, 0, hwndMain2, test, test );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child ); ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 ); check_parents( test, desktop, child, 0, child, test, test );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, 0 ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, 0 ); ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child ); check_parents( test, desktop, 0, 0, 0, test, test ); DestroyWindow( test ); @@ -343,15 +376,15 @@ test = create_tool_window( WS_POPUP, 0 ); trace( "created popup %p\n", test );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)hwndMain2 ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)hwndMain2 ); ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret ); check_parents( test, desktop, hwndMain2, hwndMain2, hwndMain2, test, hwndMain2 );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (LONG_PTR)child ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (LONG_PTR)child ); ok( ret == hwndMain2, "GWL_HWNDPARENT return value %p expected %p\n", ret, hwndMain2 ); check_parents( test, desktop, child, child, child, test, hwndMain );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, 0 ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, 0 ); ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child ); check_parents( test, desktop, 0, 0, 0, test, test ); DestroyWindow( test ); @@ -390,7 +423,7 @@ ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop ); check_parents( test, child, child, hwndMain2, hwndMain2, hwndMain, hwndMain2 );
- ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (ULONG_PTR)hwndMain ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (ULONG_PTR)hwndMain ); ok( ret == child, "GWL_HWNDPARENT return value %p expected %p\n", ret, child ); check_parents( test, hwndMain, hwndMain, hwndMain2, hwndMain2, hwndMain, hwndMain2 ); DestroyWindow( test ); @@ -426,7 +459,7 @@ owner = create_tool_window( WS_CHILD, hwndMain2 ); test = create_tool_window( WS_POPUP, 0 ); trace( "created owner %p and popup %p\n", owner, test ); - ret = (HWND)SetWindowLongA( test, GWL_HWNDPARENT, (ULONG_PTR)owner ); + ret = (HWND)SetWindowLongPtrA( test, GWLP_HWNDPARENT, (ULONG_PTR)owner ); ok( ret == 0, "GWL_HWNDPARENT return value %p expected 0\n", ret ); check_parents( test, desktop, owner, owner, owner, test, hwndMain2 ); DestroyWindow( owner ); @@ -440,6 +473,69 @@
/* final cleanup */ DestroyWindow(child); + + + owner = create_tool_window( WS_OVERLAPPED, 0 ); + test = create_tool_window( WS_POPUP, desktop ); + + ok( !GetWindow( test, GW_OWNER ), "Wrong owner window\n" ); + numChildren = 0; + ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ), + "EnumChildWindows should have returned FALSE\n" ); + ok( numChildren == 0, "numChildren should be 0 got %d\n", numChildren ); + + SetWindowLongA( test, GWL_STYLE, (GetWindowLongA( test, GWL_STYLE ) & ~WS_POPUP) | WS_CHILD ); + ret = SetParent( test, owner ); + ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop ); + + numChildren = 0; + ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ), + "EnumChildWindows should have returned TRUE\n" ); + ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren ); + + child = create_tool_window( WS_CHILD, owner ); + numChildren = 0; + ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ), + "EnumChildWindows should have returned FALSE\n" ); + ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren ); + DestroyWindow( child ); + + child = create_tool_window( WS_VISIBLE | WS_OVERLAPPEDWINDOW, owner ); + ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" ); + numChildren = 0; + ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ), + "EnumChildWindows should have returned TRUE\n" ); + ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren ); + + ret = SetParent( child, owner ); + ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" ); + ok( ret == desktop, "SetParent return value %p expected %p\n", ret, desktop ); + numChildren = 0; + ok( !EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ), + "EnumChildWindows should have returned FALSE\n" ); + ok( numChildren == 2, "numChildren should be 2 got %d\n", numChildren ); + + ret = SetParent( child, NULL ); + ok( GetWindow( child, GW_OWNER ) == owner, "Wrong owner window\n" ); + ok( ret == owner, "SetParent return value %p expected %p\n", ret, owner ); + numChildren = 0; + ok( EnumChildWindows( owner, EnumChildProc, (LPARAM)&numChildren ), + "EnumChildWindows should have returned TRUE\n" ); + ok( numChildren == 1, "numChildren should be 1 got %d\n", numChildren ); + + /* even GW_OWNER == owner it's still a desktop's child */ + ok( !EnumChildWindows( desktop, EnumChildProc1, (LPARAM)child ), + "EnumChildWindows should have found %p and returned FALSE\n", child ); + + DestroyWindow( child ); + child = create_tool_window( WS_VISIBLE | WS_OVERLAPPEDWINDOW, NULL ); + + ok( !EnumChildWindows( desktop, EnumChildProc1, (LPARAM)child ), + "EnumChildWindows should have found %p and returned FALSE\n", child ); + + DestroyWindow( child ); + DestroyWindow( test ); + DestroyWindow( owner ); }
@@ -459,7 +555,7 @@ minmax->ptMaxPosition.x, minmax->ptMaxPosition.y, minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y, minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y); - SetWindowLongA(hwnd, GWL_USERDATA, 0x20031021); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021); break; } case WM_WINDOWPOSCHANGING: @@ -516,7 +612,7 @@ } case WM_NCCREATE: { - BOOL got_getminmaxinfo = GetWindowLongA(hwnd, GWL_USERDATA) == 0x20031021; + BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021; CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
trace("WM_NCCREATE: hwnd %p, parent %p, style %08lx\n", hwnd, cs->hwndParent, cs->style); @@ -554,12 +650,12 @@ minmax->ptMaxPosition.x, minmax->ptMaxPosition.y, minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y, minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y); - SetWindowLongA(hwnd, GWL_USERDATA, 0x20031021); + SetWindowLongPtrA(hwnd, GWLP_USERDATA, 0x20031021); break; } case WM_NCCREATE: { - BOOL got_getminmaxinfo = GetWindowLongA(hwnd, GWL_USERDATA) == 0x20031021; + BOOL got_getminmaxinfo = GetWindowLongPtrA(hwnd, GWLP_USERDATA) == 0x20031021; CREATESTRUCTA *cs = (CREATESTRUCTA *)lparam;
trace("WM_NCCREATE: hwnd %p, parent %p, style %08lx\n", hwnd, cs->hwndParent, cs->style); @@ -670,7 +766,7 @@ DWORD style, exstyle; RECT rc_window, rc_client, rc; BOOL menu; - BOOL is_win9x = GetWindowLongW(hwnd, GWL_WNDPROC) == 0; + BOOL is_win9x = GetWindowLongPtrW(hwnd, GWLP_WNDPROC) == 0;
style = GetWindowLongA(hwnd, GWL_STYLE); exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE); @@ -973,14 +1069,14 @@ mdi_cs.lParam = (LPARAM)mdi_lParam_test_message; mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
mdi_cs.style = 0x7fffffff; /* without WS_POPUP */ mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -993,7 +1089,7 @@ else { ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n"); } @@ -1014,7 +1110,7 @@ } else { - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n"); } @@ -1026,7 +1122,7 @@ mdi_client, GetModuleHandle(0), (LPARAM)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1037,7 +1133,7 @@ mdi_client, GetModuleHandle(0), (LPARAM)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1054,7 +1150,7 @@ else { ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n"); } @@ -1076,7 +1172,7 @@ } else { - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n"); } @@ -1088,7 +1184,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1099,7 +1195,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n");
@@ -1116,7 +1212,7 @@ else { ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n"); } @@ -1138,7 +1234,7 @@ } else { - ok(GetWindowLongA(mdi_child, GWL_ID) == first_id, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == first_id, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child, 0); ok(!IsWindow(mdi_child), "WM_MDIDESTROY failed\n"); } @@ -1162,7 +1258,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == 0, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); DestroyWindow(mdi_child);
mdi_child = CreateWindowExA(0, "MDI_child_Class_2", "MDI child", @@ -1172,7 +1268,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == 0, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); DestroyWindow(mdi_child);
/* maximized child */ @@ -1183,7 +1279,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == 0, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); DestroyWindow(mdi_child);
trace("Creating maximized child with a caption\n"); @@ -1194,7 +1290,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == 0, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); DestroyWindow(mdi_child);
trace("Creating maximized child with a caption and a thick frame\n"); @@ -1205,7 +1301,7 @@ mdi_client, 0, GetModuleHandle(0), (LPVOID)mdi_lParam_test_message); ok(mdi_child != 0, "MDI child creation failed\n"); - ok(GetWindowLongA(mdi_child, GWL_ID) == 0, "wrong child id %ld\n", GetWindowLongA(mdi_child, GWL_ID)); + ok(GetWindowLongPtrA(mdi_child, GWLP_ID) == 0, "wrong child id %ld\n", GetWindowLongPtrA(mdi_child, GWLP_ID)); DestroyWindow(mdi_child); }
@@ -1860,8 +1956,18 @@
for (i = 0; i < total; i++) { - child[i] = CreateWindowExA(0, "static", "", style[i], 0,0,10,10, - parent, 0, 0, NULL); + if (style[i] & DS_CONTROL) + { + child[i] = CreateWindowExA(0, MAKEINTATOMA(32770), "", style[i] & ~WS_VISIBLE, + 0,0,0,0, parent, (HMENU)i, 0, NULL); + if (style[i] & WS_VISIBLE) + ShowWindow(child[i], SW_SHOW); + + SetWindowPos(child[i], HWND_BOTTOM, 0,0,10,10, SWP_NOACTIVATE); + } + else + child[i] = CreateWindowExA(0, "static", "", style[i], 0,0,10,10, + parent, (HMENU)i, 0, NULL); trace("child[%d] = %p\n", i, child[i]); ok(child[i] != 0, "CreateWindowEx failed to create child window\n"); } @@ -1897,6 +2003,10 @@ const int complex_order_3[3] = { 1, 0, 2 }; const int complex_order_4[4] = { 1, 0, 2, 3 }; const int complex_order_5[5] = { 4, 1, 0, 2, 3 }; + const DWORD complex_style_6[3] = { WS_CHILD | WS_VISIBLE, + WS_CHILD | WS_CLIPSIBLINGS | DS_CONTROL | WS_VISIBLE, + WS_CHILD | WS_VISIBLE }; + const int complex_order_6[3] = { 0, 1, 2 };
/* simple WS_CHILD */ test_window_tree(parent, simple_style, simple_order, 5); @@ -1907,6 +2017,38 @@ test_window_tree(parent, complex_style, complex_order_3, 3); test_window_tree(parent, complex_style, complex_order_4, 4); test_window_tree(parent, complex_style, complex_order_5, 5); + + /* another set of complex children styles */ + test_window_tree(parent, complex_style_6, complex_order_6, 3); +} + +static void test_vis_rgn( HWND hwnd ) +{ + RECT win_rect, rgn_rect; + HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 ); + HDC hdc; + + ShowWindow(hwnd,SW_SHOW); + hdc = GetDC( hwnd ); + ok( GetRandomRgn( hdc, hrgn, SYSRGN ) != 0, "GetRandomRgn failed\n" ); + GetWindowRect( hwnd, &win_rect ); + GetRgnBox( hrgn, &rgn_rect ); + if (GetVersion() & 0x80000000) + { + trace("win9x, mapping to screen coords\n"); + MapWindowPoints( hwnd, 0, (POINT *)&rgn_rect, 2 ); + } + trace("win: %ld,%ld-%ld,%ld\n", win_rect.left, win_rect.top, win_rect.right, win_rect.bottom ); + trace("rgn: %ld,%ld-%ld,%ld\n", rgn_rect.left, rgn_rect.top, rgn_rect.right, rgn_rect.bottom ); + ok( win_rect.left <= rgn_rect.left, "rgn left %ld not inside win rect %ld\n", + rgn_rect.left, win_rect.left ); + ok( win_rect.top <= rgn_rect.top, "rgn top %ld not inside win rect %ld\n", + rgn_rect.top, win_rect.top ); + ok( win_rect.right >= rgn_rect.right, "rgn right %ld not inside win rect %ld\n", + rgn_rect.right, win_rect.right ); + ok( win_rect.bottom >= rgn_rect.bottom, "rgn bottom %ld not inside win rect %ld\n", + rgn_rect.bottom, win_rect.bottom ); + ReleaseDC( hwnd, hdc ); }
static void test_SetFocus(HWND hwnd) @@ -2144,6 +2286,8 @@
static void test_capture_3(HWND hwnd1, HWND hwnd2) { + BOOL ret; + ShowWindow(hwnd1, SW_HIDE); ShowWindow(hwnd2, SW_HIDE);
@@ -2159,7 +2303,10 @@ ShowWindow(hwnd1, SW_SHOW); check_wnd_state(hwnd1, hwnd1, hwnd1, hwnd2);
- ReleaseCapture(); + ret = ReleaseCapture(); + ok (ret, "releasecapture did not return TRUE.\n"); + ret = ReleaseCapture(); + ok (ret, "releasecapture did not return TRUE after second try.\n"); }
static void test_keyboard_input(HWND hwnd) @@ -2169,6 +2316,7 @@
ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); + flush_events();
ok(GetActiveWindow() == hwnd, "wrong active window %p\n", GetActiveWindow());
@@ -2235,6 +2383,7 @@ HWND popup; MSG msg; BOOL ret; + LRESULT res;
ShowWindow(hwnd, SW_SHOW); UpdateWindow(hwnd); @@ -2344,6 +2493,39 @@ ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "no message available\n"); ok(msg.hwnd == popup && msg.message == WM_LBUTTONUP, "hwnd %p message %04x\n", msg.hwnd, msg.message); ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "no message available\n"); + + /* Test WM_MOUSEACTIVATE */ +#define TEST_MOUSEACTIVATE(A,B) \ + res = SendMessageA(hwnd, WM_MOUSEACTIVATE, (WPARAM)hwnd, (LPARAM)MAKELRESULT(A,0)); \ + ok(res == B, "WM_MOUSEACTIVATE for %s returned %ld\n", #A, res); + + TEST_MOUSEACTIVATE(HTERROR,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTTRANSPARENT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTNOWHERE,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTCLIENT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTCAPTION,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTSYSMENU,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTSIZE,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTMENU,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTHSCROLL,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTVSCROLL,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTMINBUTTON,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTMAXBUTTON,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTLEFT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTRIGHT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTTOP,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTTOPLEFT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTTOPRIGHT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTBOTTOM,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTBOTTOMLEFT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTBOTTOMRIGHT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTBORDER,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTOBJECT,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTCLOSE,MA_ACTIVATE); + TEST_MOUSEACTIVATE(HTHELP,MA_ACTIVATE); + + /* Clear any messages left behind by WM_MOUSEACTIVATE tests */ + while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
DestroyWindow(popup); } @@ -2649,6 +2831,9 @@ * hwnd2 because of the WS_CLIPSIBLING style */ HWND hwnd1, hwnd2;
+ clipping = CreateRectRgn(0,0,0,0); + tmprgn = CreateRectRgn(0,0,0,0); + exprgn = CreateRectRgn(0,0,0,0); hwnd2 = CreateWindowExA(0, "static", NULL, WS_CHILD| WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER , 75, 30, 100, 100, parent, 0, 0, NULL); @@ -2659,17 +2844,17 @@ UpdateWindow( parent); GetClientRect( hwnd1, &rc); cliprc=rc; - clipping = CreateRectRgn( 10, 10, 90, 90); + SetRectRgn( clipping, 10, 10, 90, 90); hdc = GetDC( hwnd1); /* for a visual touch */ TextOut( hdc, 0,10, "0123456789", 10); ScrollDC( hdc, -10, -5, &rc, &cliprc, hrgn, &rcu); if (winetest_debug > 0) dump_region(hrgn); /* create a region with what is expected */ - exprgn = CreateRectRgn( 39,0,49,74); - tmprgn = CreateRectRgn( 88,79,98,93); + SetRectRgn( exprgn, 39,0,49,74); + SetRectRgn( tmprgn, 88,79,98,93); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); - tmprgn = CreateRectRgn( 0,93,98,98); + SetRectRgn( tmprgn, 0,93,98,98); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); ok( EqualRgn( exprgn, hrgn), "wrong update region\n"); trace("update rect is %ld,%ld - %ld,%ld\n", @@ -2679,10 +2864,10 @@ ScrollDC( hdc, -10, -5, &rc, &cliprc, hrgn, &rcu); if (winetest_debug > 0) dump_region(hrgn); /* create a region with what is expected */ - exprgn = CreateRectRgn( 39,10,49,74); - tmprgn = CreateRectRgn( 80,79,90,85); + SetRectRgn( exprgn, 39,10,49,74); + SetRectRgn( tmprgn, 80,79,90,85); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); - tmprgn = CreateRectRgn( 10,85,90,90); + SetRectRgn( tmprgn, 10,85,90,90); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); ok( EqualRgn( exprgn, hrgn), "wrong update region\n"); trace("update rect is %ld,%ld - %ld,%ld\n", @@ -2699,8 +2884,8 @@ ScrollWindowEx( hwnd1, -10, 0, &rc, &cliprc, hrgn, &rcu, SW_SCROLLCHILDREN | SW_INVALIDATE); if (winetest_debug > 0) dump_region(hrgn); - exprgn = CreateRectRgn( 88,0,98,98); - tmprgn = CreateRectRgn( 30, 40, 50, 50); + SetRectRgn( exprgn, 88,0,98,98); + SetRectRgn( tmprgn, 30, 40, 50, 50); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); ok( EqualRgn( exprgn, hrgn), "wrong update region\n");
@@ -2721,8 +2906,8 @@ ScrollWindowEx( hwnd1, -10, -10, &rc, &cliprc, hrgn, &rcu, SW_SCROLLCHILDREN | SW_INVALIDATE); if (winetest_debug > 0) dump_region(hrgn); - exprgn = CreateRectRgn( 88,0,98,88); - tmprgn = CreateRectRgn( 0,88,98,98); + SetRectRgn( exprgn, 88,0,98,88); + SetRectRgn( tmprgn, 0,88,98,98); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); ok( EqualRgn( exprgn, hrgn), "wrong update region\n");
@@ -2750,12 +2935,12 @@ ValidateRect( hwnd2, NULL); ScrollWindowEx( hwnd1, -10, -10, &rc, &cliprc, hrgn, &rcu, SW_INVALIDATE); if (winetest_debug > 0) dump_region(hrgn); - exprgn = CreateRectRgn( 88,0,98,20); - tmprgn = CreateRectRgn( 20,20,98,30); + SetRectRgn( exprgn, 88,0,98,20); + SetRectRgn( tmprgn, 20,20,98,30); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); - tmprgn = CreateRectRgn( 20,30,30,88); + SetRectRgn( tmprgn, 20,30,30,88); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); - tmprgn = CreateRectRgn( 0,88,30,98); + SetRectRgn( tmprgn, 0,88,30,98); CombineRgn( exprgn, exprgn, tmprgn, RGN_OR); ok( EqualRgn( exprgn, hrgn), "wrong update region\n");
@@ -2803,14 +2988,97 @@ DestroyWindow( hwnd); }
+static void test_scrolldc( HWND parent) +{ + HDC hdc; + HRGN exprgn, tmprgn, hrgn; + RECT rc, rc2, rcu, cliprc; + HWND hwnd1; + COLORREF colr; + + hrgn = CreateRectRgn(0,0,0,0); + tmprgn = CreateRectRgn(0,0,0,0); + exprgn = CreateRectRgn(0,0,0,0); + + hwnd1 = CreateWindowExA(0, "static", NULL, + WS_CHILD| WS_VISIBLE, + 25, 50, 100, 100, parent, 0, 0, NULL); + ShowWindow( parent, SW_SHOW); + UpdateWindow( parent); + GetClientRect( hwnd1, &rc); + hdc = GetDC( hwnd1); + /* paint the upper half of the window black */ + rc2 = rc; + rc2.bottom = ( rc.top + rc.bottom) /2; + FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH)); + /* clip region is the lower half */ + cliprc=rc; + cliprc.top = (rc.top + rc.bottom) /2; + /* test whether scrolled pixels are properly clipped */ + colr = GetPixel( hdc, (rc.left+rc.right)/2, ( rc.top + rc.bottom) /2 - 1); + ok ( colr == 0, "pixel should be black, color is %08lx\n", colr); + /* this scroll should not cause any visible changes */ + ScrollDC( hdc, 5, -20, &rc, &cliprc, hrgn, &rcu); + colr = GetPixel( hdc, (rc.left+rc.right)/2, ( rc.top + rc.bottom) /2 - 1); + ok ( colr == 0, "pixel should be black, color is %08lx\n", colr); + /* test with NULL clip rect */ + ScrollDC( hdc, 20, -20, &rc, NULL, hrgn, &rcu); + /*FillRgn(hdc, hrgn, GetStockObject(WHITE_BRUSH));*/ + trace("update rect: %ld,%ld - %ld,%ld\n", + rcu.left, rcu.top, rcu.right, rcu.bottom); + if (winetest_debug > 0) dump_region(hrgn); + SetRect(&rc2, 0, 0, 100, 100); + ok(EqualRect(&rcu, &rc2), "rects do not match (%ld,%ld-%ld,%ld) / (%ld,%ld-%ld,%ld)\n", + rcu.left, rcu.top, rcu.right, rcu.bottom, rc2.left, rc2.top, rc2.right, rc2.bottom); + + SetRectRgn( exprgn, 0, 0, 20, 80); + SetRectRgn( tmprgn, 0, 80, 100, 100); + CombineRgn(exprgn, exprgn, tmprgn, RGN_OR); + if (winetest_debug > 0) dump_region(exprgn); + ok(EqualRgn(exprgn, hrgn), "wrong update region\n"); + /* test clip rect > scroll rect */ + FillRect( hdc, &rc, GetStockObject(WHITE_BRUSH)); + rc2=rc; + InflateRect( &rc2, -(rc.right-rc.left)/4, -(rc.bottom-rc.top)/4); + FillRect( hdc, &rc2, GetStockObject(BLACK_BRUSH)); + ScrollDC( hdc, 10, 10, &rc2, &rc, hrgn, &rcu); + SetRectRgn( exprgn, 25, 25, 75, 35); + SetRectRgn( tmprgn, 25, 35, 35, 75); + CombineRgn(exprgn, exprgn, tmprgn, RGN_OR); + ok(EqualRgn(exprgn, hrgn), "wrong update region\n"); + colr = GetPixel( hdc, 80, 80); + ok ( colr == 0, "pixel should be black, color is %08lx\n", colr); + trace("update rect: %ld,%ld - %ld,%ld\n", + rcu.left, rcu.top, rcu.right, rcu.bottom); + if (winetest_debug > 0) dump_region(hrgn); + + /* clean up */ + DeleteObject(hrgn); + DeleteObject(exprgn); + DeleteObject(tmprgn); + DestroyWindow(hwnd1); +} + static void test_params(void) { + HWND hwnd; INT rc;
/* Just a param check */ SetLastError(0xdeadbeef); rc = GetWindowText(hwndMain2, NULL, 1024); ok( rc==0, "GetWindowText: rc=%d err=%ld\n",rc,GetLastError()); + + SetLastError(0xdeadbeef); + hwnd=CreateWindow("LISTBOX", "TestList", + (LBS_STANDARD & ~LBS_SORT), + 0, 0, 100, 100, + NULL, (HMENU)1, NULL, 0); + + ok(!hwnd, "CreateWindow with invalid menu handle should fail\n"); + ok(GetLastError() == ERROR_INVALID_MENU_HANDLE || /* NT */ + GetLastError() == 0xdeadbeef, /* Win9x */ + "wrong last error value %ld\n", GetLastError()); }
static void test_AWRwindow(LPCSTR class, LONG style, LONG exStyle, BOOL menu) @@ -3005,7 +3273,7 @@ RECT rc; PAINTSTRUCT ps;
- struct parentdc_stat *t = (struct parentdc_stat *)GetWindowLongPtrA(hwnd, GWL_USERDATA); + struct parentdc_stat *t = (struct parentdc_stat *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
switch (msg) { @@ -3163,16 +3431,17 @@ AdjustWindowRectEx(&rc, WS_OVERLAPPEDWINDOW, FALSE, 0); hwndMain = CreateWindowA("ParentDcMainWindowClass", "Main Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, 0, NULL); - SetWindowLongPtrA(hwndMain, GWL_USERDATA, (DWORD_PTR)&test_answer.main); + SetWindowLongPtrA(hwndMain, GWLP_USERDATA, (DWORD_PTR)&test_answer.main); hwnd1 = CreateWindowA("ParentDcWindowClass", "Child Window 1", WS_CHILD, 20, 20, 40, 40, hwndMain, NULL, 0, NULL); - SetWindowLongPtrA(hwnd1, GWL_USERDATA, (DWORD_PTR)&test_answer.child1); + SetWindowLongPtrA(hwnd1, GWLP_USERDATA, (DWORD_PTR)&test_answer.child1); hwnd2 = CreateWindowA("ParentDcWindowClass", "Child Window 2", WS_CHILD, 40, 40, 40, 40, hwndMain, NULL, 0, NULL); - SetWindowLongPtrA(hwnd2, GWL_USERDATA, (DWORD_PTR)&test_answer.child2); + SetWindowLongPtrA(hwnd2, GWLP_USERDATA, (DWORD_PTR)&test_answer.child2); ShowWindow(hwndMain, SW_SHOW); ShowWindow(hwnd1, SW_SHOW); ShowWindow(hwnd2, SW_SHOW); + flush_events();
zero_parentdc_test(&test_answer); InvalidateRect(hwndMain, NULL, TRUE); @@ -3377,6 +3646,7 @@ assert( hwndMain ); assert( hwndMain2 );
+ /* Add the tests below this line */ test_params();
test_capture_1(); @@ -3400,13 +3670,16 @@ test_validatergn(hwndMain); test_nccalcscroll( hwndMain); test_scrollvalidate( hwndMain); + test_scrolldc( hwndMain); test_scroll(); test_IsWindowUnicode(); - - UnhookWindowsHookEx(hhook); + test_vis_rgn(hwndMain);
test_AdjustWindowRect(); test_window_styles(); test_redrawnow(); test_csparentdc(); -} + + /* add the tests above this line */ + UnhookWindowsHookEx(hhook); +}
Propchange: trunk/reactos/regtests/winetests/user32/win.c ------------------------------------------------------------------------------ native = class.c
Modified: trunk/reactos/regtests/winetests/user32/winstation.c URL: http://svn.reactos.ru/svn/reactos/trunk/reactos/regtests/winetests/user32/wi... ============================================================================== --- trunk/reactos/regtests/winetests/user32/winstation.c (original) +++ trunk/reactos/regtests/winetests/user32/winstation.c Wed Apr 5 06:34:10 2006 @@ -42,12 +42,29 @@ trace( "obj %p type '%s'\n", obj, buffer ); }
+static void register_class(void) +{ + WNDCLASSA cls; + + cls.style = CS_DBLCLKS; + cls.lpfnWndProc = DefWindowProcA; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(0); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "WinStationClass"; + RegisterClassA(&cls); +} + static HDESK initial_desktop;
static DWORD CALLBACK thread( LPVOID arg ) { HDESK d1, d2; - HWND hwnd = CreateWindowExA(0,"BUTTON","test",WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0); + HWND hwnd = CreateWindowExA(0,"WinStationClass","test",WS_POPUP,0,0,100,100,GetDesktopWindow(),0,0,0); ok( hwnd != 0, "CreateWindow failed\n" ); d1 = GetThreadDesktop(GetCurrentThreadId()); trace( "thread %p desktop: %p\n", arg, d1 ); @@ -89,6 +106,8 @@ HDESK d1, d2, d3; HANDLE hthread; DWORD id, flags; + ATOM atom; + char buffer[20];
/* win stations */
@@ -143,6 +162,28 @@
w3 = OpenWindowStation("foobar", TRUE, WINSTA_ALL_ACCESS ); ok( !w3, "open foobar station succeeded\n" ); + + w2 = CreateWindowStation("foobar1", 0, WINSTA_ALL_ACCESS, NULL ); + ok( w2 != 0, "create foobar station failed\n" ); + w3 = CreateWindowStation("foobar2", 0, WINSTA_ALL_ACCESS, NULL ); + ok( w3 != 0, "create foobar station failed\n" ); + ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); + ok( GetHandleInformation( w3, &flags ), "GetHandleInformation failed\n" ); + + SetProcessWindowStation( w2 ); + register_class(); + atom = GlobalAddAtomA("foo"); + ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" ); + ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer ); + + ok( !CloseWindowStation( w2 ), "CloseWindowStation succeeded\n" ); + ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); + + SetProcessWindowStation( w3 ); + ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" ); + ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" ); + ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" ); + ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );
/* desktops */ d1 = GetThreadDesktop(GetCurrentThreadId());
Propchange: trunk/reactos/regtests/winetests/user32/winstation.c ------------------------------------------------------------------------------ native = class.c
Propchange: trunk/reactos/regtests/winetests/user32/wsprintf.c ------------------------------------------------------------------------------ native = class.c