[USER32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912

svn path=/trunk/; revision=70979
This commit is contained in:
Amine Khaldi 2016-03-09 09:25:21 +00:00
parent 98e06283e7
commit a0ab4941f0
14 changed files with 2073 additions and 192 deletions

View file

@ -24,29 +24,89 @@
#include "wingdi.h"
#include "winuser.h"
static BOOL is_win9x = FALSE;
#define WM_CLIPBOARDUPDATE 0x031D
#define test_last_error(expected_error) \
do \
{ \
if (!is_win9x) \
ok(GetLastError() == expected_error, \
"Last error should be set to %d, not %d\n", \
expected_error, GetLastError()); \
} while (0)
static BOOL (WINAPI *pAddClipboardFormatListener)(HWND hwnd);
static DWORD (WINAPI *pGetClipboardSequenceNumber)(void);
static int thread_from_line;
static DWORD WINAPI open_clipboard_thread(LPVOID arg)
{
HWND hWnd = arg;
ok(OpenClipboard(hWnd), "OpenClipboard second time in the same hwnd failed\n");
ok(OpenClipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line);
return 0;
}
static DWORD WINAPI empty_clipboard_thread(LPVOID arg)
{
SetLastError( 0xdeadbeef );
ok(!EmptyClipboard(), "%u: EmptyClipboard succeeded\n", thread_from_line );
ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
thread_from_line, GetLastError());
return 0;
}
static DWORD WINAPI open_and_empty_clipboard_thread(LPVOID arg)
{
HWND hWnd = arg;
ok(OpenClipboard(hWnd), "%u: OpenClipboard failed\n", thread_from_line);
ok(EmptyClipboard(), "%u: EmptyClipboard failed\n", thread_from_line );
return 0;
}
static DWORD WINAPI set_clipboard_data_thread(LPVOID arg)
{
HWND hwnd = arg;
HANDLE ret;
SetLastError( 0xdeadbeef );
if (GetClipboardOwner() == hwnd)
{
SetClipboardData( CF_WAVE, 0 );
todo_wine ok( IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData failed\n", thread_from_line );
ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
ok( ret != 0, "%u: SetClipboardData failed err %u\n", thread_from_line, GetLastError() );
}
else
{
SetClipboardData( CF_WAVE, 0 );
todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
thread_from_line, GetLastError());
ok( !IsClipboardFormatAvailable( CF_WAVE ), "%u: SetClipboardData succeeded\n", thread_from_line );
ret = SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 ));
todo_wine ok( !ret, "%u: SetClipboardData succeeded\n", thread_from_line );
todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "%u: wrong error %u\n",
thread_from_line, GetLastError());
}
return 0;
}
static void run_thread( LPTHREAD_START_ROUTINE func, void *arg, int line )
{
DWORD ret;
HANDLE thread;
thread_from_line = line;
thread = CreateThread(NULL, 0, func, arg, 0, NULL);
ok(thread != NULL, "%u: CreateThread failed with error %d\n", line, GetLastError());
for (;;)
{
ret = MsgWaitForMultipleObjectsEx( 1, &thread, 1000, QS_ALLINPUT, 0 );
if (ret == WAIT_OBJECT_0 + 1)
{
MSG msg;
while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageW( &msg );
}
else break;
}
ok(ret == WAIT_OBJECT_0, "%u: expected WAIT_OBJECT_0, got %u\n", line, ret);
CloseHandle(thread);
}
static void test_ClipboardOwner(void)
{
HANDLE thread;
HWND hWnd1, hWnd2;
DWORD dwret;
BOOL ret;
SetLastError(0xdeadbeef);
@ -71,16 +131,16 @@ static void test_ClipboardOwner(void)
ok(OpenClipboard(0), "OpenClipboard failed\n");
ok(!GetClipboardOwner(), "clipboard should still be not owned\n");
ok(!OpenClipboard(hWnd1), "OpenClipboard should fail since clipboard already opened\n");
ok(OpenClipboard(0), "OpenClipboard again failed\n");
ret = CloseClipboard();
ok( ret, "CloseClipboard error %d\n", GetLastError());
ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
thread = CreateThread(NULL, 0, open_clipboard_thread, hWnd1, 0, NULL);
ok(thread != NULL, "CreateThread failed with error %d\n", GetLastError());
dwret = WaitForSingleObject(thread, 1000);
ok(dwret == WAIT_OBJECT_0, "expected WAIT_OBJECT_0, got %u\n", dwret);
CloseHandle(thread);
ok(OpenClipboard(hWnd1), "OpenClipboard second time in the same hwnd failed\n");
run_thread( open_clipboard_thread, hWnd1, __LINE__ );
run_thread( empty_clipboard_thread, 0, __LINE__ );
run_thread( set_clipboard_data_thread, hWnd1, __LINE__ );
ok(!CloseClipboard(), "CloseClipboard should fail if clipboard wasn't open\n");
ok(OpenClipboard(hWnd1), "OpenClipboard failed\n");
SetLastError(0xdeadbeef);
ret = OpenClipboard(hWnd2);
@ -92,6 +152,8 @@ static void test_ClipboardOwner(void)
ret = EmptyClipboard();
ok( ret, "EmptyClipboard error %d\n", GetLastError());
ok(GetClipboardOwner() == hWnd1, "clipboard should be owned by %p, not by %p\n", hWnd1, GetClipboardOwner());
run_thread( empty_clipboard_thread, 0, __LINE__ );
run_thread( set_clipboard_data_thread, hWnd1, __LINE__ );
SetLastError(0xdeadbeef);
ret = OpenClipboard(hWnd2);
@ -102,12 +164,54 @@ static void test_ClipboardOwner(void)
ok( ret, "CloseClipboard error %d\n", GetLastError());
ok(GetClipboardOwner() == hWnd1, "clipboard should still be owned\n");
/* any window will do, even from a different process */
ret = OpenClipboard( GetDesktopWindow() );
ok( ret, "OpenClipboard error %d\n", GetLastError());
ret = EmptyClipboard();
ok( ret, "EmptyClipboard error %d\n", GetLastError());
ok( GetClipboardOwner() == GetDesktopWindow(), "wrong owner %p/%p\n",
GetClipboardOwner(), GetDesktopWindow() );
run_thread( set_clipboard_data_thread, GetDesktopWindow(), __LINE__ );
ret = CloseClipboard();
ok( ret, "CloseClipboard error %d\n", GetLastError());
ret = OpenClipboard( hWnd1 );
ok( ret, "OpenClipboard error %d\n", GetLastError());
ret = EmptyClipboard();
ok( ret, "EmptyClipboard error %d\n", GetLastError());
ok( GetClipboardOwner() == hWnd1, "wrong owner %p/%p\n", GetClipboardOwner(), hWnd1 );
ret = CloseClipboard();
ok( ret, "CloseClipboard error %d\n", GetLastError());
ret = DestroyWindow(hWnd1);
ok( ret, "DestroyWindow error %d\n", GetLastError());
ret = DestroyWindow(hWnd2);
ok( ret, "DestroyWindow error %d\n", GetLastError());
SetLastError(0xdeadbeef);
ok(!GetClipboardOwner() && GetLastError() == 0xdeadbeef, "clipboard should not be owned\n");
ret = OpenClipboard( 0 );
ok( ret, "OpenClipboard error %d\n", GetLastError());
run_thread( set_clipboard_data_thread, 0, __LINE__ );
ret = CloseClipboard();
ok( ret, "CloseClipboard error %d\n", GetLastError());
run_thread( open_and_empty_clipboard_thread, 0, __LINE__ );
ret = OpenClipboard( 0 );
ok( ret, "OpenClipboard error %d\n", GetLastError());
run_thread( set_clipboard_data_thread, 0, __LINE__ );
ret = EmptyClipboard();
ok( ret, "EmptyClipboard error %d\n", GetLastError());
ret = CloseClipboard();
ok( ret, "CloseClipboard error %d\n", GetLastError());
SetLastError( 0xdeadbeef );
todo_wine ok( !SetClipboardData( CF_WAVE, GlobalAlloc( GMEM_DDESHARE | GMEM_ZEROINIT, 100 )),
"SetClipboardData succeeded\n" );
todo_wine ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError() );
todo_wine ok( !IsClipboardFormatAvailable( CF_WAVE ), "SetClipboardData succeeded\n" );
}
static void test_RegisterClipboardFormatA(void)
@ -117,6 +221,7 @@ static void test_RegisterClipboardFormatA(void)
char buf[256];
int len;
BOOL ret;
HANDLE handle;
format_id = RegisterClipboardFormatA("my_cool_clipboard_format");
ok(format_id > 0xc000 && format_id < 0xffff, "invalid clipboard format id %04x\n", format_id);
@ -132,7 +237,7 @@ static void test_RegisterClipboardFormatA(void)
SetLastError(0xdeadbeef);
len = GetAtomNameA((ATOM)format_id, buf, 256);
ok(len == 0, "GetAtomNameA should fail\n");
test_last_error(ERROR_INVALID_HANDLE);
ok(GetLastError() == ERROR_INVALID_HANDLE, "err %d\n", GetLastError());
todo_wine
{
@ -140,13 +245,13 @@ todo_wine
SetLastError(0xdeadbeef);
len = GlobalGetAtomNameA((ATOM)format_id, buf, 256);
ok(len == 0, "GlobalGetAtomNameA should fail\n");
test_last_error(ERROR_INVALID_HANDLE);
ok(GetLastError() == ERROR_INVALID_HANDLE, "err %d\n", GetLastError());
}
SetLastError(0xdeadbeef);
atom_id = FindAtomA("my_cool_clipboard_format");
ok(atom_id == 0, "FindAtomA should fail\n");
test_last_error(ERROR_FILE_NOT_FOUND);
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %d\n", GetLastError());
if (0)
{
@ -154,7 +259,7 @@ todo_wine
SetLastError(0xdeadbeef);
atom_id = GlobalFindAtomA("my_cool_clipboard_format");
ok(atom_id == 0, "GlobalFindAtomA should fail\n");
test_last_error(ERROR_FILE_NOT_FOUND);
ok(GetLastError() == ERROR_FILE_NOT_FOUND, "err %d\n", GetLastError());
}
for (format_id = 0; format_id < 0xffff; format_id++)
@ -171,6 +276,25 @@ todo_wine
ret = OpenClipboard(0);
ok( ret, "OpenClipboard error %d\n", GetLastError());
/* try some invalid/unregistered formats */
SetLastError( 0xdeadbeef );
handle = SetClipboardData( 0, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
ok( !handle, "SetClipboardData succeeded\n" );
ok( GetLastError() == ERROR_CLIPBOARD_NOT_OPEN, "wrong error %u\n", GetLastError());
handle = SetClipboardData( 0x1234, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError());
handle = SetClipboardData( 0x123456, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError());
handle = SetClipboardData( 0xffff8765, GlobalAlloc( GMEM_DDESHARE | GMEM_MOVEABLE, 1 ));
ok( handle != 0, "SetClipboardData failed err %d\n", GetLastError());
ok( IsClipboardFormatAvailable( 0x1234 ), "format missing\n" );
ok( IsClipboardFormatAvailable( 0x123456 ), "format missing\n" );
ok( IsClipboardFormatAvailable( 0xffff8765 ), "format missing\n" );
ok( !IsClipboardFormatAvailable( 0 ), "format available\n" );
ok( !IsClipboardFormatAvailable( 0x3456 ), "format available\n" );
ok( !IsClipboardFormatAvailable( 0x8765 ), "format available\n" );
trace("# of formats available: %d\n", CountClipboardFormats());
format_id = 0;
@ -263,12 +387,9 @@ static void test_synthesized(void)
ok(data != NULL, "couldn't get data, cf %08x\n", cf);
cf = EnumClipboardFormats(cf);
ok(cf == CF_UNICODETEXT ||
broken(cf == CF_METAFILEPICT), /* win9x and winME has no CF_UNICODETEXT */
"cf %08x\n", cf);
ok(cf == CF_UNICODETEXT, "cf %08x\n", cf);
if(cf == CF_UNICODETEXT)
cf = EnumClipboardFormats(cf);
cf = EnumClipboardFormats(cf);
ok(cf == CF_METAFILEPICT, "cf %08x\n", cf);
data = GetClipboardData(cf);
todo_wine ok(data != NULL, "couldn't get data, cf %08x\n", cf);
@ -287,9 +408,15 @@ static CRITICAL_SECTION clipboard_cs;
static HWND next_wnd;
static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
static UINT wm_drawclipboard;
static UINT wm_clipboardupdate;
static UINT wm_destroyclipboard;
LRESULT ret;
switch(msg) {
case WM_DRAWCLIPBOARD:
EnterCriticalSection(&clipboard_cs);
wm_drawclipboard++;
LeaveCriticalSection(&clipboard_cs);
break;
case WM_CHANGECBCHAIN:
@ -298,10 +425,29 @@ static LRESULT CALLBACK clipboard_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARA
else if (next_wnd)
SendMessageA(next_wnd, msg, wp, lp);
break;
case WM_DESTROYCLIPBOARD:
wm_destroyclipboard++;
ok( GetClipboardOwner() == hwnd, "WM_DESTROYCLIPBOARD owner %p\n", GetClipboardOwner() );
break;
case WM_CLIPBOARDUPDATE:
wm_clipboardupdate++;
break;
case WM_USER:
ChangeClipboardChain(hwnd, next_wnd);
PostQuitMessage(0);
break;
case WM_USER+1:
ret = wm_drawclipboard;
wm_drawclipboard = 0;
return ret;
case WM_USER+2:
ret = wm_clipboardupdate;
wm_clipboardupdate = 0;
return ret;
case WM_USER+3:
ret = wm_destroyclipboard;
wm_destroyclipboard = 0;
return ret;
}
return DefWindowProcA(hwnd, msg, wp, lp);
@ -311,24 +457,194 @@ static DWORD WINAPI clipboard_thread(void *param)
{
HWND win = param;
BOOL r;
HANDLE handle;
UINT count, old_seq = 0, seq;
if (pGetClipboardSequenceNumber) old_seq = pGetClipboardSequenceNumber();
EnterCriticalSection(&clipboard_cs);
SetLastError(0xdeadbeef);
next_wnd = SetClipboardViewer(win);
ok(GetLastError() == 0xdeadbeef, "GetLastError = %d\n", GetLastError());
LeaveCriticalSection(&clipboard_cs);
if (pAddClipboardFormatListener)
{
r = pAddClipboardFormatListener(win);
ok( r, "AddClipboardFormatListener failed err %d\n", GetLastError());
}
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( seq == old_seq, "sequence changed\n" );
}
count = SendMessageA( win, WM_USER + 1, 0, 0 );
ok( count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
r = OpenClipboard(win);
ok(r, "OpenClipboard failed: %d\n", GetLastError());
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( seq == old_seq, "sequence changed\n" );
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
r = EmptyClipboard();
ok(r, "EmptyClipboard failed: %d\n", GetLastError());
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
count = SendMessageA( win, WM_USER+3, 0, 0 );
ok( !count, "WM_DESTROYCLIPBOARD received\n" );
r = EmptyClipboard();
ok(r, "EmptyClipboard failed: %d\n", GetLastError());
/* sequence changes again, even though it was already empty */
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
count = SendMessageA( win, WM_USER+3, 0, 0 );
ok( count, "WM_DESTROYCLIPBOARD not received\n" );
handle = SetClipboardData( CF_TEXT, create_text() );
ok(handle != 0, "SetClipboardData failed: %d\n", GetLastError());
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
SetClipboardData( CF_UNICODETEXT, 0 );
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
SetClipboardData( CF_UNICODETEXT, 0 ); /* same data again */
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
EnterCriticalSection(&clipboard_cs);
r = CloseClipboard();
ok(r, "CloseClipboard failed: %d\n", GetLastError());
LeaveCriticalSection(&clipboard_cs);
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( count, "WM_DRAWCLIPBOARD not received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
r = OpenClipboard(win);
ok(r, "OpenClipboard failed: %d\n", GetLastError());
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( seq == old_seq, "sequence changed\n" );
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
SetClipboardData( CF_WAVE, 0 );
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
todo_wine ok( (int)(seq - old_seq) > 0, "sequence unchanged\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
r = CloseClipboard();
ok(r, "CloseClipboard failed: %d\n", GetLastError());
if (pGetClipboardSequenceNumber)
{
/* no synthesized format, so CloseClipboard doesn't change the sequence */
seq = pGetClipboardSequenceNumber();
todo_wine ok( seq == old_seq, "sequence changed\n" );
old_seq = seq;
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( count, "WM_DRAWCLIPBOARD not received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
todo_wine ok( count || broken(!pAddClipboardFormatListener), "WM_CLIPBOARDUPDATE not received\n" );
r = OpenClipboard(win);
ok(r, "OpenClipboard failed: %d\n", GetLastError());
r = CloseClipboard();
ok(r, "CloseClipboard failed: %d\n", GetLastError());
/* nothing changed */
if (pGetClipboardSequenceNumber)
{
seq = pGetClipboardSequenceNumber();
ok( seq == old_seq, "sequence changed\n" );
}
count = SendMessageA( win, WM_USER+1, 0, 0 );
ok( !count, "WM_DRAWCLIPBOARD received\n" );
count = SendMessageA( win, WM_USER+2, 0, 0 );
ok( !count, "WM_CLIPBOARDUPDATE received\n" );
r = OpenClipboard(0);
ok(r, "OpenClipboard failed: %d\n", GetLastError());
r = EmptyClipboard();
ok(r, "EmptyClipboard failed: %d\n", GetLastError());
r = CloseClipboard();
ok(r, "CloseClipboard failed: %d\n", GetLastError());
r = PostMessageA(win, WM_USER, 0, 0);
ok(r, "PostMessage failed: %d\n", GetLastError());
return 0;
@ -370,9 +686,10 @@ static void test_messages(void)
START_TEST(clipboard)
{
SetLastError(0xdeadbeef);
FindAtomW(NULL);
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) is_win9x = TRUE;
HMODULE mod = GetModuleHandleA( "user32" );
pAddClipboardFormatListener = (void *)GetProcAddress( mod, "AddClipboardFormatListener" );
pGetClipboardSequenceNumber = (void *)GetProcAddress( mod, "GetClipboardSequenceNumber" );
test_RegisterClipboardFormatA();
test_ClipboardOwner();

View file

@ -378,12 +378,12 @@ static void test_changesize( DWORD style)
/* first make it slightly smaller */
MoveWindow( hCombo, 10, 10, clwidth - 2, clheight - 2, TRUE);
GetClientRect( hCombo, &rc);
ok( rc.right - rc.left == clwidth - 2, "clientrect witdh is %d vs %d\n",
ok( rc.right - rc.left == clwidth - 2, "clientrect width is %d vs %d\n",
rc.right - rc.left, clwidth - 2);
ok( rc.bottom - rc.top == clheight, "clientrect height is %d vs %d\n",
rc.bottom - rc.top, clheight);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
ok( rc.right - rc.left == clwidth - 2, "drop-down rect witdh is %d vs %d\n",
ok( rc.right - rc.left == clwidth - 2, "drop-down rect width is %d vs %d\n",
rc.right - rc.left, clwidth - 2);
ok( rc.bottom - rc.top == ddheight, "drop-down rect height is %d vs %d\n",
rc.bottom - rc.top, ddheight);
@ -392,12 +392,12 @@ static void test_changesize( DWORD style)
/* new cx, cy is slightly bigger than the initial values */
MoveWindow( hCombo, 10, 10, clwidth + 2, clheight + 2, TRUE);
GetClientRect( hCombo, &rc);
ok( rc.right - rc.left == clwidth + 2, "clientrect witdh is %d vs %d\n",
ok( rc.right - rc.left == clwidth + 2, "clientrect width is %d vs %d\n",
rc.right - rc.left, clwidth + 2);
ok( rc.bottom - rc.top == clheight, "clientrect height is %d vs %d\n",
rc.bottom - rc.top, clheight);
SendMessageA(hCombo, CB_GETDROPPEDCONTROLRECT, 0, (LPARAM)&rc);
ok( rc.right - rc.left == clwidth + 2, "drop-down rect witdh is %d vs %d\n",
ok( rc.right - rc.left == clwidth + 2, "drop-down rect width is %d vs %d\n",
rc.right - rc.left, clwidth + 2);
todo_wine {
ok( rc.bottom - rc.top == clheight + 2, "drop-down rect height is %d vs %d\n",
@ -476,6 +476,8 @@ static void test_editselection(void)
/* Now what is the selection - still empty */
SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
ok(start==0, "Unexpected start position for selection %d\n", start);
ok(end==0, "Unexpected end position for selection %d\n", end);
len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
ok(HIWORD(len)==0, "Unexpected end position for selection %d\n", HIWORD(len));
@ -483,6 +485,8 @@ static void test_editselection(void)
/* Give it focus, and it gets selected */
SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
ok(start==0, "Unexpected start position for selection %d\n", start);
ok(end==6, "Unexpected end position for selection %d\n", end);
len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len));
@ -523,6 +527,8 @@ static void test_editselection(void)
/* Now what is the selection */
SendMessageA(hCombo, CB_GETEDITSEL, (WPARAM)&start, (WPARAM)&end);
ok(start==0, "Unexpected start position for selection %d\n", start);
ok(end==6, "Unexpected end position for selection %d\n", end);
len = SendMessageA(hCombo, CB_GETEDITSEL, 0,0);
ok(LOWORD(len)==0, "Unexpected start position for selection %d\n", LOWORD(len));
ok(HIWORD(len)==6, "Unexpected end position for selection %d\n", HIWORD(len));
@ -537,6 +543,107 @@ static void test_editselection(void)
DestroyWindow(hCombo);
}
static WNDPROC edit_window_proc;
static long setsel_start = 1, setsel_end = 1;
static HWND hCBN_SetFocus, hCBN_KillFocus;
static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == EM_SETSEL)
{
setsel_start = wParam;
setsel_end = lParam;
}
return CallWindowProcA(edit_window_proc, hwnd, msg, wParam, lParam);
}
static LRESULT CALLBACK test_window_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_COMMAND:
switch (HIWORD(wParam))
{
case CBN_SETFOCUS:
hCBN_SetFocus = (HWND)lParam;
break;
case CBN_KILLFOCUS:
hCBN_KillFocus = (HWND)lParam;
break;
}
break;
case WM_NEXTDLGCTL:
SetFocus((HWND)wParam);
break;
}
return CallWindowProcA(old_parent_proc, hwnd, msg, wParam, lParam);
}
static void test_editselection_focus(DWORD style)
{
BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
HWND hCombo, hEdit, hButton;
COMBOBOXINFO cbInfo;
BOOL ret;
const char wine_test[] = "Wine Test";
char buffer[16] = {0};
DWORD len;
pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
if (!pGetComboBoxInfo)
{
win_skip("GetComboBoxInfo is not available\n");
return;
}
hCombo = build_combo(style);
cbInfo.cbSize = sizeof(COMBOBOXINFO);
SetLastError(0xdeadbeef);
ret = pGetComboBoxInfo(hCombo, &cbInfo);
ok(ret, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError());
hEdit = cbInfo.hwndItem;
hButton = CreateWindowA("Button", "OK", WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON,
5, 50, 100, 20, hMainWnd, NULL,
(HINSTANCE)GetWindowLongPtrA(hMainWnd, GWLP_HINSTANCE), NULL);
old_parent_proc = (WNDPROC)SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)test_window_proc);
edit_window_proc = (WNDPROC)SetWindowLongPtrA(hEdit, GWLP_WNDPROC, (ULONG_PTR)combobox_subclass_proc);
SendMessageA(hCombo, WM_SETFOCUS, 0, (LPARAM)hEdit);
ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
todo_wine ok(setsel_end == INT_MAX, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
ok(hCBN_SetFocus == hCombo, "Wrong handle set by CBN_SETFOCUS; got %p\n", hCBN_SetFocus);
ok(GetFocus() == hEdit, "hEdit should have keyboard focus\n");
SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hButton, TRUE);
ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
todo_wine ok(setsel_end == 0, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
ok(hCBN_KillFocus == hCombo, "Wrong handle set by CBN_KILLFOCUS; got %p\n", hCBN_KillFocus);
ok(GetFocus() == hButton, "hButton should have keyboard focus\n");
SendMessageA(hCombo, WM_SETTEXT, 0, (LPARAM)wine_test);
SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hCombo, TRUE);
ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
todo_wine ok(setsel_end == INT_MAX, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
ok(hCBN_SetFocus == hCombo, "Wrong handle set by CBN_SETFOCUS; got %p\n", hCBN_SetFocus);
ok(GetFocus() == hEdit, "hEdit should have keyboard focus\n");
SendMessageA(hCombo, WM_GETTEXT, sizeof(buffer), (LPARAM)buffer);
ok(!strcmp(buffer, wine_test), "Unexpected text in edit control; got '%s'\n", buffer);
SendMessageA(hMainWnd, WM_NEXTDLGCTL, (WPARAM)hButton, TRUE);
ok(setsel_start == 0, "Unexpected EM_SETSEL start value; got %ld\n", setsel_start);
todo_wine ok(setsel_end == 0, "Unexpected EM_SETSEL end value; got %ld\n", setsel_end);
ok(hCBN_KillFocus == hCombo, "Wrong handle set by CBN_KILLFOCUS; got %p\n", hCBN_KillFocus);
ok(GetFocus() == hButton, "hButton should have keyboard focus\n");
len = SendMessageA(hCombo, CB_GETEDITSEL, 0, 0);
ok(len == 0, "Unexpected text selection; start: %u, end: %u\n", LOWORD(len), HIWORD(len));
SetWindowLongPtrA(hMainWnd, GWLP_WNDPROC, (ULONG_PTR)old_parent_proc);
DestroyWindow(hButton);
DestroyWindow(hCombo);
}
static void test_listbox_styles(DWORD cb_style)
{
BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
@ -606,6 +713,8 @@ START_TEST(combo)
test_changesize(CBS_DROPDOWN);
test_changesize(CBS_DROPDOWNLIST);
test_editselection();
test_editselection_focus(CBS_SIMPLE);
test_editselection_focus(CBS_DROPDOWN);
test_listbox_styles(CBS_SIMPLE);
test_listbox_styles(CBS_DROPDOWN);
test_listbox_styles(CBS_DROPDOWNLIST);

View file

@ -43,6 +43,15 @@ static WNDPROC old_dde_client_wndproc;
static const DWORD default_timeout = 200;
static BOOL is_cjk(void)
{
int lang_id = PRIMARYLANGID(GetUserDefaultLangID());
if (lang_id == LANG_CHINESE || lang_id == LANG_JAPANESE || lang_id == LANG_KOREAN)
return TRUE;
return FALSE;
}
static void flush_events(void)
{
MSG msg;
@ -2385,6 +2394,7 @@ static WCHAR test_cmd_w_to_w[][32] = {
{ 0x2018, 0x2019, 0x0161, 0x0041, 0x02dc, 0 }, /* some chars that should map properly to CP1252 */
{ 0x2026, 0x2020, 0x2021, 0x0d0a, 0 }, /* false negative for IsTextUnicode */
{ 0x4efa, 0x4efc, 0x0061, 0x4efe, 0 }, /* some Chinese chars */
{ 0x0061, 0x0062, 0x0063, 0x9152, 0 }, /* Chinese with latin characters begin */
};
static const int nb_callbacks = 5 + sizeof(test_cmd_w_to_w)/sizeof(test_cmd_w_to_w[0]);
@ -2457,7 +2467,7 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index);
size = DdeGetData(hdata, NULL, 0, 0);
ok((buffer = HeapAlloc(GetProcessHeap(), 0, size)) != NULL, "should not be null\n");
ok((buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size)) != NULL, "should not be null\n");
rsize = DdeGetData(hdata, buffer, size, 0);
ok(rsize == size, "Incorrect size returned, expected %d got %d, msg_index=%d\n",
size, rsize, msg_index);
@ -2545,11 +2555,47 @@ static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV
"Expected %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), msg_index);
}
break;
case 5: /* Chinese with latin characters begin */
if (unicode_server && unicode_client)
{
todo_wine ok(size == size_w, "Wrong size %d expected %d, msg_index=%d\n", size, size_w, msg_index);
MultiByteToWideChar(CP_ACP, 0, test_cmd_w_to_a, size_w, test_cmd_a_to_w,
sizeof(test_cmd_a_to_w)/sizeof(WCHAR));
todo_wine ok(!lstrcmpW((WCHAR*)buffer, cmd_w),
"Expected %s got %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), wine_dbgstr_w((WCHAR *)buffer), msg_index);
}
else if (unicode_server)
{
todo_wine ok(size == size_w, "Wrong size %d expected %d, msg_index=%d\n", size, size_w, msg_index);
MultiByteToWideChar(CP_ACP, 0, test_cmd_w_to_a, size_w, test_cmd_a_to_w,
sizeof(test_cmd_a_to_w)/sizeof(WCHAR));
if (!is_cjk())
todo_wine ok(!lstrcmpW((WCHAR*)buffer, test_cmd_a_to_w), "Expected %s, got %s, msg_index=%d\n",
wine_dbgstr_w(test_cmd_a_to_w), wine_dbgstr_w((WCHAR*)buffer), msg_index);
else
todo_wine ok(!lstrcmpW((WCHAR*)buffer, cmd_w),
"Expected %s got %s, msg_index=%d\n", wine_dbgstr_w(cmd_w), wine_dbgstr_w((WCHAR *)buffer), msg_index);
}
else if (unicode_client)
{
ok(size == size_w_to_a, "Wrong size %d expected %d, msg_index=%d\n", size, size_w_to_a, msg_index);
ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
test_cmd_w_to_a, buffer, msg_index);
}
else
{
todo_wine ok(size == size_w_to_a || size == (size_w_to_a - 1), "Wrong size %d expected %d or %d, msg_index=%d\n",
size, size_w_to_a, size_w_to_a - 1, msg_index);
todo_wine ok(!lstrcmpA((CHAR*)buffer, test_cmd_w_to_a), "Expected %s, got %s, msg_index=%d\n",
test_cmd_w_to_a, buffer, msg_index);
}
break;
default:
ok( 0, "Invalid message %u\n", msg_index );
break;
}
HeapFree(GetProcessHeap(), 0, buffer);
return (HDDEDATA) DDE_FACK;
}
case XTYP_DISCONNECT:

View file

@ -394,17 +394,8 @@ static void test_GetNextDlgItem(void)
{
HWND a;
a = (p->tab ? GetNextDlgTabItem : GetNextDlgGroupItem) (hwnd[p->dlg], hwnd[p->ctl], p->prev);
if (p->isok)
{
todo_wine_if (!p->isok)
ok (a == hwnd[p->res], "Test %d: %s %s item of %d in %d was %d instead of %d\n", p->test, p->prev ? "Prev" : "Next", p->tab ? "Tab" : "Group", p->ctl, p->dlg, id(a), p->res);
}
else
{
todo_wine
{
ok (a == hwnd[p->res], "Test %d: %s %s item of %d in %d was actually %d matching expected %d\n", p->test, p->prev ? "Prev" : "Next", p->tab ? "Tab" : "Group", p->ctl, p->dlg, id(a), p->res);
}
}
p++;
}
}
@ -795,7 +786,8 @@ static INT_PTR CALLBACK focusDlgWinProc (HWND hDlg, UINT uiMsg, WPARAM wParam,
switch (uiMsg)
{
case WM_INITDIALOG:
return TRUE;
SetWindowTextA(GetDlgItem(hDlg, 200), "new caption");
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == 200)
@ -967,6 +959,34 @@ static void test_focus(void)
DestroyWindow(hDlg);
}
/* Test 5:
* Select textbox's text on creation */
{
HWND hDlg;
HRSRC hResource;
HANDLE hTemplate;
DLGTEMPLATE* pTemplate;
HWND edit;
DWORD selectionStart = 0xdead, selectionEnd = 0xbeef;
hResource = FindResourceA(g_hinst,"FOCUS_TEST_DIALOG_3", (LPCSTR)RT_DIALOG);
hTemplate = LoadResource(g_hinst, hResource);
pTemplate = LockResource(hTemplate);
hDlg = CreateDialogIndirectParamA(g_hinst, pTemplate, NULL, focusDlgWinProc, 0);
ok(hDlg != 0, "Failed to create test dialog.\n");
edit = GetDlgItem(hDlg, 200);
ok(GetFocus() == edit, "Focus not set to edit, focus=%p, dialog=%p, edit=%p\n",
GetFocus(), hDlg, edit);
SendMessageA(edit, EM_GETSEL, (WPARAM)&selectionStart, (LPARAM)&selectionEnd);
ok(selectionStart == 0 && selectionEnd == 11,
"Text selection after WM_SETFOCUS is [%i, %i) expected [0, 11)\n",
selectionStart, selectionEnd);
DestroyWindow(hDlg);
}
}
static void test_GetDlgItemText(void)
@ -1452,12 +1472,122 @@ static void test_timer_message(void)
DialogBoxA(g_hinst, "RADIO_TEST_DIALOG", NULL, timer_message_dlg_proc);
}
struct create_window_params
{
BOOL owner;
char caption[64];
DWORD style;
};
static DWORD WINAPI create_window_thread(void *param)
{
struct create_window_params *p = param;
HWND owner = 0;
if (p->owner)
{
owner = CreateWindowExA(0, "Static", NULL, WS_POPUP, 10, 10, 10, 10, 0, 0, 0, NULL);
ok(owner != 0, "failed to create owner window\n");
}
MessageBoxA(owner, NULL, p->caption, p->style);
if (owner) DestroyWindow(owner);
return 0;
}
static HWND wait_for_window(const char *caption)
{
HWND hwnd;
DWORD timeout = 0;
for (;;)
{
hwnd = FindWindowA(NULL, caption);
if (hwnd) break;
Sleep(50);
timeout += 50;
if (timeout > 3000)
{
ok(0, "failed to wait for a window %s\n", caption);
break;
}
}
return hwnd;
}
static void test_MessageBox(void)
{
static const struct
{
DWORD mb_style;
DWORD ex_style;
} test[] =
{
{ MB_OK, 0 },
{ MB_OK | MB_TASKMODAL, 0 },
{ MB_OK | MB_SYSTEMMODAL, WS_EX_TOPMOST },
};
DWORD tid, i;
HANDLE thread;
struct create_window_params params;
sprintf(params.caption, "pid %08x, tid %08x, time %08x",
GetCurrentProcessId(), GetCurrentThreadId(), GetCurrentTime());
params.owner = FALSE;
for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
{
HWND hwnd;
DWORD ex_style;
params.style = test[i].mb_style;
thread = CreateThread(NULL, 0, create_window_thread, &params, 0, &tid);
hwnd = wait_for_window(params.caption);
ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
ok((ex_style & test[i].ex_style) == test[i].ex_style, "%d: got window ex_style %#x\n", i, ex_style);
PostMessageA(hwnd, WM_COMMAND, IDCANCEL, 0);
ok(WaitForSingleObject(thread, 5000) != WAIT_TIMEOUT, "thread failed to terminate\n");
CloseHandle(thread);
}
params.owner = TRUE;
for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
{
HWND hwnd;
DWORD ex_style;
params.style = test[i].mb_style;
thread = CreateThread(NULL, 0, create_window_thread, &params, 0, &tid);
hwnd = wait_for_window(params.caption);
ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
ok((ex_style & test[i].ex_style) == test[i].ex_style, "%d: got window ex_style %#x\n", i, ex_style);
PostMessageA(hwnd, WM_COMMAND, IDCANCEL, 0);
ok(WaitForSingleObject(thread, 5000) != WAIT_TIMEOUT, "thread failed to terminate\n");
CloseHandle(thread);
}
}
START_TEST(dialog)
{
g_hinst = GetModuleHandleA (0);
if (!RegisterWindowClasses()) assert(0);
test_MessageBox();
test_GetNextDlgItem();
test_IsDialogMessage();
test_WM_NEXTDLGCTL();

View file

@ -1635,6 +1635,9 @@ static const struct tounicode_tests
{ 0, ctrl, '^', 1, {0x1e}},
{ 0, ctrl, '_', 1, {0x1f}},
{ 0, ctrl, '`', 0, {0}},
{ VK_SPACE, 0, 0, 1, {' ',0}},
{ VK_SPACE, shift, 0, 1, {' ',0}},
{ VK_SPACE, ctrl, 0, 1, {' ',0}},
};
static void test_ToUnicode(void)

View file

@ -405,6 +405,191 @@ static void test_getmenubarinfo(void)
DestroyWindow(hwnd);
}
static void test_system_menu(void)
{
WCHAR testW[] = {'t','e','s','t',0};
BOOL ret;
HMENU menu;
HWND hwnd;
MENUITEMINFOA info;
MENUITEMINFOW infoW;
char buffer[80];
char found[0x200];
int i, res;
hwnd = CreateWindowExA(0, (LPCSTR)MAKEINTATOM(atomMenuCheckClass), NULL,
WS_SYSMENU | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
NULL, NULL, NULL, NULL);
ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
menu = GetSystemMenu( hwnd, FALSE );
ok( menu != NULL, "no system menu\n" );
for (i = 0xf000; i < 0xf200; i++)
{
memset( &info, 0xcc, sizeof(info) );
info.cbSize = sizeof(info);
info.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
info.dwTypeData = buffer;
info.cch = sizeof( buffer );
ret = GetMenuItemInfoA( menu, i, FALSE, &info );
if (ret) trace( "found %x: '%s'\n", i, buffer );
switch (i)
{
case SC_RESTORE:
case SC_SIZE:
case SC_MOVE:
case SC_MINIMIZE:
case SC_MAXIMIZE:
case SC_CLOSE:
ok( ret, "%x menu item not found\n", i );
break;
case SC_SCREENSAVE+1: /* used for the 'About Wine' entry, don't test */
break;
default:
ok( !ret, "%x menu item found\n", i );
break;
}
found[i - 0xf000] = ret;
}
for (i = 0xf000; i < 0xf200; i++)
{
res = CheckMenuItem( menu, i, 0 );
if (res == -1) ok( !found[i - 0xf000], "could not check existent item %x\n", i );
else ok( found[i - 0xf000], "could check non-existent item %x\n", i );
res = EnableMenuItem( menu, i, 0 );
if (res == -1) ok( !found[i - 0xf000], "could not enable existent item %x\n", i );
else ok( found[i - 0xf000], "could enable non-existent item %x\n", i );
res = GetMenuState( menu, i, 0 );
if (res == -1) ok( !found[i - 0xf000], "could not get state existent item %x\n", i );
else ok( found[i - 0xf000], "could get state of non-existent item %x\n", i );
if (!found[i - 0xf000]) /* don't remove the existing ones */
{
ret = RemoveMenu( menu, i, 0 );
ok( !ret, "could remove non-existent item %x\n", i );
}
ret = ModifyMenuA( menu, i, 0, i, "test" );
if (i == SC_TASKLIST) ok( ret, "failed to modify SC_TASKLIST\n" );
else if (!ret) ok( !found[i - 0xf000], "could not modify existent item %x\n", i );
else ok( found[i - 0xf000], "could modify non-existent item %x\n", i );
ret = ModifyMenuW( menu, i, 0, i, testW );
if (i == SC_TASKLIST) ok( ret, "failed to modify SC_TASKLIST\n" );
else if (!ret) ok( !found[i - 0xf000], "could not modify existent item %x\n", i );
else ok( found[i - 0xf000], "could modify non-existent item %x\n", i );
ret = ModifyMenuA( menu, i, MF_BYPOSITION, i, "test" );
ok( !ret, "could modify non-existent item %x\n", i );
strcpy( buffer, "test" );
memset( &info, 0xcc, sizeof(info) );
info.cbSize = sizeof(info);
info.fMask = MIIM_STRING | MIIM_ID;
info.wID = i;
info.dwTypeData = buffer;
info.cch = strlen( buffer );
ret = SetMenuItemInfoA( menu, i, FALSE, &info );
if (i == SC_TASKLIST) ok( ret, "failed to set SC_TASKLIST\n" );
else if (!ret) ok( !found[i - 0xf000], "could not set existent item %x\n", i );
else ok( found[i - 0xf000], "could set non-existent item %x\n", i );
ret = SetMenuItemInfoA( menu, i, TRUE, &info );
ok( !ret, "could modify non-existent item %x\n", i );
memset( &infoW, 0xcc, sizeof(infoW) );
infoW.cbSize = sizeof(infoW);
infoW.fMask = MIIM_STRING | MIIM_ID;
infoW.wID = i;
infoW.dwTypeData = testW;
infoW.cch = lstrlenW( testW );
ret = SetMenuItemInfoW( menu, i, FALSE, &infoW );
if (i == SC_TASKLIST) ok( ret, "failed to set SC_TASKLIST\n" );
else if (!ret) ok( !found[i - 0xf000], "could not set existent item %x\n", i );
else ok( found[i - 0xf000], "could set non-existent item %x\n", i );
ret = SetMenuItemInfoW( menu, i, TRUE, &infoW );
ok( !ret, "could modify non-existent item %x\n", i );
}
/* confirm that SC_TASKLIST still does not exist */
for (i = 0xf000; i < 0xf200; i++)
{
memset( &info, 0xcc, sizeof(info) );
info.cbSize = sizeof(info);
info.fMask = MIIM_STRING | MIIM_FTYPE | MIIM_ID;
info.dwTypeData = buffer;
info.cch = sizeof( buffer );
ret = GetMenuItemInfoA( menu, i, FALSE, &info );
switch (i)
{
case SC_RESTORE:
case SC_SIZE:
case SC_MOVE:
case SC_MINIMIZE:
case SC_MAXIMIZE:
case SC_CLOSE:
ok( ret, "%x menu item not found\n", i );
break;
case SC_SCREENSAVE+1: /* used for the 'About Wine' entry, don't test */
break;
default:
ok( !ret, "%x menu item found\n", i );
break;
}
}
/* now a normal (non-system) menu */
menu = CreateMenu();
ok( menu != NULL, "CreateMenu failed with error %d\n", GetLastError() );
res = CheckMenuItem( menu, SC_TASKLIST, 0 );
ok( res == -1, "CheckMenuItem succeeded\n" );
res = EnableMenuItem( menu, SC_TASKLIST, 0 );
ok( res == -1, "EnableMenuItem succeeded\n" );
res = GetMenuState( menu, SC_TASKLIST, 0 );
ok( res == -1, "GetMenuState succeeded\n" );
ret = RemoveMenu( menu, SC_TASKLIST, 0 );
ok( !ret, "RemoveMenu succeeded\n" );
ret = ModifyMenuA( menu, SC_TASKLIST, 0, SC_TASKLIST, "test" );
ok( ret, "ModifyMenuA failed err %d\n", GetLastError() );
ret = ModifyMenuW( menu, SC_TASKLIST, 0, SC_TASKLIST, testW );
ok( ret, "ModifyMenuW failed err %d\n", GetLastError() );
ret = ModifyMenuA( menu, SC_TASKLIST-1, 0, SC_TASKLIST, "test" );
ok( !ret, "ModifyMenu succeeded on SC_TASKLIST-1\n" );
strcpy( buffer, "test" );
memset( &info, 0xcc, sizeof(info) );
info.cbSize = sizeof(info);
info.fMask = MIIM_STRING | MIIM_ID;
info.wID = SC_TASKLIST;
info.dwTypeData = buffer;
info.cch = strlen( buffer );
ret = SetMenuItemInfoA( menu, SC_TASKLIST, FALSE, &info );
ok( ret, "failed to set SC_TASKLIST\n" );
ret = SetMenuItemInfoA( menu, SC_TASKLIST+1, FALSE, &info );
ok( !ret, "succeeded setting SC_TASKLIST+1\n" );
ret = SetMenuItemInfoA( menu, SC_TASKLIST, TRUE, &info );
ok( !ret, "succeeded setting by position\n" );
memset( &infoW, 0xcc, sizeof(infoW) );
infoW.cbSize = sizeof(infoW);
infoW.fMask = MIIM_STRING | MIIM_ID;
infoW.wID = SC_TASKLIST;
infoW.dwTypeData = testW;
infoW.cch = lstrlenW( testW );
ret = SetMenuItemInfoW( menu, SC_TASKLIST, FALSE, &infoW );
ok( ret, "failed to set SC_TASKLIST\n" );
ret = SetMenuItemInfoW( menu, SC_TASKLIST+1, FALSE, &infoW );
ok( !ret, "succeeded setting SC_TASKLIST+1\n" );
ret = SetMenuItemInfoW( menu, SC_TASKLIST, TRUE, &infoW );
ok( !ret, "succeeded setting by position\n" );
DestroyMenu( menu );
DestroyWindow( hwnd );
}
/* 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)
@ -848,6 +1033,37 @@ static void test_menu_bmp_and_string(void)
ok( HBMMENU_POPUP_CLOSE == mii.hbmpItem, "Item info did not get the right hbitmap: got %p expected %p\n",
mii.hbmpItem, HBMMENU_POPUP_CLOSE);
memset(&mii, 0x81, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE | MIIM_DATA;
mii.dwTypeData = (LPSTR)bmfill;
mii.cch = sizeof(bmfill);
mii.dwItemData = 0x81818181;
got = GetMenuItemInfoA(hsysmenu, SC_RESTORE, FALSE, &mii);
ok(got, "GetMenuItemInfo failed\n");
ok((mii.fType & ~(MFT_RIGHTJUSTIFY|MFT_RIGHTORDER)) == MFT_STRING, "expected MFT_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == SC_RESTORE, "expected SC_RESTORE, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0, "expected 0, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == (LPSTR)bmfill, "expected %p, got %p\n", bmfill, mii.dwTypeData);
ok(mii.cch != 0, "cch should not be 0\n");
ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE;
mii.hbmpItem = (HBITMAP)0x81818181;
got = GetMenuItemInfoA(hsysmenu, SC_CLOSE, FALSE, &mii);
ok(got, "GetMenuItemInfo failed\n");
ok((mii.fType & ~(MFT_RIGHTJUSTIFY|MFT_RIGHTORDER)) == MFT_STRING, "expected MFT_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == SC_RESTORE, "expected SC_RESTORE, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0, "expected 0, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == (LPSTR)bmfill, "expected %p, got %p\n", bmfill, mii.dwTypeData);
ok(mii.cch != 0, "cch should not be 0\n");
ok(mii.hbmpItem == HBMMENU_POPUP_CLOSE, "expected HBMMENU_POPUP_CLOSE, got %p\n", mii.hbmpItem);
SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)menu_ownerdraw_wnd_proc);
if( winetest_debug)
@ -2166,13 +2382,7 @@ static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter)
return 0;
}
if (menu_tests[i]._todo_wine)
{
todo_wine {
ok(menu_tests[i].bMenuVisible == bMenuVisible, "test %d\n", i);
}
}
else
todo_wine_if (menu_tests[i]._todo_wine)
ok(menu_tests[i].bMenuVisible == bMenuVisible, "test %d\n", i);
}
return 0;
@ -2234,11 +2444,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam,
if (pGetMenuInfo) /* Skip on NT */
{
/* Native returns handle to destroyed window */
if (msg==WM_UNINITMENUPOPUP && popmenu==1)
todo_wine ok(!mbi.hwndMenu == !popmenu,
"msg %x: GetMenuBarInfo.hwndMenu wrong: %p expected %sNULL\n",
msg, mbi.hwndMenu, popmenu ? "not " : "");
else
todo_wine_if (msg==WM_UNINITMENUPOPUP && popmenu==1)
ok(!mbi.hwndMenu == !popmenu,
"msg %x: GetMenuBarInfo.hwndMenu wrong: %p expected %sNULL\n",
msg, mbi.hwndMenu, popmenu ? "not " : "");
@ -2515,7 +2721,8 @@ static void check_menu_items(HMENU hmenu, UINT checked_cmd, UINT checked_type,
if (mii.hSubMenu)
{
ok(mii.wID == (UINT_PTR)mii.hSubMenu, "id %u: wID should be equal to hSubMenu\n", checked_cmd);
ok(mii.wID == (UINT_PTR)mii.hSubMenu, "id %u: wID %x should be equal to hSubMenu %p\n",
checked_cmd, mii.wID, mii.hSubMenu);
if (!GetMenuItemCount(mii.hSubMenu))
{
ok(mii.fType == checked_type, "id %u: expected fType %04x, got %04x\n", checked_cmd, checked_type, mii.fType);
@ -3656,10 +3863,19 @@ static void test_emptypopup(void)
ok(ret, "DestroyMenu failed with error %d\n", GetLastError());
}
static HMENU get_bad_hmenu( UINT_PTR id )
{
while (IsMenu( (HMENU)id )) id++;
return (HMENU)id;
}
static void test_AppendMenu(void)
{
static char string[] = "string";
MENUITEMINFOA mii;
HMENU hmenu, hsubmenu;
HBITMAP hbmp;
char buf[16];
BOOL ret;
hmenu = CreateMenu();
@ -3671,16 +3887,18 @@ static void test_AppendMenu(void)
hmenu = CreateMenu();
ok(hmenu != 0, "CreateMenu failed\n");
ret = AppendMenuA(hmenu, MF_POPUP, 202, "item 1");
hsubmenu = get_bad_hmenu( 202 );
ret = AppendMenuA(hmenu, MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
ok(ret, "AppendMenu failed\n");
check_menu_items(hmenu, 202, MF_STRING, 0);
check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_STRING, 0);
DestroyMenu(hmenu);
hmenu = CreateMenu();
ok(hmenu != 0, "CreateMenu failed\n");
ret = AppendMenuA(hmenu, MF_OWNERDRAW | MF_POPUP, 203, "item 1");
hsubmenu = get_bad_hmenu( 203 );
ret = AppendMenuA(hmenu, MF_OWNERDRAW | MF_POPUP, (UINT_PTR)hsubmenu, "item 1");
ok(ret, "AppendMenu failed\n");
check_menu_items(hmenu, 203, MF_OWNERDRAW, 0);
check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_OWNERDRAW, 0);
DestroyMenu(hmenu);
hmenu = CreateMenu();
@ -3748,13 +3966,14 @@ static void test_AppendMenu(void)
ret = AppendMenuA(hmenu, MF_STRING, 204, "item 1");
ok(ret, "AppendMenu failed\n");
check_menu_items(hmenu, 204, MF_STRING, 0);
ret = ModifyMenuA(hmenu, 0, MF_POPUP | MF_BYPOSITION, 205, "item 2");
hsubmenu = get_bad_hmenu( 205 );
ret = ModifyMenuA(hmenu, 0, MF_POPUP | MF_BYPOSITION, (UINT_PTR)hsubmenu, "item 2");
ok(ret, "ModifyMenu failed\n");
check_menu_items(hmenu, 205, MF_STRING, 0);
check_menu_items(hmenu, (UINT_PTR)hsubmenu, MF_STRING, 0);
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_SUBMENU;
mii.hSubMenu = (HMENU)204;
mii.hSubMenu = get_bad_hmenu( 204 );
ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
ok(!ret, "InsertMenuItem should fail\n");
ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
@ -3771,11 +3990,323 @@ if (0) /* FIXME: uncomment once Wine is fixed */
if (0) /* FIXME: uncomment once Wine is fixed */
check_menu_items(hmenu, 207, MF_SEPARATOR, MFS_GRAYED);
DestroyMenu(hmenu);
hbmp = CreateBitmap(1, 1, 1, 1, NULL);
hmenu = CreateMenu();
ok(hmenu != 0, "CreateMenu failed\n");
/* menu item with a string and a bitmap */
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = string;
mii.cch = strlen(string);
mii.hbmpItem = hbmp;
ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
ok(ret, "InsertMenuItem failed\n");
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE;
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_BITMAP, "expected MF_BITMAP, got %#x\n", mii.fType);
ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == (LPSTR)hbmp, "expected %p, got %p\n", hbmp, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE | MIIM_DATA;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_BITMAP, "expected MF_BITMAP, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0, "expected 0, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == (LPSTR)hbmp, "expected %p, got %p\n", hbmp, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
DestroyMenu(hmenu);
DeleteObject(hbmp);
hmenu = CreateMenu();
ok(hmenu != 0, "CreateMenu failed\n");
/* menu item with a string and a "magic" bitmap */
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = string;
mii.cch = strlen(string);
mii.hbmpItem = HBMMENU_POPUP_RESTORE;
ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
ok(ret, "InsertMenuItem failed\n");
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE | MIIM_DATA;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0, "expected 0, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
DestroyMenu(hmenu);
hbmp = CreateBitmap(1, 1, 1, 1, NULL);
hmenu = CreateMenu();
ok(hmenu != 0, "CreateMenu failed\n");
/* menu item with a string */
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE | MIIM_DATA;
mii.dwItemData = (ULONG_PTR)hbmp;
mii.dwTypeData = string;
mii.cch = strlen(string);
mii.hbmpItem = hbmp;
ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
ok(ret, "InsertMenuItem failed\n");
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STATE | MIIM_ID | MIIM_TYPE | MIIM_DATA;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == (ULONG_PTR)hbmp, "expected %p, got %#lx\n", hbmp, mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == 0, "expected 0, got %p\n", mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == 0, "expected 0, got %p\n", mii.hbmpItem);
DestroyMenu(hmenu);
DeleteObject(hbmp);
/* menu item with a string */
hbmp = CreateBitmap(1, 1, 1, 1, NULL);
hmenu = CreateMenu();
ok(hmenu != 0, "CreateMenu failed\n");
memset(&mii, 0, sizeof(mii));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_STRING;
mii.dwTypeData = string;
mii.cch = strlen(string);
ret = InsertMenuItemA(hmenu, 0, TRUE, &mii);
ok(ret, "InsertMenuItem failed\n");
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == 0, "expected 0, got %p\n", mii.hbmpItem);
/* add "magic" bitmap to a menu item */
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = HBMMENU_POPUP_RESTORE;
ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "SetMenuItemInfo failed\n");
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == HBMMENU_POPUP_RESTORE, "expected HBMMENU_POPUP_RESTORE, got %p\n", mii.hbmpItem);
/* replace "magic" bitmap by a normal one */
mii.fMask = MIIM_BITMAP;
mii.hbmpItem = hbmp;
ret = SetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "SetMenuItemInfo failed\n");
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_FTYPE | MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_STRING | MIIM_BITMAP;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_STRING, "expected MF_STRING, got %#x\n", mii.fType);
ok(mii.fState == MF_ENABLED, "expected MF_ENABLED, got %#x\n", mii.fState);
ok(mii.wID == 0, "expected 0, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == buf, "expected %p, got %p\n", buf, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(!strcmp(buf, string), "expected %s, got %s\n", string, buf);
ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
memset(&mii, 0x81, sizeof(mii));
memset(buf, 0x81, sizeof(buf));
mii.cbSize = sizeof(mii);
mii.fMask = MIIM_TYPE;
mii.dwTypeData = buf;
mii.cch = sizeof(buf);
mii.dwItemData = 0x81818181;
ret = GetMenuItemInfoA(hmenu, 0, TRUE, &mii);
ok(ret, "GetMenuItemInfo failed\n");
ok(mii.fType == MF_BITMAP, "expected MF_BITMAP, got %#x\n", mii.fType);
ok(mii.fState == 0x81818181, "expected 0x81818181, got %#x\n", mii.fState);
ok(mii.wID == 0x81818181, "expected 0x81818181, got %#x\n", mii.wID);
ok(mii.hSubMenu == 0, "expected 0, got %p\n", mii.hSubMenu);
ok(mii.dwItemData == 0x81818181, "expected 0x81818181, got %#lx\n", mii.dwItemData);
ok(mii.dwTypeData == (LPSTR)hbmp, "expected %p, got %p\n", hbmp, mii.dwTypeData);
ok(mii.cch == 6, "expected 6, got %u\n", mii.cch);
ok(mii.hbmpItem == hbmp, "expected %p, got %p\n", hbmp, mii.hbmpItem);
DestroyMenu(hmenu);
DeleteObject(hbmp);
}
START_TEST(menu)
{
init_function_pointers();
register_menu_check_class();
/* Wine defines MENUITEMINFO for W2K and above. NT4 and below can't
* handle that.
@ -3789,10 +4320,9 @@ START_TEST(menu)
test_menu_resource_layout();
test_InsertMenu();
test_menualign();
test_system_menu();
}
register_menu_check_class();
test_menu_locked_by_window();
test_subpopup_locked_by_menu();
test_menu_ownerdraw();

View file

@ -524,11 +524,11 @@ static void test_work_area(void)
wp.rcNormalPosition.left, wp.rcNormalPosition.top,
wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
OffsetRect(&wp.rcNormalPosition, rc_work.left, rc_work.top);
if (mi.rcMonitor.left != mi.rcWork.left ||
todo_wine_if (mi.rcMonitor.left != mi.rcWork.left ||
mi.rcMonitor.top != mi.rcWork.top) /* FIXME: remove once Wine is fixed */
todo_wine ok(EqualRect(&rc_normal, &wp.rcNormalPosition), "normal pos is different\n");
else
{
ok(EqualRect(&rc_normal, &wp.rcNormalPosition), "normal pos is different\n");
}
SetWindowLongA(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);

View file

@ -32,6 +32,7 @@
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "dbt.h"
#include "wine/test.h"
@ -76,6 +77,7 @@ static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *);
static BOOL (WINAPI *pQueryActCtxW)(DWORD,HANDLE,void*,ULONG,void*,SIZE_T,SIZE_T*);
static void (WINAPI *pReleaseActCtx)(HANDLE);
/* encoded DRAWITEMSTRUCT into an LPARAM */
@ -3377,6 +3379,7 @@ static void test_mdi_messages(void)
BOOL zoomed;
RECT rc;
HMENU hMenu = CreateMenu();
DWORD val;
if (!mdi_RegisterWindowClasses()) assert(0);
@ -3405,8 +3408,9 @@ static void test_mdi_messages(void)
rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
mdi_frame, 0, GetModuleHandleA(0), &client_cs);
assert(mdi_client);
ok_sequence(WmCreateMDIclientSeq, "Create visible MDI client window", FALSE);
SetWindowLongA(mdi_client, 0, 0xdeadbeef);
ok_sequence(WmCreateMDIclientSeq, "Create visible MDI client window", FALSE);
ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
ok(GetFocus() == mdi_frame, "input focus should be on MDI frame not on %p\n", GetFocus());
@ -3864,6 +3868,8 @@ static void test_mdi_messages(void)
SetFocus(0);
flush_sequence();
val = GetWindowLongA(mdi_client, 0);
ok(val == 0xdeadbeef || broken(val == 0) /* >= Win 2003 */, "Expected 0xdeadbeef, got 0x%x\n", val);
DestroyWindow(mdi_client);
ok_sequence(WmDestroyMDIclientSeq, "Destroy MDI client window", FALSE);
@ -4519,6 +4525,47 @@ static void test_MsgWaitForMultipleObjects(HWND hwnd)
ok(ret == WAIT_IO_COMPLETION, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
}
static void test_WM_DEVICECHANGE(HWND hwnd)
{
DWORD ret;
MSG msg;
int i;
static const WPARAM wparams[] = {0,
DBT_DEVNODES_CHANGED,
DBT_QUERYCHANGECONFIG,
DBT_CONFIGCHANGED,
DBT_CONFIGCHANGECANCELED,
DBT_NO_DISK_SPACE,
DBT_LOW_DISK_SPACE,
DBT_CONFIGMGPRIVATE, /* 0x7fff */
DBT_DEVICEARRIVAL, /* 0x8000 */
DBT_DEVICEQUERYREMOVE,
DBT_DEVICEQUERYREMOVEFAILED,
DBT_DEVICEREMOVEPENDING,
DBT_DEVICEREMOVECOMPLETE,
DBT_DEVICETYPESPECIFIC,
DBT_CUSTOMEVENT};
for (i = 0; i < sizeof(wparams)/sizeof(wparams[0]); i++)
{
SetLastError(0xdeadbeef);
ret = PostMessageA(hwnd, WM_DEVICECHANGE, wparams[i], 0);
if (wparams[i] & 0x8000)
{
ok(ret == FALSE, "PostMessage should returned %d\n", ret);
ok(GetLastError() == ERROR_MESSAGE_SYNC_ONLY, "PostMessage error %08x\n", GetLastError());
}
else
{
ret = MsgWaitForMultipleObjects(0, NULL, FALSE, 0, QS_POSTMESSAGE);
ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjects returned %x\n", ret);
memset(&msg, 0, sizeof(msg));
ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should succeed\n");
ok(msg.message == WM_DEVICECHANGE, "got %04x instead of WM_DEVICECHANGE\n", msg.message);
}
}
}
static DWORD CALLBACK show_window_thread(LPVOID arg)
{
HWND hwnd = arg;
@ -4910,6 +4957,7 @@ static void test_messages(void)
flush_sequence();
test_MsgWaitForMultipleObjects(hparent);
test_WM_DEVICECHANGE(hparent);
/* the following test causes an exception in user.exe under win9x */
if (!PostMessageW( hparent, WM_USER, 0, 0 ))
@ -5892,7 +5940,96 @@ static const struct message WmSetPosComboSeq[] =
{ 0 }
};
static WNDPROC old_combobox_proc;
static const struct message WMSetFocusComboBoxSeq[] =
{
{ WM_SETFOCUS, sent },
{ WM_KILLFOCUS, sent|parent },
{ WM_SETFOCUS, sent },
{ WM_COMMAND, sent|defwinproc|wparam, MAKEWPARAM(1001, EN_SETFOCUS) },
{ EM_SETSEL, sent|defwinproc|wparam|lparam, 0, INT_MAX },
{ WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */
{ WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SETFOCUS) },
{ 0 }
};
static const struct message SetFocusButtonSeq[] =
{
{ WM_KILLFOCUS, sent },
{ CB_GETCOMBOBOXINFO, sent|optional },/* Windows 2000 */
{ 0x0167, sent|optional },/* Undocumented message. Sent on all versions except Windows 2000 */
{ WM_LBUTTONUP, sent|defwinproc },
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SELENDCANCEL) },
{ EM_SETSEL, sent|defwinproc|wparam|lparam, 0, 0 },
{ WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */
{ WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_KILLFOCUS) },
{ WM_CTLCOLORBTN, sent|parent },
{ 0 }
};
static const struct message SetFocusComboBoxSeq[] =
{
{ WM_CTLCOLORBTN, sent|parent },
{ WM_SETFOCUS, sent },
{ WM_KILLFOCUS, sent|defwinproc },
{ WM_SETFOCUS, sent },
{ WM_COMMAND, sent|defwinproc|wparam, MAKEWPARAM(1001, EN_SETFOCUS) },
{ EM_SETSEL, sent|defwinproc|wparam|lparam, 0, INT_MAX },
{ WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */
{ WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SETFOCUS) },
{ 0 }
};
static const struct message SetFocusButtonSeq2[] =
{
{ WM_KILLFOCUS, sent },
{ CB_GETCOMBOBOXINFO, sent|optional },/* Windows 2000 */
{ 0x0167, sent|optional },/* Undocumented message. Sent on all versions except Windows 2000 */
{ WM_LBUTTONUP, sent|defwinproc },
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_SELENDCANCEL) },
{ EM_SETSEL, sent|defwinproc|wparam|lparam, 0, 0 },
{ WM_CTLCOLOREDIT, sent|defwinproc },
{ WM_CTLCOLOREDIT, sent|parent },
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_COMBOBOX, CBN_KILLFOCUS) },
{ WM_CTLCOLORBTN, sent|parent },
{ 0 }
};
static WNDPROC old_combobox_proc, edit_window_proc;
static LRESULT CALLBACK combobox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static LONG defwndproc_counter = 0;
LRESULT ret;
struct recvd_message msg;
/* do not log painting messages */
if (message != WM_PAINT &&
message != WM_NCPAINT &&
message != WM_SYNCPAINT &&
message != WM_ERASEBKGND &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
!ignore_message( message ))
{
msg.hwnd = hwnd;
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
msg.descr = "combo";
add_message(&msg);
}
defwndproc_counter++;
ret = CallWindowProcA(edit_window_proc, hwnd, message, wParam, lParam);
defwndproc_counter--;
return ret;
}
static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@ -5943,8 +6080,11 @@ static void subclass_combobox(void)
static void test_combobox_messages(void)
{
HWND parent, combo;
HWND parent, combo, button, edit;
LRESULT ret;
BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
COMBOBOXINFO cbInfo;
BOOL res;
subclass_combobox();
@ -5985,6 +6125,65 @@ static void test_combobox_messages(void)
DestroyWindow(combo);
DestroyWindow(parent);
/* Start again. Test combobox text selection when getting and losing focus */
pGetComboBoxInfo = (void *)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
if (!pGetComboBoxInfo)
{
win_skip("GetComboBoxInfo is not available\n");
return;
}
parent = CreateWindowExA(0, "TestParentClass", "Parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
10, 10, 300, 300, NULL, NULL, NULL, NULL);
ok(parent != 0, "Failed to create parent window\n");
combo = CreateWindowExA(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
5, 5, 100, 100, parent, (HMENU)ID_COMBOBOX, NULL, NULL);
ok(combo != 0, "Failed to create combobox window\n");
cbInfo.cbSize = sizeof(COMBOBOXINFO);
SetLastError(0xdeadbeef);
res = pGetComboBoxInfo(combo, &cbInfo);
ok(res, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError());
edit = cbInfo.hwndItem;
edit_window_proc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC, (ULONG_PTR)combobox_subclass_proc);
button = CreateWindowExA(0, "Button", "OK", WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
5, 50, 100, 20, parent, NULL,
(HINSTANCE)GetWindowLongPtrA(parent, GWLP_HINSTANCE), NULL);
ok(button != 0, "Failed to create button window\n");
flush_sequence();
log_all_parent_messages++;
SendMessageA(combo, WM_SETFOCUS, 0, (LPARAM)edit);
log_all_parent_messages--;
ok_sequence(WMSetFocusComboBoxSeq, "WM_SETFOCUS on a ComboBox", TRUE);
flush_sequence();
log_all_parent_messages++;
SetFocus(button);
log_all_parent_messages--;
ok_sequence(SetFocusButtonSeq, "SetFocus on a Button", TRUE);
SendMessageA(combo, WM_SETTEXT, 0, (LPARAM)"Wine Test");
flush_sequence();
log_all_parent_messages++;
SetFocus(combo);
log_all_parent_messages--;
ok_sequence(SetFocusComboBoxSeq, "SetFocus on a ComboBox", TRUE);
flush_sequence();
log_all_parent_messages++;
SetFocus(button);
log_all_parent_messages--;
ok_sequence(SetFocusButtonSeq2, "SetFocus on a Button (2)", TRUE);
DestroyWindow(button);
DestroyWindow(combo);
DestroyWindow(parent);
}
/****************** WM_IME_KEYDOWN message test *******************/
@ -7300,7 +7499,7 @@ static const struct message WmAltPressRelease[] = {
{ EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
{ WM_INITMENU, sent|defwinproc },
{ EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
{ WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE) },
{ WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE), 0, MAKEWPARAM(0,MF_RIGHTJUSTIFY) },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
{ HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x30000001 }, /* XP */
@ -7367,7 +7566,7 @@ static const struct message WmVkF10Seq[] = {
{ EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
{ WM_INITMENU, sent|defwinproc },
{ EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
{ WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE) },
{ WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE), 0, MAKEWPARAM(0,MF_RIGHTJUSTIFY) },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
{ HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 0x10000001 }, /* XP */
@ -7399,7 +7598,7 @@ static const struct message WmShiftF10Seq[] = {
{ HCBT_SYSCOMMAND, hook },
{ WM_ENTERMENULOOP, sent|defwinproc|wparam|lparam, 0, 0 },
{ WM_INITMENU, sent|defwinproc },
{ WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE) },
{ WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE), 0, MAKEWPARAM(0,MF_RIGHTJUSTIFY) },
{ HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0xd0000001 }, /* XP */
{ HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 0x10000001 }, /* XP */
{ WM_CAPTURECHANGED, sent|defwinproc|wparam|lparam, 0, 0 },
@ -7742,6 +7941,7 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message,
case WM_USER+10:
{
ACTIVATION_CONTEXT_BASIC_INFORMATION basicinfo;
HANDLE handle, event = (HANDLE)lParam;
BOOL ret;
@ -7749,6 +7949,14 @@ static LRESULT MsgCheckProc (BOOL unicode, HWND hwnd, UINT message,
ret = pGetCurrentActCtx(&handle);
ok(ret, "failed to get current context, %u\n", GetLastError());
ok(handle == 0, "got active context %p\n", handle);
memset(&basicinfo, 0xff, sizeof(basicinfo));
ret = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, handle, 0, ActivationContextBasicInformation,
&basicinfo, sizeof(basicinfo), NULL);
ok(ret, "got %d, error %d\n", ret, GetLastError());
ok(basicinfo.hActCtx == NULL, "got %p\n", basicinfo.hActCtx);
ok(basicinfo.dwFlags == 0, "got %x\n", basicinfo.dwFlags);
if (event) SetEvent(event);
return 1;
}
@ -8559,9 +8767,11 @@ todo_wine
static void test_timers_no_wnd(void)
{
static UINT_PTR ids[0xffff];
UINT_PTR id, id2;
DWORD start;
MSG msg;
int i;
count = 0;
id = SetTimer(NULL, 0, 100, callback_count);
@ -8597,6 +8807,18 @@ todo_wine
count, TIMER_COUNT_EXPECTED);
KillTimer(NULL, id);
/* Note: SetSystemTimer doesn't support a NULL window, see test_timers */
/* Check what happens when we're running out of timers */
for (i=0; i<sizeof(ids)/sizeof(ids[0]); i++)
{
SetLastError(0xdeadbeef);
ids[i] = SetTimer(NULL, 0, USER_TIMER_MAXIMUM, tfunc);
if (!ids[i]) break;
}
ok(i != sizeof(ids)/sizeof(ids[0]), "all timers were created successfully\n");
ok(GetLastError()==ERROR_NO_MORE_USER_HANDLES || broken(GetLastError()==0xdeadbeef),
"GetLastError() = %d\n", GetLastError());
while (i > 0) KillTimer(NULL, ids[--i]);
}
static void test_timers_exception(DWORD code)
@ -9241,7 +9463,7 @@ static void test_recursive_hook(void)
hook_depth = 0;
GetMessageW(&msg, hook_hwnd, 0, 0);
ok(15 < max_hook_depth && max_hook_depth < 45, "max_hook_depth = %d\n", max_hook_depth);
ok(15 <= max_hook_depth && max_hook_depth < 45, "max_hook_depth = %d\n", max_hook_depth);
trace("max_hook_depth = %d\n", max_hook_depth);
b = UnhookWindowsHookEx(recursive_hook);
@ -11598,13 +11820,7 @@ static void test_ShowWindow(void)
"expected -1,-1 got %d,%d\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
"expected -1,-1 got %d,%d\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
if (work_rc.left || work_rc.top) todo_wine /* FIXME: remove once Wine is fixed */
ok(EqualRect(&win_rc, &wp.rcNormalPosition),
"expected %d,%d-%d,%d got %d,%d-%d,%d\n",
win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
wp.rcNormalPosition.left, wp.rcNormalPosition.top,
wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
else
todo_wine_if (work_rc.left || work_rc.top) /* FIXME: remove once Wine is fixed */
ok(EqualRect(&win_rc, &wp.rcNormalPosition),
"expected %d,%d-%d,%d got %d,%d-%d,%d\n",
win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
@ -11700,6 +11916,76 @@ static INT_PTR WINAPI test_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPAR
return 1;
}
static WNDPROC orig_edit_proc;
static LRESULT WINAPI dlg_creation_edit_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
struct recvd_message msg;
if (ignore_message( message )) return 0;
msg.hwnd = hwnd;
msg.message = message;
msg.flags = sent|wparam|lparam;
msg.wParam = wp;
msg.lParam = lp;
msg.descr = "edit";
add_message(&msg);
return CallWindowProcW(orig_edit_proc, hwnd, message, wp, lp);
}
static INT_PTR WINAPI test_dlg_proc2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
struct recvd_message msg;
if (ignore_message( message )) return 0;
msg.hwnd = hwnd;
msg.message = message;
msg.flags = sent|wparam|lparam|parent;
msg.wParam = wParam;
msg.lParam = lParam;
msg.descr = "dialog";
add_message(&msg);
if (message == WM_INITDIALOG)
{
orig_edit_proc = (WNDPROC)SetWindowLongPtrW(GetDlgItem(hwnd, 200),
GWLP_WNDPROC, (LONG_PTR)dlg_creation_edit_proc);
}
return 1;
}
static INT_PTR WINAPI test_dlg_proc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
ok( 0, "should not be called since DefDlgProc is not used\n" );
return 0;
}
static LRESULT WINAPI test_dlg_proc4(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
struct recvd_message msg;
if (!ignore_message( message ))
{
msg.hwnd = hwnd;
msg.message = message;
msg.flags = sent|wparam|lparam|parent;
msg.wParam = wParam;
msg.lParam = lParam;
msg.descr = "dialog";
add_message(&msg);
}
if (message == WM_INITDIALOG)
{
orig_edit_proc = (WNDPROC)SetWindowLongPtrW(GetDlgItem(hwnd, 200),
GWLP_WNDPROC, (LONG_PTR)dlg_creation_edit_proc);
return 1;
}
return DefWindowProcW( hwnd, message, wParam, lParam );
}
static const struct message WmDefDlgSetFocus_1[] = {
{ WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
{ WM_GETTEXTLENGTH, sent|wparam|lparam|optional, 0, 0 }, /* XP */
@ -11758,6 +12044,65 @@ static const struct message WmCreateDialogParamSeq_2[] = {
{ 0 }
};
static const struct message WmCreateDialogParamSeq_3[] = {
{ HCBT_CREATEWND, hook },
{ WM_SETFONT, sent|parent },
{ WM_INITDIALOG, sent|parent },
{ WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
{ EM_SETSEL, sent|wparam|lparam, 0, INT_MAX },
{ EM_SETSEL, sent|wparam|lparam|optional, 0, INT_MAX },
{ EM_SETSEL, sent|wparam|lparam|optional, 0, INT_MAX },
{ EM_SETSEL, sent|wparam|lparam|optional, 0, INT_MAX },
{ HCBT_ACTIVATE, hook },
{ WM_QUERYNEWPALETTE, sent|parent|optional }, /* TODO: this message should not be sent */
{ WM_WINDOWPOSCHANGING, sent|parent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
{ WM_WINDOWPOSCHANGING, sent|parent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
{ WM_ACTIVATEAPP, sent|parent|wparam, 1 },
{ WM_NCACTIVATE, sent|parent },
{ WM_ACTIVATE, sent|parent|wparam, 1 },
{ WM_SETFOCUS, sent },
{ WM_COMMAND, sent|parent|wparam, MAKELONG(200, EN_SETFOCUS) },
{ WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
{ WM_USER, sent|parent },
{ WM_CHANGEUISTATE, sent|parent|optional },
{ 0 }
};
static const struct message WmCreateDialogParamSeq_4[] = {
{ HCBT_CREATEWND, hook },
{ WM_NCCREATE, sent|parent },
{ WM_NCCALCSIZE, sent|parent|wparam, 0 },
{ WM_CREATE, sent|parent },
{ EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
{ WM_SIZE, sent|parent|wparam, SIZE_RESTORED },
{ WM_MOVE, sent|parent },
{ WM_SETFONT, sent|parent },
{ WM_INITDIALOG, sent|parent },
{ WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
{ EM_SETSEL, sent|wparam|lparam, 0, INT_MAX },
{ EM_SETSEL, sent|wparam|lparam|optional, 0, INT_MAX },
{ EM_SETSEL, sent|wparam|lparam|optional, 0, INT_MAX },
{ EM_SETSEL, sent|wparam|lparam|optional, 0, INT_MAX },
{ HCBT_ACTIVATE, hook },
{ WM_QUERYNEWPALETTE, sent|parent|optional }, /* TODO: this message should not be sent */
{ WM_WINDOWPOSCHANGING, sent|parent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
{ WM_WINDOWPOSCHANGING, sent|parent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
{ WM_ACTIVATEAPP, sent|parent|wparam, 1 },
{ WM_NCACTIVATE, sent|parent },
{ WM_ACTIVATE, sent|parent|wparam, 1 },
{ HCBT_SETFOCUS, hook },
{ WM_SETFOCUS, sent|parent },
{ WM_KILLFOCUS, sent|parent },
{ WM_SETFOCUS, sent },
{ WM_COMMAND, sent|parent|wparam, MAKELONG(200, EN_SETFOCUS) },
{ WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
{ WM_USER, sent|parent },
{ WM_CHANGEUISTATE, sent|parent|optional },
{ WM_UPDATEUISTATE, sent|parent|optional },
{ WM_UPDATEUISTATE, sent|optional },
{ 0 }
};
static void test_dialog_messages(void)
{
WNDCLASSA cls;
@ -11860,6 +12205,23 @@ static void test_dialog_messages(void)
DestroyWindow(hdlg);
flush_sequence();
hdlg = CreateDialogParamA(0, "FOCUS_TEST_DIALOG_3", 0, test_dlg_proc2, 0);
ok(IsWindow(hdlg), "CreateDialogParam failed\n");
ok_sequence(WmCreateDialogParamSeq_3, "CreateDialogParam_3", TRUE);
EndDialog(hdlg, 0);
DestroyWindow(hdlg);
flush_sequence();
UnregisterClassA( cls.lpszClassName, cls.hInstance );
cls.lpfnWndProc = test_dlg_proc4;
ok( RegisterClassA(&cls), "failed to register class again\n" );
hdlg = CreateDialogParamA(0, "FOCUS_TEST_DIALOG_4", 0, test_dlg_proc3, 0);
ok(IsWindow(hdlg), "CreateDialogParam failed\n");
ok_sequence(WmCreateDialogParamSeq_4, "CreateDialogParam_4", TRUE);
EndDialog(hdlg, 0);
DestroyWindow(hdlg);
flush_sequence();
UnregisterClassA(cls.lpszClassName, cls.hInstance);
}
@ -14903,9 +15265,7 @@ static void test_SendMessage_other_thread(int thread_n)
ret = GetQueueStatus(QS_SENDMESSAGE|QS_POSTMESSAGE);
/* FIXME: remove once Wine is fixed */
if (thread_n == 2) todo_wine
ok(ret == 0, "wrong status %08x\n", ret);
else
todo_wine_if (thread_n == 2)
ok(ret == 0, "wrong status %08x\n", ret);
trace("main: call PeekMessage\n");
@ -14922,6 +15282,33 @@ else
flush_sequence();
}
static const struct message DoubleSetCaptureSeq[] =
{
{ WM_CAPTURECHANGED, sent },
{ 0 }
};
static void test_DoubleSetCapture(void)
{
HWND hwnd;
hwnd = CreateWindowExA(0, "TestWindowClass", "Test DoubleSetCapture",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 200, 200, 0, 0, 0, NULL);
ok (hwnd != 0, "Failed to create overlapped window\n");
ShowWindow( hwnd, SW_SHOW );
UpdateWindow( hwnd );
flush_events();
flush_sequence();
SetCapture( hwnd );
SetCapture( hwnd );
ok_sequence(DoubleSetCaptureSeq, "SetCapture( hwnd ) twice", FALSE);
DestroyWindow(hwnd);
}
static void init_funcs(void)
{
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
@ -14931,6 +15318,7 @@ static void init_funcs(void)
X(CreateActCtxW);
X(DeactivateActCtx);
X(GetCurrentActCtx);
X(QueryActCtxW);
X(ReleaseActCtx);
#undef X
}
@ -15067,6 +15455,7 @@ START_TEST(msg)
test_TrackPopupMenu();
test_TrackPopupMenuEmpty();
}
test_DoubleSetCapture();
/* keep it the last test, under Windows it tends to break the tests
* which rely on active/foreground windows being correct.
*/
@ -15192,6 +15581,8 @@ START_TEST(msg_focus)
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);
flush_events();
test_DoubleSetCapture();
/* keep it the last test, under Windows it tends to break the tests
* which rely on active/foreground windows being correct.
*/

View file

@ -107,6 +107,23 @@ FONT 8, "MS Shell Dlg"
LTEXT "Hello world", 200,4,4,50,14
}
FOCUS_TEST_DIALOG_3 DIALOG 0, 0, 60, 30
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Test dialog"
FONT 8, "MS Shell Dlg"
{
EDITTEXT 200,4,4,50,14
}
FOCUS_TEST_DIALOG_4 DIALOG 0, 0, 60, 30
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Test dialog"
CLASS "MyDialogClass"
FONT 8, "MS Shell Dlg"
{
EDITTEXT 200,4,4,50,14
}
IDD_DIALOG DIALOG 0, 0, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"

View file

@ -25,7 +25,7 @@
#include "wine/test.h"
static HWND hScroll, hMainWnd;
static HWND hScroll;
static BOOL bThemeActive = FALSE;
static LRESULT CALLBACK MyWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
@ -52,20 +52,45 @@ static LRESULT CALLBACK MyWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP
}
return 0;
}
static void scrollbar_test_track(void)
static HWND create_main_test_wnd(void)
{
/* test that scrollbar tracking is terminated when
* the control looses mouse capture */
SendMessageA( hScroll, WM_LBUTTONDOWN, 0, MAKELPARAM( 1, 1));
/* a normal return from the sendmessage */
/* not normal for instance by closing the windws */
ok( IsWindow( hScroll), "Scrollbar has gone!\n");
HWND hMainWnd;
hScroll = NULL;
hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll",
WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0 );
ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
ok(hScroll != NULL, "got NULL scroll bar handle\n");
return hMainWnd;
}
static void scrollbar_test1(void)
static void scrollbar_test_track(void)
{
HWND mainwnd;
mainwnd = create_main_test_wnd();
/* test that scrollbar tracking is terminated when
* the control loses mouse capture */
SendMessageA( hScroll, WM_LBUTTONDOWN, 0, MAKELPARAM( 1, 1));
/* a normal return from SendMessage */
/* not normal for instances such as closing the window */
ok( IsWindow( hScroll), "Scrollbar has gone!\n");
DestroyWindow(hScroll);
DestroyWindow(mainwnd);
}
static void test_EnableScrollBar(void)
{
HWND mainwnd;
BOOL ret;
mainwnd = create_main_test_wnd();
ret = EnableScrollBar( hScroll, SB_CTL, ESB_DISABLE_BOTH );
ok( ret, "The scrollbar should be disabled.\n" );
ok( !IsWindowEnabled( hScroll ), "The scrollbar window should be disabled.\n" );
@ -88,13 +113,17 @@ static void scrollbar_test1(void)
ret = EnableScrollBar( hScroll, SB_CTL, ESB_ENABLE_BOTH );
ok( ret, "The scrollbar should be enabled.\n" );
ok( IsWindowEnabled( hScroll ), "The scrollbar window should be enabled.\n" );
DestroyWindow(hScroll);
DestroyWindow(mainwnd);
}
static void scrollbar_test2(void)
static void test_SetScrollPos(void)
{
HWND mainwnd;
int ret;
trace("The scrollbar is disabled.\n");
mainwnd = create_main_test_wnd();
EnableWindow( hScroll, FALSE );
ok( !IsWindowEnabled( hScroll ), "The scroll should be disabled.\n" );
@ -114,8 +143,6 @@ static void scrollbar_test2(void)
ret = GetScrollPos( hScroll, SB_CTL);
ok( ret == 30, "The position should be set!!!\n");
trace("The scrollbar is enabled.\n");
EnableWindow( hScroll, TRUE );
ok( IsWindowEnabled( hScroll ), "The scroll should be enabled.\n" );
@ -133,12 +160,18 @@ static void scrollbar_test2(void)
ret = GetScrollPos( hScroll, SB_CTL);
ok( ret == 30, "The position should not be equal to zero\n");
DestroyWindow(hScroll);
DestroyWindow(mainwnd);
}
static void scrollbar_test3(void)
static void test_ShowScrollBar(void)
{
HWND mainwnd;
BOOL ret;
mainwnd = create_main_test_wnd();
ret = ShowScrollBar( hScroll, SB_CTL, FALSE );
ok( ret, "The ShowScrollBar() should not failed.\n" );
ok( !IsWindowVisible( hScroll ), "The scrollbar window should not be visible\n" );
@ -150,10 +183,13 @@ static void scrollbar_test3(void)
ret = ShowScrollBar( NULL, SB_CTL, TRUE );
ok( !ret, "The ShowScrollBar() should failed.\n" );
DestroyWindow(hScroll);
DestroyWindow(mainwnd);
}
static void scrollbar_test4(void)
static void test_GetScrollBarInfo(void)
{
HWND hMainWnd;
BOOL ret;
SCROLLBARINFO sbi;
RECT rect;
@ -166,6 +202,8 @@ static void scrollbar_test4(void)
return;
}
hMainWnd = create_main_test_wnd();
/* Test GetScrollBarInfo to make sure it returns rcScrollBar in screen
* coordinates. */
sbi.cbSize = sizeof(sbi);
@ -218,6 +256,9 @@ static void scrollbar_test4(void)
rect.top, rect.left, rect.bottom, rect.right,
sbi.rcScrollBar.top, sbi.rcScrollBar.left,
sbi.rcScrollBar.bottom, sbi.rcScrollBar.right );
DestroyWindow(hScroll);
DestroyWindow(hMainWnd);
}
/* some tests designed to show that Horizontal and Vertical
@ -484,6 +525,49 @@ static void scrollbar_test_init(void)
UnregisterClassA(cls_name, wc.hInstance);
}
static void test_SetScrollInfo(void)
{
SCROLLINFO si;
HWND mainwnd;
BOOL ret;
mainwnd = create_main_test_wnd();
ret = IsWindowEnabled(hScroll);
ok(ret, "scroll bar disabled\n");
EnableScrollBar(hScroll, SB_CTL, ESB_DISABLE_BOTH);
ret = IsWindowEnabled(hScroll);
ok(!ret, "scroll bar disabled\n");
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = 0xf;
ret = GetScrollInfo(hScroll, SB_CTL, &si);
ok(ret, "got %d\n", ret);
/* SetScrollInfo */
memset(&si, 0, sizeof(si));
si.cbSize = sizeof(si);
ret = IsWindowEnabled(hScroll);
ok(!ret, "scroll bar disabled\n");
si.fMask = SIF_POS|SIF_RANGE|SIF_PAGE|SIF_DISABLENOSCROLL;
si.nMax = 100;
si.nPos = 0;
si.nPage = 100;
SetScrollInfo(hScroll, SB_CTL, &si, TRUE);
ret = IsWindowEnabled(hScroll);
ok(!ret, "scroll bar enabled\n");
si.fMask = 0xf;
ret = GetScrollInfo(hScroll, SB_CTL, &si);
ok(ret, "got %d\n", ret);
DestroyWindow(hScroll);
DestroyWindow(mainwnd);
}
START_TEST ( scroll )
{
WNDCLASSA wc;
@ -502,20 +586,12 @@ START_TEST ( scroll )
wc.lpfnWndProc = MyWndProc;
RegisterClassA(&wc);
hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll",
WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0 );
ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n");
if (!hMainWnd) return;
assert( hScroll );
scrollbar_test1();
scrollbar_test2();
scrollbar_test3();
scrollbar_test4();
test_EnableScrollBar();
test_SetScrollPos();
test_ShowScrollBar();
test_GetScrollBarInfo();
scrollbar_test_track();
test_SetScrollInfo();
/* Some test results vary depending of theming being active or not */
hUxtheme = LoadLibraryA("uxtheme.dll");
@ -533,7 +609,4 @@ START_TEST ( scroll )
scrollbar_test_default( WS_HSCROLL | WS_VSCROLL);
scrollbar_test_init();
DestroyWindow(hScroll);
DestroyWindow(hMainWnd);
}

View file

@ -1553,10 +1553,10 @@ static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
ok( Ncmcur.iSmCaptionHeight == expect,
"SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
ok( Ncmcur.iCaptionWidth == 8 ||
Ncmcur.iCaptionWidth == 12 || /* Vista, W7b */
/* iCaptionWidth depends on a version, could be 8, 12 (Vista, Win7), 13 */
ok( (Ncmcur.iCaptionWidth >= 8 && Ncmcur.iCaptionWidth <= 13) ||
Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */
"CaptionWidth: %d expected 8, 12 or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
"CaptionWidth: %d expected from [8, 13] or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
ok( Ncmcur.iScrollWidth == 8,
"ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
ok( Ncmcur.iScrollHeight == 8,
@ -2496,9 +2496,7 @@ static void test_WM_DISPLAYCHANGE(void)
continue;
}
if(start_bpp != test_bpps[i]) {
todo_wine ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
} else {
todo_wine_if(start_bpp != test_bpps[i]) {
ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
}
last_set_bpp = test_bpps[i];

View file

@ -604,15 +604,13 @@ static void strfmt( const char *str, char *strout)
#define TABTEST( tabval, tabcount, string, _exp) \
{ int i,x_act, x_exp; char strdisp[64];\
{ int i; 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); \
ok( extent == _exp, "Test case \"%s\". Text extent is 0x%x, expected 0x%x tab %d tabcount %d\n", \
strdisp, extent, _exp, tabval, tabcount); \
} \
@ -649,16 +647,16 @@ static void test_TabbedText(void)
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)
TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy))
TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy))
TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy))
TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy))
TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy))
TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy))
}
}
align=-1;
@ -667,16 +665,16 @@ static void test_TabbedText(void)
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)
TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy))
TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy))
TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy))
TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy))
TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy))
TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy))
}
}

View file

@ -39,6 +39,10 @@
#define SPI_GETDESKWALLPAPER 0x0073
#endif
#ifndef WM_SYSTIMER
#define WM_SYSTIMER 0x0118
#endif
#define LONG_PTR INT_PTR
#define ULONG_PTR UINT_PTR
@ -183,6 +187,8 @@ static BOOL ignore_message( UINT message )
return (message >= 0xc000 ||
message == WM_GETICON ||
message == WM_GETOBJECT ||
message == WM_TIMER ||
message == WM_SYSTIMER ||
message == WM_TIMECHANGE ||
message == WM_DEVICECHANGE);
}
@ -983,6 +989,52 @@ static void FixedAdjustWindowRectEx(RECT* rc, LONG style, BOOL menu, LONG exstyl
rc->bottom += GetSystemMetrics(SM_CYHSCROLL);
}
/* reimplement it to check that the Wine algorithm gives the correct result */
static void wine_AdjustWindowRectEx( RECT *rect, LONG style, BOOL menu, LONG exStyle )
{
int adjust;
if ((exStyle & (WS_EX_STATICEDGE|WS_EX_DLGMODALFRAME)) ==
WS_EX_STATICEDGE)
{
adjust = 1; /* for the outer frame always present */
}
else
{
adjust = 0;
if ((exStyle & WS_EX_DLGMODALFRAME) ||
(style & (WS_THICKFRAME|WS_DLGFRAME))) adjust = 2; /* outer */
}
if (style & WS_THICKFRAME)
adjust += GetSystemMetrics(SM_CXFRAME) - GetSystemMetrics(SM_CXDLGFRAME); /* The resize border */
if ((style & (WS_BORDER|WS_DLGFRAME)) ||
(exStyle & WS_EX_DLGMODALFRAME))
adjust++; /* The other border */
InflateRect (rect, adjust, adjust);
if ((style & WS_CAPTION) == WS_CAPTION)
{
if (exStyle & WS_EX_TOOLWINDOW)
rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
else
rect->top -= GetSystemMetrics(SM_CYCAPTION);
}
if (menu) rect->top -= GetSystemMetrics(SM_CYMENU);
if (exStyle & WS_EX_CLIENTEDGE)
InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
if (style & WS_VSCROLL)
{
if((exStyle & WS_EX_LEFTSCROLLBAR) != 0)
rect->left -= GetSystemMetrics(SM_CXVSCROLL);
else
rect->right += GetSystemMetrics(SM_CXVSCROLL);
}
if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
}
static void test_nonclient_area(HWND hwnd)
{
DWORD style, exstyle;
@ -1010,6 +1062,14 @@ static void test_nonclient_area(HWND hwnd)
style, exstyle, menu, rc_window.left, rc_window.top, rc_window.right, rc_window.bottom,
rc.left, rc.top, rc.right, rc.bottom);
CopyRect(&rc, &rc_client);
MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
wine_AdjustWindowRectEx(&rc, style, menu, exstyle);
ok(EqualRect(&rc, &rc_window),
"window rect does not match: style:exstyle=0x%08x:0x%08x, menu=%d, win=(%d,%d)-(%d,%d), calc=(%d,%d)-(%d,%d)\n",
style, exstyle, menu, rc_window.left, rc_window.top, rc_window.right, rc_window.bottom,
rc.left, rc.top, rc.right, rc.bottom);
CopyRect(&rc, &rc_window);
DefWindowProcA(hwnd, WM_NCCALCSIZE, 0, (LPARAM)&rc);
@ -2000,10 +2060,12 @@ static BOOL mdi_RegisterWindowClasses(void)
static void test_mdi(void)
{
static const DWORD style[] = { 0, WS_HSCROLL, WS_VSCROLL, WS_HSCROLL | WS_VSCROLL };
HWND mdi_hwndMain, mdi_client;
CLIENTCREATESTRUCT client_cs;
RECT rc;
/*MSG msg;*/
DWORD i;
MSG msg;
if (!mdi_RegisterWindowClasses()) assert(0);
@ -2020,6 +2082,138 @@ static void test_mdi(void)
client_cs.hWindowMenu = 0;
client_cs.idFirstChild = 1;
for (i = 0; i < sizeof(style)/sizeof(style[0]); i++)
{
HWND mdi_child;
SCROLLINFO si;
BOOL ret, gotit;
mdi_client = CreateWindowExA(0, "mdiclient", NULL,
WS_CHILD | style[i],
0, 0, rc.right, rc.bottom,
mdi_hwndMain, 0, 0, &client_cs);
ok(mdi_client != 0, "MDI client creation failed\n");
mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_Class_1", "MDI child",
0,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
mdi_client, 0, 0,
mdi_lParam_test_message);
ok(mdi_child != 0, "MDI child creation failed\n");
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
ret = GetScrollInfo(mdi_client, SB_HORZ, &si);
if (style[i] & (WS_HSCROLL | WS_VSCROLL))
{
ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
ok(si.nPage == 0, "expected 0\n");
ok(si.nPos == 0, "expected 0\n");
ok(si.nTrackPos == 0, "expected 0\n");
ok(si.nMin == 0, "expected 0\n");
ok(si.nMax == 100, "expected 100\n");
}
else
ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
ret = GetScrollInfo(mdi_client, SB_VERT, &si);
if (style[i] & (WS_HSCROLL | WS_VSCROLL))
{
ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
ok(si.nPage == 0, "expected 0\n");
ok(si.nPos == 0, "expected 0\n");
ok(si.nTrackPos == 0, "expected 0\n");
ok(si.nMin == 0, "expected 0\n");
ok(si.nMax == 100, "expected 100\n");
}
else
ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
SetWindowPos(mdi_child, 0, -100, -100, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
ret = GetScrollInfo(mdi_client, SB_HORZ, &si);
if (style[i] & (WS_HSCROLL | WS_VSCROLL))
{
ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
ok(si.nPage == 0, "expected 0\n");
ok(si.nPos == 0, "expected 0\n");
ok(si.nTrackPos == 0, "expected 0\n");
ok(si.nMin == 0, "expected 0\n");
ok(si.nMax == 100, "expected 100\n");
}
else
ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
ret = GetScrollInfo(mdi_client, SB_VERT, &si);
if (style[i] & (WS_HSCROLL | WS_VSCROLL))
{
ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
ok(si.nPage == 0, "expected 0\n");
ok(si.nPos == 0, "expected 0\n");
ok(si.nTrackPos == 0, "expected 0\n");
ok(si.nMin == 0, "expected 0\n");
ok(si.nMax == 100, "expected 100\n");
}
else
ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
gotit = FALSE;
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_MOUSEMOVE || msg.message == WM_PAINT)
{
DispatchMessageA(&msg);
continue;
}
if (msg.message == 0x003f) /* WM_MDICALCCHILDSCROLL ??? */
{
ok(msg.hwnd == mdi_client, "message 0x003f should be posted to mdiclient\n");
gotit = TRUE;
}
else
ok(msg.hwnd != mdi_client, "message %04x should not be posted to mdiclient\n", msg.message);
DispatchMessageA(&msg);
}
ok(gotit, "message 0x003f should appear after SetWindowPos\n");
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
ret = GetScrollInfo(mdi_client, SB_HORZ, &si);
if (style[i] & (WS_HSCROLL | WS_VSCROLL))
{
ok(ret, "style %#x: GetScrollInfo(SB_HORZ) failed\n", style[i]);
todo_wine
ok(si.nPage != 0, "expected !0\n");
ok(si.nPos == 0, "expected 0\n");
ok(si.nTrackPos == 0, "expected 0\n");
ok(si.nMin != 0, "expected !0\n");
ok(si.nMax != 100, "expected !100\n");
}
else
ok(!ret, "style %#x: GetScrollInfo(SB_HORZ) should fail\n", style[i]);
ret = GetScrollInfo(mdi_client, SB_VERT, &si);
if (style[i] & (WS_HSCROLL | WS_VSCROLL))
{
ok(ret, "style %#x: GetScrollInfo(SB_VERT) failed\n", style[i]);
todo_wine
ok(si.nPage != 0, "expected !0\n");
ok(si.nPos == 0, "expected 0\n");
ok(si.nTrackPos == 0, "expected 0\n");
ok(si.nMin != 0, "expected !0\n");
ok(si.nMax != 100, "expected !100\n");
}
else
ok(!ret, "style %#x: GetScrollInfo(SB_VERT) should fail\n", style[i]);
DestroyWindow(mdi_child);
DestroyWindow(mdi_client);
}
/* MDIClient without MDIS_ALLCHILDSTYLES */
mdi_client = CreateWindowExA(0, "mdiclient",
NULL,
@ -3299,7 +3493,7 @@ static BOOL peek_message( MSG *msg )
do
{
ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE);
} while (ret && (msg->message == WM_TIMER || ignore_message(msg->message)));
} while (ret && ignore_message(msg->message));
return ret;
}
@ -3463,7 +3657,7 @@ static void test_mouse_input(HWND hwnd)
/* FIXME: SetCursorPos in Wine generates additional WM_MOUSEMOVE message */
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_TIMER || ignore_message(msg.message)) continue;
if (ignore_message(msg.message)) continue;
ok(msg.hwnd == popup && msg.message == WM_MOUSEMOVE,
"hwnd %p message %04x\n", msg.hwnd, msg.message);
DispatchMessageA(&msg);
@ -4605,26 +4799,16 @@ static BOOL AWR_init(void)
static void test_AWR_window_size(BOOL menu)
{
LONG styles[] = {
WS_POPUP,
WS_MAXIMIZE, WS_BORDER, WS_DLGFRAME,
WS_SYSMENU,
WS_THICKFRAME,
WS_MINIMIZEBOX, WS_MAXIMIZEBOX,
WS_HSCROLL, WS_VSCROLL
static const DWORD styles[] = {
WS_POPUP, WS_MAXIMIZE, WS_BORDER, WS_DLGFRAME, WS_CAPTION, WS_SYSMENU,
WS_THICKFRAME, WS_MINIMIZEBOX, WS_MAXIMIZEBOX, WS_HSCROLL, WS_VSCROLL
};
LONG exStyles[] = {
WS_EX_CLIENTEDGE,
WS_EX_TOOLWINDOW, WS_EX_WINDOWEDGE,
WS_EX_APPWINDOW,
#if 0
/* These styles have problems on (at least) WinXP (SP2) and Wine */
WS_EX_DLGMODALFRAME,
WS_EX_STATICEDGE,
#endif
static const DWORD exStyles[] = {
WS_EX_CLIENTEDGE, WS_EX_TOOLWINDOW, WS_EX_WINDOWEDGE, WS_EX_APPWINDOW,
WS_EX_DLGMODALFRAME, WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE
};
int i;
unsigned int i;
/* A exhaustive check of all the styles takes too long
* so just do a (hopefully representative) sample
@ -4636,6 +4820,33 @@ static void test_AWR_window_size(BOOL menu)
test_AWRwindow(szAWRClass, WS_THICKFRAME, exStyles[i], menu);
}
}
static void test_AWR_flags(void)
{
static const DWORD styles[] = { WS_POPUP, WS_BORDER, WS_DLGFRAME, WS_THICKFRAME };
static const DWORD exStyles[] = { WS_EX_CLIENTEDGE, WS_EX_TOOLWINDOW, WS_EX_WINDOWEDGE,
WS_EX_APPWINDOW, WS_EX_DLGMODALFRAME, WS_EX_STATICEDGE };
DWORD i, j, k, style, exstyle;
RECT rect, rect2;
for (i = 0; i < (1 << COUNTOF(styles)); i++)
{
for (k = style = 0; k < COUNTOF(styles); k++) if (i & (1 << k)) style |= styles[k];
for (j = 0; j < (1 << COUNTOF(exStyles)); j++)
{
for (k = exstyle = 0; k < COUNTOF(exStyles); k++) if (j & (1 << k)) exstyle |= exStyles[k];
SetRect( &rect, 100, 100, 200, 200 );
rect2 = rect;
AdjustWindowRectEx( &rect, style, FALSE, exstyle );
wine_AdjustWindowRectEx( &rect2, style, FALSE, exstyle );
ok( EqualRect( &rect, &rect2 ), "rects do not match: win %d,%d-%d,%d wine %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom,
rect2.left, rect2.top, rect2.right, rect2.bottom );
}
}
}
#undef COUNTOF
#define SHOWSYSMETRIC(SM) trace(#SM "=%d\n", GetSystemMetrics(SM))
@ -4661,6 +4872,7 @@ static void test_AdjustWindowRect(void)
test_AWR_window_size(FALSE);
test_AWR_window_size(TRUE);
test_AWR_flags();
DestroyMenu(hmenu);
}
@ -6705,11 +6917,11 @@ static void test_fullscreen(void)
/* Windows makes a maximized window slightly larger (to hide the borders?) */
fixup = min(abs(rc.left), abs(rc.top));
InflateRect(&rc, -fixup, -fixup);
ok(rc.left >= mi.rcWork.left && rc.top <= mi.rcWork.top &&
rc.right <= mi.rcWork.right && rc.bottom <= mi.rcWork.bottom,
ok(rc.left >= mi.rcMonitor.left && rc.top >= mi.rcMonitor.top &&
rc.right <= mi.rcMonitor.right && rc.bottom <= mi.rcMonitor.bottom,
"%#x/%#x: window rect %d,%d-%d,%d must be in %d,%d-%d,%d\n",
ex_style, style, rc.left, rc.top, rc.right, rc.bottom,
mi.rcWork.left, mi.rcWork.top, mi.rcWork.right, mi.rcWork.bottom);
mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom);
DestroyWindow(hwnd);
style = t_style[i] | WS_MAXIMIZE | WS_MAXIMIZEBOX;
@ -6727,8 +6939,8 @@ static void test_fullscreen(void)
rc.right >= mi.rcMonitor.right && rc.bottom >= mi.rcMonitor.bottom,
"%#x/%#x: window rect %d,%d-%d,%d\n", ex_style, style, rc.left, rc.top, rc.right, rc.bottom);
else
ok(rc.left >= mi.rcWork.left && rc.top <= mi.rcWork.top &&
rc.right <= mi.rcWork.right && rc.bottom <= mi.rcWork.bottom,
ok(rc.left >= mi.rcMonitor.left && rc.top >= mi.rcMonitor.top &&
rc.right <= mi.rcMonitor.right && rc.bottom <= mi.rcMonitor.bottom,
"%#x/%#x: window rect %d,%d-%d,%d\n", ex_style, style, rc.left, rc.top, rc.right, rc.bottom);
DestroyWindow(hwnd);
}
@ -7488,9 +7700,7 @@ static void test_child_window_from_point(void)
ok(hwnd != 0, "RealChildWindowFromPoint failed\n");
ret = window_to_index(hwnd, window, sizeof(window)/sizeof(window[0]));
/* FIXME: remove once Wine is fixed */
if (ret != real_child_pos[i])
todo_wine ok(ret == real_child_pos[i] || broken(ret == real_child_pos_nt4[i]), "expected %d, got %d\n", real_child_pos[i], ret);
else
todo_wine_if (ret != real_child_pos[i])
ok(ret == real_child_pos[i] || broken(ret == real_child_pos_nt4[i]), "expected %d, got %d\n", real_child_pos[i], ret);
get_window_attributes(hwnd, &attrs);

View file

@ -23,6 +23,9 @@
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/winternl.h"
static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG);
#define DESKTOP_ALL_ACCESS 0x01ff
@ -202,6 +205,34 @@ static void test_handles(void)
else if (le == ERROR_ACCESS_DENIED)
win_skip( "Not enough privileges for CreateWindowStation\n" );
SetLastError( 0xdeadbeef );
w2 = OpenWindowStationA( "", TRUE, WINSTA_ALL_ACCESS );
ok( !w2, "open station succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %u\n", GetLastError() );
SetLastError( 0xdeadbeef );
w2 = CreateWindowStationA( "", 0, WINSTA_ALL_ACCESS, NULL );
ok( w2 != 0, "create station failed err %u\n", GetLastError() );
SetLastError( 0xdeadbeef );
w3 = OpenWindowStationA( "", TRUE, WINSTA_ALL_ACCESS );
todo_wine
ok( w3 != 0, "open station failed err %u\n", GetLastError() );
CloseWindowStation( w3 );
CloseWindowStation( w2 );
SetLastError( 0xdeadbeef );
w2 = CreateWindowStationA( "foo\\bar", 0, WINSTA_ALL_ACCESS, NULL );
ok( !w2, "create station succeeded\n" );
ok( GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_ACCESS_DENIED,
"wrong error %u\n", GetLastError() );
SetLastError( 0xdeadbeef );
w2 = OpenWindowStationA( "foo\\bar", TRUE, WINSTA_ALL_ACCESS );
ok( !w2, "create station succeeded\n" );
ok( GetLastError() == ERROR_PATH_NOT_FOUND, "wrong error %u\n", GetLastError() );
/* desktops */
d1 = GetThreadDesktop(GetCurrentThreadId());
initial_desktop = d1;
@ -236,6 +267,28 @@ static void test_handles(void)
d2 = OpenDesktopA( "dummy name", 0, TRUE, DESKTOP_ALL_ACCESS );
ok( !d2, "open dummy desktop succeeded\n" );
SetLastError( 0xdeadbeef );
d2 = CreateDesktopA( "", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
todo_wine
ok( !d2, "create empty desktop succeeded\n" );
todo_wine
ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
SetLastError( 0xdeadbeef );
d2 = OpenDesktopA( "", 0, TRUE, DESKTOP_ALL_ACCESS );
ok( !d2, "open mepty desktop succeeded\n" );
ok( GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError() );
SetLastError( 0xdeadbeef );
d2 = CreateDesktopA( "foo\\bar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
ok( !d2, "create desktop succeeded\n" );
ok( GetLastError() == ERROR_BAD_PATHNAME, "wrong error %u\n", GetLastError() );
SetLastError( 0xdeadbeef );
d2 = OpenDesktopA( "foo\\bar", 0, TRUE, DESKTOP_ALL_ACCESS );
ok( !d2, "open desktop succeeded\n" );
ok( GetLastError() == ERROR_BAD_PATHNAME, "wrong error %u\n", GetLastError() );
d2 = CreateDesktopA( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
ok( d2 != 0, "create foobar desktop failed\n" );
SetLastError( 0xdeadbeef );
@ -388,12 +441,14 @@ static void test_enumdesktops(void)
static void test_getuserobjectinformation(void)
{
HDESK desk;
WCHAR bufferW[20];
char buffer[20];
WCHAR foobarTestW[] = {'f','o','o','b','a','r','T','e','s','t',0};
WCHAR foobarTestW[] = {'\\','f','o','o','b','a','r','T','e','s','t',0};
WCHAR DesktopW[] = {'D','e','s','k','t','o','p',0};
OBJECT_NAME_INFORMATION *name_info;
WCHAR bufferW[20];
char buffer[64];
NTSTATUS status;
DWORD size;
HDESK desk;
BOOL ret;
desk = CreateDesktopA("foobarTest", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
@ -440,9 +495,16 @@ static void test_getuserobjectinformation(void)
ok(ret, "GetUserObjectInformationW returned %x\n", ret);
ok(GetLastError() == 0xdeadbeef, "LastError is set to %08x\n", GetLastError());
ok(lstrcmpW(bufferW, foobarTestW) == 0, "Buffer is not set to 'foobarTest'\n");
ok(lstrcmpW(bufferW, foobarTestW + 1) == 0, "Buffer is not set to 'foobarTest'\n");
ok(size == 22, "size is set to %d\n", size); /* 22 bytes in 'foobarTest\0' in Unicode */
/* ObjectNameInformation does not return the full desktop name */
name_info = (OBJECT_NAME_INFORMATION *)buffer;
status = pNtQueryObject(desk, ObjectNameInformation, name_info, sizeof(buffer), NULL);
ok(!status, "expected STATUS_SUCCESS, got %08x\n", status);
ok(lstrcmpW(name_info->Name.Buffer, foobarTestW) == 0,
"expected '\\foobarTest', got %s\n", wine_dbgstr_w(name_info->Name.Buffer));
/** Tests for UOI_TYPE **/
/* Get size, test size and return value/error code */
@ -880,10 +942,8 @@ static void test_foregroundwindow(void)
if (input_desk_id == thread_desk_id)
{
ok(ret, "SetForegroundWindow failed!\n");
if (hwnd)
todo_wine_if (!hwnd)
ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd);
else
todo_wine ok(hwnd == hwnd_test , "unexpected foreground window %p\n", hwnd);
}
else
{
@ -896,18 +956,14 @@ static void test_foregroundwindow(void)
if (input_desk_id == thread_desk_id)
{
ok(!ret, "SetForegroundWindow should fail!\n");
if (hwnd)
todo_wine_if (!hwnd)
ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd);
else
todo_wine ok(hwnd == partners[input_desk_id] , "unexpected foreground window %p\n", hwnd);
}
else
{
todo_wine ok(!ret, "SetForegroundWindow should fail!\n");
if (!hwnd)
todo_wine_if (hwnd)
ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
else
todo_wine ok(hwnd == 0, "unexpected foreground window %p\n", hwnd);
}
}
}
@ -935,6 +991,9 @@ static void test_foregroundwindow(void)
START_TEST(winstation)
{
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
pNtQueryObject = (void *)GetProcAddress(hntdll, "NtQueryObject");
/* Check whether this platform supports WindowStation calls */
SetLastError( 0xdeadbeef );