- update user32 winetest

svn path=/trunk/; revision=37702
This commit is contained in:
Kamil Hornicek 2008-11-28 12:02:57 +00:00
parent 017c4d5476
commit acffd663c1
20 changed files with 4031 additions and 784 deletions

View file

@ -108,14 +108,14 @@ static void test_parameters(PBROADCAST broadcast, const char *functionname)
skip("%s is not implemented\n", functionname); skip("%s is not implemented\n", functionname);
return; return;
} }
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError()); ok(!ret || broken(ret), "Returned: %d\n", ret);
ok(!ret, "Returned: %d\n", ret); if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
SetLastError(0xcafebabe); SetLastError(0xcafebabe);
recips = BSM_APPLICATIONS; recips = BSM_APPLICATIONS;
ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 ); ret = broadcast( 0x80000000, &recips, WM_NULL, 0, 0 );
ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError()); ok(!ret || broken(ret), "Returned: %d\n", ret);
ok(!ret, "Returned: %d\n", ret); if (!ret) ok(GetLastError() == ERROR_INVALID_PARAMETER, "Last error: %08x\n", GetLastError());
#if 0 /* TODO: Check the hang flags */ #if 0 /* TODO: Check the hang flags */
SetLastError(0xcafebabe); SetLastError(0xcafebabe);
@ -150,8 +150,11 @@ static void test_parameters(PBROADCAST broadcast, const char *functionname)
ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
PulseEvent(hevent); PulseEvent(hevent);
SetLastError( 0xdeadbeef );
recips = BSM_APPLICATIONS; recips = BSM_APPLICATIONS;
ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 ); ret = broadcast( BSF_POSTMESSAGE|BSF_SENDNOTIFYMESSAGE, &recips, WM_NULL, 100, 0 );
if (ret)
{
ok(ret==1, "Returned: %d\n", ret); ok(ret==1, "Returned: %d\n", ret);
ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_OBJECT_0, "Synchronous message sent instead\n");
PulseEvent(hevent); PulseEvent(hevent);
@ -167,6 +170,9 @@ static void test_parameters(PBROADCAST broadcast, const char *functionname)
ok(!ret, "Returned: %d\n", ret); ok(!ret, "Returned: %d\n", ret);
ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
PulseEvent(hevent); PulseEvent(hevent);
}
else /* BSF_SENDNOTIFYMESSAGE not supported on NT4 */
ok( GetLastError() == ERROR_INVALID_PARAMETER, "failed with err %u\n", GetLastError() );
recips = BSM_APPLICATIONS; recips = BSM_APPLICATIONS;
ret = broadcast( 0, &recips, WM_NULL, 100, 0 ); ret = broadcast( 0, &recips, WM_NULL, 100, 0 );
@ -264,6 +270,9 @@ static void test_noprivileges(void)
DWORD recips; DWORD recips;
BOOL ret; BOOL ret;
static const DWORD BSM_ALL_RECIPS = BSM_VXDS | BSM_NETDRIVER |
BSM_INSTALLABLEDRIVERS | BSM_APPLICATIONS;
pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken"); pOpenProcessToken = (void *)GetProcAddress(advapi32, "OpenProcessToken");
pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges"); pAdjustTokenPrivileges = (void *)GetProcAddress(advapi32, "AdjustTokenPrivileges");
if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) if (!pOpenProcessToken || !pAdjustTokenPrivileges || !pOpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token))
@ -282,41 +291,44 @@ static void test_noprivileges(void)
recips = BSM_ALLDESKTOPS; recips = BSM_ALLDESKTOPS;
ResetEvent(hevent); ResetEvent(hevent);
ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "Last error: %08x\n", GetLastError()); ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
ok(ret==1, "Returned: %d\n", ret);
ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
ok(recips == BSM_ALLDESKTOPS, "Received by: %08x\n", recips); ok(recips == BSM_ALLDESKTOPS ||
recips == BSM_ALL_RECIPS, /* win2k3 */
"Received by: %08x\n", recips);
PulseEvent(hevent); PulseEvent(hevent);
/* Wine sets last error to 0, so just use that one as token here so it doesn't fail */ SetLastError(0xcafebabe);
SetLastError(0);
recips = BSM_ALLCOMPONENTS; recips = BSM_ALLCOMPONENTS;
ResetEvent(hevent); ResetEvent(hevent);
ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
ok(!GetLastError(), "Last error: %08x\n", GetLastError()); ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
ok(ret==1, "Returned: %d\n", ret);
ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
ok(recips == BSM_ALLCOMPONENTS, "Received by: %08x\n", recips); ok(recips == BSM_ALLCOMPONENTS ||
recips == BSM_ALL_RECIPS, /* win2k3 */
"Received by: %08x\n", recips);
PulseEvent(hevent); PulseEvent(hevent);
SetLastError(0xcafebabe); SetLastError(0xcafebabe);
recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS; recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
ResetEvent(hevent); ResetEvent(hevent);
ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL ); ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, 0, NULL );
todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "Last error: %08x\n", GetLastError()); ok(ret==1, "Returned: %d error %u\n", ret, GetLastError());
ok(ret==1, "Returned: %d\n", ret);
ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS), "Received by: %08x\n", recips); ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
recips == BSM_APPLICATIONS, /* win2k3 */
"Received by: %08x\n", recips);
PulseEvent(hevent); PulseEvent(hevent);
SetLastError(0xcafebabe); SetLastError(0xcafebabe);
recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS; recips = BSM_ALLDESKTOPS|BSM_APPLICATIONS;
ResetEvent(hevent); ResetEvent(hevent);
ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL ); ret = pBroadcastExW( BSF_QUERY, &recips, WM_NULL, 100, BROADCAST_QUERY_DENY, NULL );
todo_wine ok(GetLastError() == ERROR_PRIVILEGE_NOT_HELD, "Last error: %08x\n", GetLastError());
ok(!ret, "Returned: %d\n", ret); ok(!ret, "Returned: %d\n", ret);
ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n"); ok(WaitForSingleObject(hevent, 0) != WAIT_TIMEOUT, "Asynchronous message sent instead\n");
ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS), "Received by: %08x\n", recips); ok(recips == (BSM_ALLDESKTOPS|BSM_APPLICATIONS) ||
recips == BSM_APPLICATIONS, /* win2k3 */
"Received by: %08x\n", recips);
PulseEvent(hevent); PulseEvent(hevent);
} }

View file

@ -570,13 +570,14 @@ static void test_instances(void)
static void test_builtinproc(void) static void test_builtinproc(void)
{ {
/* Edit behaves differently. ScrollBar have currently only a Unicode winproc */ /* Edit behaves differently */
static const CHAR NORMAL_CLASSES[][10] = { static const CHAR NORMAL_CLASSES[][10] = {
"Button", "Button",
"Static", "Static",
"ComboBox", "ComboBox",
"ComboLBox", "ComboLBox",
"ListBox", "ListBox",
"ScrollBar",
"#32770", /* dialog */ "#32770", /* dialog */
}; };
static const int NUM_NORMAL_CLASSES = (sizeof(NORMAL_CLASSES)/sizeof(NORMAL_CLASSES[0])); static const int NUM_NORMAL_CLASSES = (sizeof(NORMAL_CLASSES)/sizeof(NORMAL_CLASSES[0]));
@ -796,7 +797,7 @@ static BOOL RegisterTestDialog(HINSTANCE hInstance)
wcx.hInstance = hInstance; wcx.hInstance = hInstance;
wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcx.hCursor = LoadCursor(NULL, IDC_ARROW); wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wcx.hbrBackground = GetStockObject(WHITE_BRUSH);
wcx.lpszClassName = "TestDialog"; wcx.lpszClassName = "TestDialog";
wcx.lpszMenuName = "TestDialog"; wcx.lpszMenuName = "TestDialog";
wcx.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(5), wcx.hIconSm = (HICON)LoadImage(hInstance, MAKEINTRESOURCE(5),
@ -813,7 +814,7 @@ static BOOL RegisterTestDialog(HINSTANCE hInstance)
/* test registering a dialog box created by using the CLASS directive in a /* test registering a dialog box created by using the CLASS directive in a
resource file, then test creating the dialog using CreateDialogParam. */ resource file, then test creating the dialog using CreateDialogParam. */
static void WINAPI CreateDialogParamTest(HINSTANCE hInstance) static void CreateDialogParamTest(HINSTANCE hInstance)
{ {
HWND hWndMain; HWND hWndMain;

View file

@ -265,6 +265,103 @@ static void test_CBN_SELCHANGE(void)
test_selection(CBS_DROPDOWNLIST, text, sel_2, sel_2); test_selection(CBS_DROPDOWNLIST, text, sel_2, sel_2);
} }
static void test_WM_LBUTTONDOWN(void)
{
HWND hCombo, hEdit, hList;
COMBOBOXINFO cbInfo;
UINT x, y, item_height;
LRESULT result;
int i, idx;
RECT rect;
CHAR buffer[3];
static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
static const CHAR stringFormat[] = "%2d";
BOOL ret;
BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
if (!pGetComboBoxInfo){
win_skip("GetComboBoxInfo is not available\n");
return;
}
hCombo = CreateWindow("ComboBox", "Combo", WS_VISIBLE|WS_CHILD|CBS_DROPDOWN,
0, 0, 200, 150, hMainWnd, (HMENU)COMBO_ID, NULL, 0);
for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
sprintf(buffer, stringFormat, choices[i]);
result = SendMessageA(hCombo, CB_ADDSTRING, 0, (LPARAM)buffer);
ok(result == i,
"Failed to add item %d\n", i);
}
cbInfo.cbSize = sizeof(COMBOBOXINFO);
SetLastError(0xdeadbeef);
ret = pGetComboBoxInfo(hCombo, &cbInfo);
ok(ret, "Failed to get combobox info structure. LastError=%d\n",
GetLastError());
hEdit = cbInfo.hwndItem;
hList = cbInfo.hwndList;
trace("hMainWnd=%x, hCombo=%x, hList=%x, hEdit=%x\n",
(UINT)hMainWnd, (UINT)hCombo, (UINT)hList, (UINT)hEdit);
ok(GetFocus() == hMainWnd, "Focus not on Main Window, instead on %x\n",
(UINT)GetFocus());
/* Click on the button to drop down the list */
x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
result = SendMessage(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
GetLastError());
ok(SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
"The dropdown list should have appeared after clicking the button.\n");
ok(GetFocus() == hEdit,
"Focus not on ComboBox's Edit Control, instead on %x\n",
(UINT)GetFocus());
result = SendMessage(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hEdit,
"Focus not on ComboBox's Edit Control, instead on %x\n",
(UINT)GetFocus());
/* Click on the 5th item in the list */
item_height = SendMessage(hCombo, CB_GETITEMHEIGHT, 0, 0);
ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
x = rect.left + (rect.right-rect.left)/2;
y = item_height/2 + item_height*4;
result = SendMessage(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hEdit,
"Focus not on ComboBox's Edit Control, instead on %x\n",
(UINT)GetFocus());
result = SendMessage(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hEdit,
"Focus not on ComboBox's Edit Control, instead on %x\n",
(UINT)GetFocus());
ok(SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
"The dropdown list should still be visible.\n");
result = SendMessage(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hEdit,
"Focus not on ComboBox's Edit Control, instead on %x\n",
(UINT)GetFocus());
ok(!SendMessage(hCombo, CB_GETDROPPEDSTATE, 0, 0),
"The dropdown list should have been rolled up.\n");
idx = SendMessage(hCombo, CB_GETCURSEL, 0, 0);
ok(idx, "Current Selection: expected %d, got %d\n", 4, idx);
DestroyWindow(hCombo);
}
START_TEST(combo) START_TEST(combo)
{ {
hMainWnd = CreateWindow("static", "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0); hMainWnd = CreateWindow("static", "Test", WS_OVERLAPPEDWINDOW, 10, 10, 300, 300, NULL, NULL, NULL, 0);
@ -275,6 +372,7 @@ START_TEST(combo)
test_setitemheight(CBS_DROPDOWN); test_setitemheight(CBS_DROPDOWN);
test_setitemheight(CBS_DROPDOWNLIST); test_setitemheight(CBS_DROPDOWNLIST);
test_CBN_SELCHANGE(); test_CBN_SELCHANGE();
test_WM_LBUTTONDOWN();
DestroyWindow(hMainWnd); DestroyWindow(hMainWnd);
} }

View file

@ -76,11 +76,10 @@ static LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARA
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DestroyCursor((HCURSOR) lParam); ret = DestroyCursor((HCURSOR) lParam);
error = GetLastError(); error = GetLastError();
todo_wine { todo_wine ok(!ret || broken(ret) /* win9x */, "DestroyCursor on the active cursor succeeded.\n");
ok(!ret, "DestroyCursor on the active cursor succeeded.\n"); ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD ||
ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD, error == 0xdeadbeef, /* vista */
"Last error: %u\n", error); "Last error: %u\n", error);
}
return TRUE; return TRUE;
case WM_DESTROY: case WM_DESTROY:
PostQuitMessage(0); PostQuitMessage(0);
@ -132,7 +131,7 @@ static void do_child(void)
PostMessage(parent, PROC_INIT, (WPARAM) child, 0); PostMessage(parent, PROC_INIT, (WPARAM) child, 0);
/* Receive messages. */ /* Receive messages. */
while ((ret = GetMessage(&msg, child, 0, 0))) while ((ret = GetMessage(&msg, 0, 0, 0)))
{ {
ok(ret != -1, "GetMessage failed. Error: %u\n", GetLastError()); ok(ret != -1, "GetMessage failed. Error: %u\n", GetLastError());
TranslateMessage(&msg); TranslateMessage(&msg);
@ -233,7 +232,7 @@ static void test_CopyImage_Check(HBITMAP bitmap, UINT flags, INT copyWidth, INT
BOOL orig_is_dib; BOOL orig_is_dib;
BOOL copy_is_dib; BOOL copy_is_dib;
copy = (HBITMAP) CopyImage(bitmap, IMAGE_BITMAP, copyWidth, copyHeight, flags); copy = CopyImage(bitmap, IMAGE_BITMAP, copyWidth, copyHeight, flags);
ok(copy != NULL, "CopyImage() failed\n"); ok(copy != NULL, "CopyImage() failed\n");
if (copy != NULL) if (copy != NULL)
{ {
@ -504,13 +503,14 @@ static void test_CreateIcon(void)
static const BYTE bmp_bits[1024]; static const BYTE bmp_bits[1024];
HICON hIcon; HICON hIcon;
HBITMAP hbmMask, hbmColor; HBITMAP hbmMask, hbmColor;
BITMAPINFO *bmpinfo;
ICONINFO info; ICONINFO info;
HDC hdc; HDC hdc;
void *bits;
UINT display_bpp; UINT display_bpp;
hdc = GetDC(0); hdc = GetDC(0);
display_bpp = GetDeviceCaps(hdc, BITSPIXEL); display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
ReleaseDC(0, hdc);
/* these crash under XP /* these crash under XP
hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, NULL); hIcon = CreateIcon(0, 16, 16, 1, 1, bmp_bits, NULL);
@ -581,6 +581,78 @@ static void test_CreateIcon(void)
DeleteObject(hbmMask); DeleteObject(hbmMask);
DeleteObject(hbmColor); DeleteObject(hbmColor);
/* test creating an icon from a DIB section */
bmpinfo = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, FIELD_OFFSET(BITMAPINFO,bmiColors[256]));
bmpinfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpinfo->bmiHeader.biWidth = 32;
bmpinfo->bmiHeader.biHeight = 32;
bmpinfo->bmiHeader.biPlanes = 1;
bmpinfo->bmiHeader.biBitCount = 8;
bmpinfo->bmiHeader.biCompression = BI_RGB;
hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
ok(hbmColor != NULL, "Expected a handle to the DIB\n");
if (bits)
memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
bmpinfo->bmiHeader.biBitCount = 1;
hbmMask = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
ok(hbmMask != NULL, "Expected a handle to the DIB\n");
if (bits)
memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
info.fIcon = TRUE;
info.xHotspot = 8;
info.yHotspot = 8;
info.hbmMask = hbmColor;
info.hbmColor = hbmMask;
SetLastError(0xdeadbeaf);
hIcon = CreateIconIndirect(&info);
ok(hIcon != 0, "CreateIconIndirect failed\n");
test_icon_info(hIcon, 32, 32, 8);
DestroyIcon(hIcon);
DeleteObject(hbmColor);
bmpinfo->bmiHeader.biBitCount = 16;
hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
ok(hbmColor != NULL, "Expected a handle to the DIB\n");
if (bits)
memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
info.fIcon = TRUE;
info.xHotspot = 8;
info.yHotspot = 8;
info.hbmMask = hbmColor;
info.hbmColor = hbmMask;
SetLastError(0xdeadbeaf);
hIcon = CreateIconIndirect(&info);
ok(hIcon != 0, "CreateIconIndirect failed\n");
test_icon_info(hIcon, 32, 32, 8);
DestroyIcon(hIcon);
DeleteObject(hbmColor);
bmpinfo->bmiHeader.biBitCount = 32;
hbmColor = CreateDIBSection( hdc, bmpinfo, DIB_RGB_COLORS, &bits, NULL, 0 );
ok(hbmColor != NULL, "Expected a handle to the DIB\n");
if (bits)
memset( bits, 0x55, 32 * 32 * bmpinfo->bmiHeader.biBitCount / 8 );
info.fIcon = TRUE;
info.xHotspot = 8;
info.yHotspot = 8;
info.hbmMask = hbmColor;
info.hbmColor = hbmMask;
SetLastError(0xdeadbeaf);
hIcon = CreateIconIndirect(&info);
ok(hIcon != 0, "CreateIconIndirect failed\n");
test_icon_info(hIcon, 32, 32, 8);
DestroyIcon(hIcon);
DeleteObject(hbmMask);
DeleteObject(hbmColor);
HeapFree( GetProcessHeap(), 0, bmpinfo );
ReleaseDC(0, hdc);
} }
/* Shamelessly ripped from dlls/oleaut32/tests/olepicture.c */ /* Shamelessly ripped from dlls/oleaut32/tests/olepicture.c */
@ -664,7 +736,10 @@ static void test_LoadImageFile(const unsigned char * image_data,
handle = LoadImageA(NULL, filename, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE); handle = LoadImageA(NULL, filename, IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
ok(handle == NULL, "LoadImage(%s) as IMAGE_CURSOR succeeded incorrectly.\n", ext); ok(handle == NULL, "LoadImage(%s) as IMAGE_CURSOR succeeded incorrectly.\n", ext);
error = GetLastError(); error = GetLastError();
ok(error == 0, "Last error: %u\n", error); ok(error == 0 ||
broken(error == 0xdeadbeef) || /* Win9x */
broken(error == ERROR_BAD_PATHNAME), /* Win98, WinMe */
"Last error: %u\n", error);
if (handle != NULL) DestroyCursor(handle); if (handle != NULL) DestroyCursor(handle);
/* Load as icon. For all tested formats, this should fail */ /* Load as icon. For all tested formats, this should fail */
@ -672,7 +747,10 @@ static void test_LoadImageFile(const unsigned char * image_data,
handle = LoadImageA(NULL, filename, IMAGE_ICON, 0, 0, LR_LOADFROMFILE); handle = LoadImageA(NULL, filename, IMAGE_ICON, 0, 0, LR_LOADFROMFILE);
ok(handle == NULL, "LoadImage(%s) as IMAGE_ICON succeeded incorrectly.\n", ext); ok(handle == NULL, "LoadImage(%s) as IMAGE_ICON succeeded incorrectly.\n", ext);
error = GetLastError(); error = GetLastError();
ok(error == 0, "Last error: %u\n", error); ok(error == 0 ||
broken(error == 0xdeadbeef) || /* Win9x */
broken(error == ERROR_BAD_PATHNAME), /* Win98, WinMe */
"Last error: %u\n", error);
if (handle != NULL) DestroyIcon(handle); if (handle != NULL) DestroyIcon(handle);
/* Load as bitmap. Should succeed if bmp, fail for everything else */ /* Load as bitmap. Should succeed if bmp, fail for everything else */
@ -682,7 +760,9 @@ static void test_LoadImageFile(const unsigned char * image_data,
ok(handle != NULL, "LoadImage(%s) as IMAGE_BITMAP failed.\n", ext); ok(handle != NULL, "LoadImage(%s) as IMAGE_BITMAP failed.\n", ext);
else ok(handle == NULL, "LoadImage(%s) as IMAGE_BITMAP succeeded incorrectly.\n", ext); else ok(handle == NULL, "LoadImage(%s) as IMAGE_BITMAP succeeded incorrectly.\n", ext);
error = GetLastError(); error = GetLastError();
ok(error == 0, "Last error: %u\n", error); ok(error == 0 ||
error == 0xdeadbeef, /* Win9x, WinMe */
"Last error: %u\n", error);
if (handle != NULL) DeleteObject(handle); if (handle != NULL) DeleteObject(handle);
DeleteFileA(filename); DeleteFileA(filename);
@ -741,15 +821,16 @@ static void test_LoadImage(void)
/* Test loading an icon as a cursor. */ /* Test loading an icon as a cursor. */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
handle = LoadImageA(NULL, "icon.ico", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE); handle = LoadImageA(NULL, "icon.ico", IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE);
todo_wine
ok(handle != NULL, "LoadImage() failed.\n"); ok(handle != NULL, "LoadImage() failed.\n");
error = GetLastError(); error = GetLastError();
ok(error == 0, "Last error: %u\n", error); ok(error == 0 ||
broken(error == 0xdeadbeef) || /* Win9x */
broken(error == ERROR_BAD_PATHNAME), /* Win98, WinMe */
"Last error: %u\n", error);
/* Test the icon information. */ /* Test the icon information. */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = GetIconInfo(handle, &icon_info); ret = GetIconInfo(handle, &icon_info);
todo_wine
ok(ret, "GetIconInfo() failed.\n"); ok(ret, "GetIconInfo() failed.\n");
error = GetLastError(); error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error); ok(error == 0xdeadbeef, "Last error: %u\n", error);
@ -766,7 +847,6 @@ static void test_LoadImage(void)
/* Clean up. */ /* Clean up. */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DestroyCursor(handle); ret = DestroyCursor(handle);
todo_wine
ok(ret, "DestroyCursor() failed.\n"); ok(ret, "DestroyCursor() failed.\n");
error = GetLastError(); error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error); ok(error == 0xdeadbeef, "Last error: %u\n", error);
@ -781,6 +861,99 @@ static void test_LoadImage(void)
test_LoadImageFile(pngimage, sizeof(pngimage), "png", 0); test_LoadImageFile(pngimage, sizeof(pngimage), "png", 0);
} }
static void test_CreateIconFromResource(void)
{
HANDLE handle;
BOOL ret;
DWORD error;
BITMAPINFOHEADER *icon_header;
INT16 *hotspot;
ICONINFO icon_info;
#define ICON_RES_WIDTH 32
#define ICON_RES_HEIGHT 32
#define ICON_RES_AND_SIZE (ICON_WIDTH*ICON_HEIGHT/8)
#define ICON_RES_BPP 32
#define ICON_RES_SIZE \
(sizeof(BITMAPINFOHEADER) + ICON_AND_SIZE + ICON_AND_SIZE*ICON_BPP)
#define CRSR_RES_SIZE (2*sizeof(INT16) + ICON_RES_SIZE)
/* Set icon data. */
hotspot = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, CRSR_RES_SIZE);
/* Cursor resources have an extra hotspot, icon resources not. */
hotspot[0] = 3;
hotspot[1] = 3;
icon_header = (BITMAPINFOHEADER *) (hotspot + 2);
icon_header->biSize = sizeof(BITMAPINFOHEADER);
icon_header->biWidth = ICON_WIDTH;
icon_header->biHeight = ICON_HEIGHT*2;
icon_header->biPlanes = 1;
icon_header->biBitCount = ICON_BPP;
icon_header->biSizeImage = 0; /* Uncompressed bitmap. */
/* Test creating a cursor. */
SetLastError(0xdeadbeef);
handle = CreateIconFromResource((PBYTE) hotspot, CRSR_RES_SIZE, FALSE, 0x00030000);
ok(handle != NULL, "Create cursor failed.\n");
/* Test the icon information. */
SetLastError(0xdeadbeef);
ret = GetIconInfo(handle, &icon_info);
ok(ret, "GetIconInfo() failed.\n");
error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error);
if (ret)
{
ok(icon_info.fIcon == FALSE, "fIcon != FALSE.\n");
ok(icon_info.xHotspot == 3, "xHotspot is %u.\n", icon_info.xHotspot);
ok(icon_info.yHotspot == 3, "yHotspot is %u.\n", icon_info.yHotspot);
ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
}
/* Clean up. */
SetLastError(0xdeadbeef);
ret = DestroyCursor(handle);
ok(ret, "DestroyCursor() failed.\n");
error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error);
/* Test creating an icon. */
SetLastError(0xdeadbeef);
handle = CreateIconFromResource((PBYTE) icon_header, ICON_RES_SIZE, TRUE,
0x00030000);
ok(handle != NULL, "Create icon failed.\n");
/* Test the icon information. */
SetLastError(0xdeadbeef);
ret = GetIconInfo(handle, &icon_info);
ok(ret, "GetIconInfo() failed.\n");
error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error);
if (ret)
{
ok(icon_info.fIcon == TRUE, "fIcon != TRUE.\n");
/* Icons always have hotspot in the middle */
ok(icon_info.xHotspot == ICON_WIDTH/2, "xHotspot is %u.\n", icon_info.xHotspot);
ok(icon_info.yHotspot == ICON_HEIGHT/2, "yHotspot is %u.\n", icon_info.yHotspot);
ok(icon_info.hbmColor != NULL, "No hbmColor!\n");
ok(icon_info.hbmMask != NULL, "No hbmMask!\n");
}
/* Clean up. */
SetLastError(0xdeadbeef);
ret = DestroyCursor(handle);
ok(ret, "DestroyCursor() failed.\n");
error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error);
HeapFree(GetProcessHeap(), 0, hotspot);
}
static void test_DestroyCursor(void) static void test_DestroyCursor(void)
{ {
static const BYTE bmp_bits[4096]; static const BYTE bmp_bits[4096];
@ -810,13 +983,13 @@ static void test_DestroyCursor(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DestroyCursor(cursor); ret = DestroyCursor(cursor);
ok(!ret, "DestroyCursor on the active cursor succeeded\n"); ok(!ret || broken(ret) /* succeeds on win9x */, "DestroyCursor on the active cursor succeeded\n");
error = GetLastError(); error = GetLastError();
ok(error == 0xdeadbeef, "Last error: %u\n", error); ok(error == 0xdeadbeef, "Last error: %u\n", error);
if (!ret)
{
cursor2 = GetCursor(); cursor2 = GetCursor();
ok(cursor2 == cursor, "Active was set to %p when trying to destroy it\n", cursor2); ok(cursor2 == cursor, "Active was set to %p when trying to destroy it\n", cursor2);
SetCursor(NULL); SetCursor(NULL);
/* Trying to destroy the cursor properly fails now with /* Trying to destroy the cursor properly fails now with
@ -827,7 +1000,9 @@ static void test_DestroyCursor(void)
todo_wine { todo_wine {
ok(!ret, "DestroyCursor succeeded.\n"); ok(!ret, "DestroyCursor succeeded.\n");
error = GetLastError(); error = GetLastError();
ok(error == ERROR_INVALID_CURSOR_HANDLE, "Last error: 0x%08x\n", error); ok(error == ERROR_INVALID_CURSOR_HANDLE || error == 0xdeadbeef, /* vista */
"Last error: 0x%08x\n", error);
}
} }
DeleteObject(cursorInfo.hbmMask); DeleteObject(cursorInfo.hbmMask);
@ -838,7 +1013,7 @@ static void test_DestroyCursor(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DestroyCursor(cursor); ret = DestroyCursor(cursor);
ok(ret, "DestroyCursor on the active cursor failed.\n"); ok(ret || broken(!ret) /* fails on win9x */, "DestroyCursor on the active cursor failed.\n");
error = GetLastError(); error = GetLastError();
ok(error == 0xdeadbeef, "Last error: 0x%08x\n", error); ok(error == 0xdeadbeef, "Last error: 0x%08x\n", error);
@ -885,6 +1060,7 @@ START_TEST(cursoricon)
test_initial_cursor(); test_initial_cursor();
test_CreateIcon(); test_CreateIcon();
test_LoadImage(); test_LoadImage();
test_CreateIconFromResource();
test_DestroyCursor(); test_DestroyCursor();
do_parent(); do_parent();
test_child_process(); test_child_process();

View file

@ -73,6 +73,12 @@ static void create_dde_window(HWND *hwnd, LPCSTR name, WNDPROC wndproc)
assert(*hwnd); assert(*hwnd);
} }
static void destroy_dde_window(HWND *hwnd, LPCSTR name)
{
DestroyWindow(*hwnd);
UnregisterClass(name, GetModuleHandleA(0));
}
static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{ {
UINT_PTR lo, hi; UINT_PTR lo, hi;
@ -178,8 +184,10 @@ static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPA
ok(poke->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", poke->cfFormat); ok(poke->cfFormat == CF_TEXT, "Expected CF_TEXT, got %d\n", poke->cfFormat);
if (msg_index == 5) if (msg_index == 5)
ok(lstrcmpA((LPSTR)poke->Value, "poke data\r\n"), {
"Expected 'poke data\\r\\n', got %s\n", poke->Value); size = GlobalSize((HGLOBAL)lo);
ok(size == 4, "got %d\n", size);
}
else else
ok(!lstrcmpA((LPSTR)poke->Value, "poke data\r\n"), ok(!lstrcmpA((LPSTR)poke->Value, "poke data\r\n"),
"Expected 'poke data\\r\\n', got %s\n", poke->Value); "Expected 'poke data\\r\\n', got %s\n", poke->Value);
@ -227,20 +235,21 @@ static LRESULT WINAPI dde_server_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPA
return DefWindowProcA(hwnd, msg, wparam, lparam); return DefWindowProcA(hwnd, msg, wparam, lparam);
} }
static void test_msg_server(HANDLE hproc) static void test_msg_server(HANDLE hproc, HANDLE hthread)
{ {
MSG msg; MSG msg;
HWND hwnd; HWND hwnd;
DWORD res; DWORD res;
create_dde_window(&hwnd, "dde_server", dde_server_wndproc); create_dde_window(&hwnd, "dde_server", dde_server_wndproc);
ResumeThread( hthread );
while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0) while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
{ {
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
} }
DestroyWindow(hwnd); destroy_dde_window(&hwnd, "dde_server");
GetExitCodeProcess( hproc, &res ); GetExitCodeProcess( hproc, &res );
ok( !res, "client failed with %u error(s)\n", res ); ok( !res, "client failed with %u error(s)\n", res );
} }
@ -288,11 +297,8 @@ static void test_ddeml_client(void)
DdeGetLastError(client_pid); DdeGetLastError(client_pid);
hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res); hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
ret = DdeGetLastError(client_pid); ret = DdeGetLastError(client_pid);
ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret); ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
todo_wine ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %08x\n", res);
{
ok(res == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %08x\n", res);
}
if (hdata == NULL) if (hdata == NULL)
ok(FALSE, "hdata is NULL\n"); ok(FALSE, "hdata is NULL\n");
else else
@ -310,11 +316,9 @@ static void test_ddeml_client(void)
DdeGetLastError(client_pid); DdeGetLastError(client_pid);
hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res); hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
ret = DdeGetLastError(client_pid); ret = DdeGetLastError(client_pid);
todo_wine
{
ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res); ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res);
todo_wine
ok(ret == DMLERR_MEMORY_ERROR, "Expected DMLERR_MEMORY_ERROR, got %d\n", ret); ok(ret == DMLERR_MEMORY_ERROR, "Expected DMLERR_MEMORY_ERROR, got %d\n", ret);
}
if (hdata == NULL) if (hdata == NULL)
ok(FALSE, "hdata is NULL\n"); ok(FALSE, "hdata is NULL\n");
else else
@ -333,10 +337,7 @@ static void test_ddeml_client(void)
hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res); hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
ret = DdeGetLastError(client_pid); ret = DdeGetLastError(client_pid);
ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret); ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
todo_wine
{
ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res); ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res);
}
if (hdata == NULL) if (hdata == NULL)
ok(FALSE, "hdata is NULL\n"); ok(FALSE, "hdata is NULL\n");
else else
@ -438,10 +439,7 @@ static void test_ddeml_client(void)
ret = DdeGetLastError(client_pid); ret = DdeGetLastError(client_pid);
ok(op == NULL, "Expected NULL, got %p\n", op); ok(op == NULL, "Expected NULL, got %p\n", op);
ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res); ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", res);
todo_wine
{
ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret); ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
}
DdeFreeStringHandle(client_pid, topic); DdeFreeStringHandle(client_pid, topic);
DdeFreeDataHandle(hdata); DdeFreeDataHandle(hdata);
@ -454,10 +452,7 @@ static void test_ddeml_client(void)
hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res); hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
ret = DdeGetLastError(client_pid); ret = DdeGetLastError(client_pid);
ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret); ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
todo_wine
{
ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res); ok(res == DDE_FNOTPROCESSED, "Expected DDE_FNOTPROCESSED, got %d\n", res);
}
if (hdata == NULL) if (hdata == NULL)
ok(FALSE, "hdata is NULL\n"); ok(FALSE, "hdata is NULL\n");
else else
@ -662,7 +657,6 @@ static HDDEDATA CALLBACK server_ddeml_callback(UINT uType, UINT uFmt, HCONV hcon
if (msg_index == 5) if (msg_index == 5)
{ {
todo_wine
{ {
ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str); ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str);
ok(size == 1, "Expected 1, got %d\n", size); ok(size == 1, "Expected 1, got %d\n", size);
@ -698,16 +692,12 @@ static HDDEDATA CALLBACK server_ddeml_callback(UINT uType, UINT uFmt, HCONV hcon
ptr = (LPSTR)DdeAccessData(hdata, &size); ptr = (LPSTR)DdeAccessData(hdata, &size);
ok(!lstrcmpA(ptr, "poke data\r\n"), "Expected 'poke data\\r\\n', got %s\n", ptr); ok(!lstrcmpA(ptr, "poke data\r\n"), "Expected 'poke data\\r\\n', got %s\n", ptr);
todo_wine ok(size == 12, "Expected 12, got %d\n", size);
{
ok(size == 14, "Expected 14, got %d\n", size);
}
DdeUnaccessData(hdata); DdeUnaccessData(hdata);
size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI); size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
if (msg_index == 7) if (msg_index == 7)
{ {
todo_wine
{ {
ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str); ok(!lstrcmpA(str, ""), "Expected empty string, got %s\n", str);
ok(size == 1, "Expected 1, got %d\n", size); ok(size == 1, "Expected 1, got %d\n", size);
@ -980,7 +970,7 @@ static HGLOBAL create_poke()
DDEPOKE *poke; DDEPOKE *poke;
DWORD size; DWORD size;
size = sizeof(DDEPOKE) + lstrlenA("poke data\r\n") + 1; size = FIELD_OFFSET(DDEPOKE, Value[sizeof("poke data\r\n")]);
hglobal = GlobalAlloc(GMEM_DDESHARE, size); hglobal = GlobalAlloc(GMEM_DDESHARE, size);
ok(hglobal != 0, "Expected non-NULL hglobal\n"); ok(hglobal != 0, "Expected non-NULL hglobal\n");
@ -1065,9 +1055,14 @@ static void test_msg_client()
/* WM_DDE_POKE, no ddepoke */ /* WM_DDE_POKE, no ddepoke */
lparam = PackDDElParam(WM_DDE_POKE, 0, item); lparam = PackDDElParam(WM_DDE_POKE, 0, item);
/* win9x returns 0 here and crashes in PostMessageA */
if (lparam) {
PostMessageA(server_hwnd, WM_DDE_POKE, (WPARAM)client_hwnd, lparam); PostMessageA(server_hwnd, WM_DDE_POKE, (WPARAM)client_hwnd, lparam);
flush_events(); flush_events();
}
else
win_skip("no lparam for WM_DDE_POKE\n");
/* WM_DDE_POKE, no item */ /* WM_DDE_POKE, no item */
lparam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)hglobal, 0); lparam = PackDDElParam(WM_DDE_POKE, (UINT_PTR)hglobal, 0);
@ -1123,7 +1118,7 @@ static void test_msg_client()
flush_events(); flush_events();
DestroyWindow(client_hwnd); destroy_dde_window(&client_hwnd, "dde_client");
} }
static LRESULT WINAPI hook_dde_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) static LRESULT WINAPI hook_dde_client_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
@ -1186,7 +1181,6 @@ static LRESULT WINAPI dde_server_wndprocW(HWND hwnd, UINT msg, WPARAM wparam, LP
ack.fBusy = 0; ack.fBusy = 0;
cmd = GlobalLock((HGLOBAL)hi); cmd = GlobalLock((HGLOBAL)hi);
if (!cmd || (lstrcmpA(cmd, exec_cmdA) && lstrcmpW((LPCWSTR)cmd, exec_cmdW))) if (!cmd || (lstrcmpA(cmd, exec_cmdA) && lstrcmpW((LPCWSTR)cmd, exec_cmdW)))
{ {
trace("ignoring unknown WM_DDE_EXECUTE command\n"); trace("ignoring unknown WM_DDE_EXECUTE command\n");
@ -1388,6 +1382,53 @@ todo_wine {
DestroyWindow(hwnd_server); DestroyWindow(hwnd_server);
} }
static void test_initialisation(void)
{
UINT ret;
DWORD res;
HDDEDATA hdata;
HSZ server, topic, item;
DWORD client_pid;
HCONV conversation;
/* Initialise without a valid server window. */
client_pid = 0;
ret = DdeInitializeA(&client_pid, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", ret);
server = DdeCreateStringHandleA(client_pid, "TestDDEService", CP_WINANSI);
topic = DdeCreateStringHandleA(client_pid, "TestDDETopic", CP_WINANSI);
DdeGetLastError(client_pid);
/* There is no server window so no conversation can be extracted */
conversation = DdeConnect(client_pid, server, topic, NULL);
ok(conversation == NULL, "Expected NULL conversation, %p\n", conversation);
ret = DdeGetLastError(client_pid);
ok(ret == DMLERR_NO_CONV_ESTABLISHED, "Expected DMLERR_NO_CONV_ESTABLISHED, got %d\n", ret);
DdeFreeStringHandle(client_pid, server);
item = DdeCreateStringHandleA(client_pid, "request", CP_WINANSI);
/* There is no converstation so an invalild parameter results */
res = 0xdeadbeef;
DdeGetLastError(client_pid);
hdata = DdeClientTransaction(NULL, 0, conversation, item, CF_TEXT, XTYP_REQUEST, default_timeout, &res);
ret = DdeGetLastError(client_pid);
todo_wine
ok(ret == DMLERR_INVALIDPARAMETER, "Expected DMLERR_INVALIDPARAMETER, got %d\n", ret);
ok(res == 0xdeadbeef, "Expected 0xdeadbeef, got %08x\n", res);
DdeFreeStringHandle(client_pid, server);
ret = DdeDisconnect(conversation);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ret = DdeUninitialize(client_pid);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
}
static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage) static void test_DdeCreateStringHandleW(DWORD dde_inst, int codepage)
{ {
static const WCHAR dde_string[] = {'D','D','E',' ','S','t','r','i','n','g',0}; static const WCHAR dde_string[] = {'D','D','E',' ','S','t','r','i','n','g',0};
@ -1486,15 +1527,9 @@ static void test_DdeCreateDataHandle(void)
item = DdeCreateStringHandleA(dde_inst, "item", CP_WINANSI); item = DdeCreateStringHandleA(dde_inst, "item", CP_WINANSI);
ok(item != NULL, "Expected non-NULL hsz\n"); ok(item != NULL, "Expected non-NULL hsz\n");
/* invalid instance id */ if (0) {
DdeGetLastError(dde_inst); /* do not test with an invalid instance id: that crashes on win9x */
hdata = DdeCreateDataHandle(0xdeadbeef, (LPBYTE)"data", MAX_PATH, 0, item, CF_TEXT, 0); hdata = DdeCreateDataHandle(0xdeadbeef, (LPBYTE)"data", MAX_PATH, 0, item, CF_TEXT, 0);
err = DdeGetLastError(dde_inst);
todo_wine
{
ok(hdata == NULL, "Expected NULL, got %p\n", hdata);
ok(err == DMLERR_INVALIDPARAMETER,
"Expected DMLERR_INVALIDPARAMETER, got %d\n", err);
} }
/* 0 instance id */ /* 0 instance id */
@ -1666,7 +1701,7 @@ static void test_DdeCreateStringHandle(void)
ret = DdeInitializeW(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0); ret = DdeInitializeW(&dde_inst, client_ddeml_callback, APPCMD_CLIENTONLY, 0);
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{ {
trace("Skipping the DDE test on a Win9x platform\n"); skip("DdeInitialize is unimplemented\n");
return; return;
} }
@ -1690,7 +1725,7 @@ static void test_FreeDDElParam(void)
HGLOBAL val, hglobal; HGLOBAL val, hglobal;
BOOL ret; BOOL ret;
ret = FreeDDElParam(WM_DDE_INITIATE, (LPARAM)NULL); ret = FreeDDElParam(WM_DDE_INITIATE, 0);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
hglobal = GlobalAlloc(GMEM_DDESHARE, 100); hglobal = GlobalAlloc(GMEM_DDESHARE, 100);
@ -1790,6 +1825,8 @@ static void test_PackDDElParam(void)
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
lparam = PackDDElParam(WM_DDE_ADVISE, 0xcafe, 0xbeef); lparam = PackDDElParam(WM_DDE_ADVISE, 0xcafe, 0xbeef);
/* win9x returns 0 here */
if (lparam) {
ptr = GlobalLock((HGLOBAL)lparam); ptr = GlobalLock((HGLOBAL)lparam);
ok(ptr != NULL, "Expected non-NULL ptr\n"); ok(ptr != NULL, "Expected non-NULL ptr\n");
ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]); ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
@ -1803,6 +1840,9 @@ static void test_PackDDElParam(void)
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo); ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi); ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
}
else
win_skip("no lparam for WM_DDE_ADVISE\n");
ret = FreeDDElParam(WM_DDE_ADVISE, lparam); ret = FreeDDElParam(WM_DDE_ADVISE, lparam);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
@ -1829,6 +1869,8 @@ static void test_PackDDElParam(void)
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
lparam = PackDDElParam(WM_DDE_ACK, 0xcafe, 0xbeef); lparam = PackDDElParam(WM_DDE_ACK, 0xcafe, 0xbeef);
/* win9x returns the input (0xbeef<<16 | 0xcafe) here */
if (lparam != 0xbeefcafe) {
ptr = GlobalLock((HGLOBAL)lparam); ptr = GlobalLock((HGLOBAL)lparam);
ok(ptr != NULL, "Expected non-NULL ptr\n"); ok(ptr != NULL, "Expected non-NULL ptr\n");
ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]); ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
@ -1850,8 +1892,13 @@ static void test_PackDDElParam(void)
ok(hglobal == (HGLOBAL)lparam, "Expected lparam, got %d\n", ret); ok(hglobal == (HGLOBAL)lparam, "Expected lparam, got %d\n", ret);
ok(GetLastError() == ERROR_INVALID_HANDLE, ok(GetLastError() == ERROR_INVALID_HANDLE,
"Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError()); "Expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
}
else
win_skip("got lparam 0x%lx for WM_DDE_ACK\n", lparam);
lparam = PackDDElParam(WM_DDE_DATA, 0xcafe, 0xbeef); lparam = PackDDElParam(WM_DDE_DATA, 0xcafe, 0xbeef);
/* win9x returns 0 here */
if (lparam) {
ptr = GlobalLock((HGLOBAL)lparam); ptr = GlobalLock((HGLOBAL)lparam);
ok(ptr != NULL, "Expected non-NULL ptr\n"); ok(ptr != NULL, "Expected non-NULL ptr\n");
ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]); ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
@ -1865,6 +1912,9 @@ static void test_PackDDElParam(void)
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo); ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi); ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
}
else
win_skip("no lparam for WM_DDE_DATA\n");
ret = FreeDDElParam(WM_DDE_DATA, lparam); ret = FreeDDElParam(WM_DDE_DATA, lparam);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
@ -1891,6 +1941,8 @@ static void test_PackDDElParam(void)
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
lparam = PackDDElParam(WM_DDE_POKE, 0xcafe, 0xbeef); lparam = PackDDElParam(WM_DDE_POKE, 0xcafe, 0xbeef);
/* win9x returns 0 here */
if (lparam) {
ptr = GlobalLock((HGLOBAL)lparam); ptr = GlobalLock((HGLOBAL)lparam);
ok(ptr != NULL, "Expected non-NULL ptr\n"); ok(ptr != NULL, "Expected non-NULL ptr\n");
ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]); ok(ptr[0] == 0xcafe, "Expected 0xcafe, got %08lx\n", ptr[0]);
@ -1904,6 +1956,9 @@ static void test_PackDDElParam(void)
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo); ok(lo == 0xcafe, "Expected 0xcafe, got %08lx\n", lo);
ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi); ok(hi == 0xbeef, "Expected 0xbeef, got %08lx\n", hi);
}
else
win_skip("no lparam for WM_DDE_POKE\n");
ret = FreeDDElParam(WM_DDE_POKE, lparam); ret = FreeDDElParam(WM_DDE_POKE, lparam);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
@ -1939,7 +1994,7 @@ static void test_UnpackDDElParam(void)
/* NULL lParam */ /* NULL lParam */
lo = 0xdead; lo = 0xdead;
hi = 0xbeef; hi = 0xbeef;
ret = UnpackDDElParam(WM_DDE_INITIATE, (LPARAM)NULL, &lo, &hi); ret = UnpackDDElParam(WM_DDE_INITIATE, 0, &lo, &hi);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret); ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
ok(lo == 0, "Expected 0, got %08lx\n", lo); ok(lo == 0, "Expected 0, got %08lx\n", lo);
ok(hi == 0, "Expected 0, got %08lx\n", hi); ok(hi == 0, "Expected 0, got %08lx\n", hi);
@ -1976,17 +2031,25 @@ static void test_UnpackDDElParam(void)
lo = 0xdead; lo = 0xdead;
hi = 0xbeef; hi = 0xbeef;
ret = UnpackDDElParam(WM_DDE_ADVISE, (LPARAM)NULL, &lo, &hi); ret = UnpackDDElParam(WM_DDE_ADVISE, 0, &lo, &hi);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ok(lo == 0, "Expected 0, got %08lx\n", lo); ok(lo == 0 ||
ok(hi == 0, "Expected 0, got %08lx\n", hi); broken(lo == 0xdead), /* win2k */
"Expected 0, got %08lx\n", lo);
ok(hi == 0 ||
broken(hi == 0xbeef), /* win2k */
"Expected 0, got %08lx\n", hi);
lo = 0xdead; lo = 0xdead;
hi = 0xbeef; hi = 0xbeef;
ret = UnpackDDElParam(WM_DDE_ADVISE, 0xcafebabe, &lo, &hi); ret = UnpackDDElParam(WM_DDE_ADVISE, 0xcafebabe, &lo, &hi);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ok(lo == 0, "Expected 0, got %08lx\n", lo); ok(lo == 0 ||
ok(hi == 0, "Expected 0, got %08lx\n", hi); broken(lo == 0xdead), /* win2k */
"Expected 0, got %08lx\n", lo);
ok(hi == 0 ||
broken(hi == 0xbeef), /* win2k */
"Expected 0, got %08lx\n", hi);
hglobal = GlobalAlloc(GMEM_DDESHARE, 2); hglobal = GlobalAlloc(GMEM_DDESHARE, 2);
ptr = GlobalLock(hglobal); ptr = GlobalLock(hglobal);
@ -2012,8 +2075,12 @@ static void test_UnpackDDElParam(void)
hi = 0xbeef; hi = 0xbeef;
ret = UnpackDDElParam(WM_DDE_ACK, 0xcafebabe, &lo, &hi); ret = UnpackDDElParam(WM_DDE_ACK, 0xcafebabe, &lo, &hi);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ok(lo == 0, "Expected 0, got %08lx\n", lo); ok(lo == 0 ||
ok(hi == 0, "Expected 0, got %08lx\n", hi); broken(lo == 0xdead), /* win2k */
"Expected 0, got %08lx\n", lo);
ok(hi == 0 ||
broken(hi == 0xbeef), /* win2k */
"Expected 0, got %08lx\n", hi);
lo = 0xdead; lo = 0xdead;
hi = 0xbeef; hi = 0xbeef;
@ -2026,8 +2093,12 @@ static void test_UnpackDDElParam(void)
hi = 0xbeef; hi = 0xbeef;
ret = UnpackDDElParam(WM_DDE_DATA, 0xcafebabe, &lo, &hi); ret = UnpackDDElParam(WM_DDE_DATA, 0xcafebabe, &lo, &hi);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ok(lo == 0, "Expected 0, got %08lx\n", lo); ok(lo == 0 ||
ok(hi == 0, "Expected 0, got %08lx\n", hi); broken(lo == 0xdead), /* win2k */
"Expected 0, got %08lx\n", lo);
ok(hi == 0 ||
broken(hi == 0xbeef), /* win2k */
"Expected 0, got %08lx\n", hi);
lo = 0xdead; lo = 0xdead;
hi = 0xbeef; hi = 0xbeef;
@ -2047,8 +2118,12 @@ static void test_UnpackDDElParam(void)
hi = 0xbeef; hi = 0xbeef;
ret = UnpackDDElParam(WM_DDE_POKE, 0xcafebabe, &lo, &hi); ret = UnpackDDElParam(WM_DDE_POKE, 0xcafebabe, &lo, &hi);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret); ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ok(lo == 0, "Expected 0, got %08lx\n", lo); ok(lo == 0 ||
ok(hi == 0, "Expected 0, got %08lx\n", hi); broken(lo == 0xdead), /* win2k */
"Expected 0, got %08lx\n", lo);
ok(hi == 0 ||
broken(hi == 0xbeef), /* win2k */
"Expected 0, got %08lx\n", hi);
lo = 0xdead; lo = 0xdead;
hi = 0xbeef; hi = 0xbeef;
@ -2065,6 +2140,270 @@ static void test_UnpackDDElParam(void)
ok(hi == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", hi); ok(hi == 0xcafebabe, "Expected 0xcafebabe, got %08lx\n", hi);
} }
static HDDEDATA CALLBACK server_end_to_end_callback(UINT uType, UINT uFmt, HCONV hconv,
HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
ULONG_PTR dwData1, ULONG_PTR dwData2)
{
DWORD size, rsize;
char str[MAX_PATH];
static int msg_index = 0;
static HCONV conversation = 0;
static char test_cmd[] = "test dde command";
static WCHAR test_cmd_w[] = {'t','e','s','t',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
static char test_service [] = "TestDDEService";
static char test_topic [] = "TestDDETopic";
msg_index++;
switch (uType)
{
case XTYP_REGISTER:
{
ok(msg_index == 1 || msg_index == 7 || msg_index == 13 || msg_index == 19,
"Expected 1, 7, 13 or 19, got %d\n", msg_index);
return (HDDEDATA)TRUE;
}
case XTYP_CONNECT:
{
ok(msg_index == 2 || msg_index == 8 || msg_index == 14 || msg_index == 20,
"Expected 2, 8, 14 or 20, got %d\n", msg_index);
ok(uFmt == 0, "Expected 0, got %d, msg_index=%d\n", uFmt, msg_index);
ok(hconv == 0, "Expected 0, got %p, msg_index=%d\n", hconv, msg_index);
ok(hdata == 0, "Expected 0, got %p, msg_index=%d\n", hdata, msg_index);
ok(dwData1 != 0, "Expected not 0, got %08lx, msg_index=%d\n", dwData1, msg_index);
ok(dwData2 == FALSE, "Expected FALSE, got %08lx, msg_index=%d\n", dwData2, msg_index);
size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
ok(!lstrcmpA(str, test_topic), "Expected %s, got %s, msg_index=%d\n",
test_topic, str, msg_index);
ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index);
size = DdeQueryStringA(server_pid, hsz2, str, MAX_PATH, CP_WINANSI);
ok(!lstrcmpA(str, test_service), "Expected %s, got %s, msg_index=%d\n",
test_service, str, msg_index);
ok(size == 14, "Expected 14, got %d, msg_index=%d\n", size, msg_index);
return (HDDEDATA) TRUE;
}
case XTYP_CONNECT_CONFIRM:
{
ok(msg_index == 3 || msg_index == 9 || msg_index == 15 || msg_index == 21,
"Expected 3, 9, 15 or 21 got %d\n", msg_index);
conversation = hconv;
return (HDDEDATA) TRUE;
}
case XTYP_EXECUTE:
{
BYTE *buffer = NULL;
ok(msg_index == 4 || msg_index == 5 || msg_index == 10 || msg_index == 11 ||
msg_index == 16 || msg_index == 17 || msg_index == 22 || msg_index == 23,
"Expected 4, 5, 10, 11, 16, 17, 22 or 23, got %d\n", msg_index);
ok(uFmt == 0, "Expected 0, got %d\n", uFmt);
ok(hconv == conversation, "Expected conversation handle, got %p, msg_index=%d\n",
hconv, msg_index);
ok(dwData1 == 0, "Expected 0, got %08lx, msg_index=%d\n", dwData1, msg_index);
ok(dwData2 == 0, "Expected 0, got %08lx, msg_index=%d\n", dwData2, msg_index);
ok(hsz2 == 0, "Expected 0, got %p, msg_index=%d\n", hsz2, msg_index);
size = DdeQueryStringA(server_pid, hsz1, str, MAX_PATH, CP_WINANSI);
ok(!lstrcmpA(str, test_topic), "Expected %s, got %s, msg_index=%d\n",
test_topic, str, msg_index);
ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index);
ok(size == 12, "Expected 12, got %d, msg_index=%d\n", size, msg_index);
size = DdeGetData(hdata, NULL, 0, 0);
if (msg_index == 10 || msg_index ==11 || msg_index == 16 || msg_index ==17)
if (msg_index == 10 || msg_index == 16)
todo_wine
ok(size == 34, "Expected that size should be 34 not %d, msg_index=%d\n",
size, msg_index);
else
ok(size == 34, "Expected that size should be 34 not %d, msg_index=%d\n",
size, msg_index);
else
if (msg_index ==22)
todo_wine
ok(size == 9, "Expected that size should be 9 not %d, msg_index=%d\n",
size, msg_index);
else
if (msg_index == 5)
todo_wine
ok(size == 17, "Expected that size should be 17 not %d, msg_index=%d\n",
size, msg_index);
else
ok(size == 17, "Expected that size should be 17 not %d, msg_index=%d\n",
size, msg_index);
ok((buffer = HeapAlloc(GetProcessHeap(), 0, size)) != NULL, "should not be null\n");
rsize = DdeGetData(hdata, buffer, size, 0);
if (msg_index == 10 || msg_index == 11 || msg_index == 16 || msg_index ==17)
{
ok(rsize == size, "Incorrect size returned, expected %d got %d, msg_index=%d\n",
size, rsize, msg_index);
if (msg_index == 10 || msg_index == 16)
todo_wine {
ok(!lstrcmpW((WCHAR*)buffer, test_cmd_w),
"Expected \"Test dde command\", msg_index=%d\n",
msg_index);
ok(size == 34, "Expected 34, got %d, msg_index=%d\n", size, msg_index);
} else
{
ok(!lstrcmpW((WCHAR*)buffer, test_cmd_w),
"Expected \"Test dde command\", msg_index=%d\n",
msg_index);
ok(size == 34, "Expected 34, got %d, msg_index=%d\n", size, msg_index);
}
}else if (msg_index == 22)
{
ok(rsize == size, "Incorrect size returned, expected %d got %d, msg_index=%d\n",
size, rsize, msg_index);
} else
{
ok(rsize == size, "Incorrect size returned, expected %d got %d, msg_index=%d\n",
size, rsize, msg_index);
if (msg_index == 5)
todo_wine {
ok(!lstrcmpA((CHAR*)buffer, test_cmd), "Expected %s, got %s, msg_index=%d\n",
test_cmd, buffer, msg_index);
ok(size == 17, "Expected size should be 17, got %d, msg_index=%d\n", size, msg_index);
}
else
{
ok(!lstrcmpA((CHAR*)buffer, test_cmd), "Expected %s, got %s, msg_index=%d\n",
test_cmd, buffer, msg_index);
ok(size == 17, "Expected size should be 17, got %d, msg_index=%d\n", size, msg_index);
}
}
return (HDDEDATA) DDE_FACK;
}
case XTYP_DISCONNECT:
return (HDDEDATA) TRUE;
default:
ok(FALSE, "Unhandled msg: %08x, msg_index=%d\n", uType, msg_index);
}
return NULL;
}
static HDDEDATA CALLBACK client_end_to_end_callback(UINT uType, UINT uFmt, HCONV hconv,
HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
ULONG_PTR dwData1, ULONG_PTR dwData2)
{
switch (uType)
{
case XTYP_DISCONNECT:
return (HDDEDATA) TRUE;
default:
ok(FALSE, "Unhandled msg: %08x\n", uType);
}
return NULL;
}
static void test_end_to_end_client(BOOL type_a)
{
DWORD ret, err;
DWORD client_pid = 0;
HSZ server, topic;
HCONV hconv;
HDDEDATA hdata;
static char test_cmd[] = "test dde command";
static WCHAR test_cmd_w[] = {'t','e','s','t',' ','d','d','e',' ','c','o','m','m','a','n','d',0};
static char test_service[] = "TestDDEService";
static WCHAR test_service_w[] = {'T','e','s','t','D','D','E','S','e','r','v','i','c','e',0};
static char test_topic[] = "TestDDETopic";
static WCHAR test_topic_w[] = {'T','e','s','t','D','D','E','T','o','p','i','c',0};
trace("Start end to end client %d\n", type_a);
if (type_a)
ret = DdeInitializeA(&client_pid, client_end_to_end_callback, APPCMD_CLIENTONLY, 0);
else
ret = DdeInitializeW(&client_pid, client_end_to_end_callback, APPCMD_CLIENTONLY, 0);
ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %x\n", ret);
if (type_a)
{
server = DdeCreateStringHandleA(client_pid, test_service, CP_WINANSI);
topic = DdeCreateStringHandleA(client_pid, test_topic, CP_WINANSI);
}
else {
server = DdeCreateStringHandleW(client_pid, test_service_w, CP_WINUNICODE);
topic = DdeCreateStringHandleW(client_pid, test_topic_w, CP_WINUNICODE);
}
DdeGetLastError(client_pid);
hconv = DdeConnect(client_pid, server, topic, NULL);
ok(hconv != NULL, "Expected non-NULL conversation\n");
ret = DdeGetLastError(client_pid);
ok(ret == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %x\n", ret);
DdeFreeStringHandle(client_pid, server);
/* Test both A and W data being passed to DdeClientTransaction */
hdata = DdeClientTransaction((LPBYTE)test_cmd, strlen(test_cmd) + 1,
hconv, (HSZ)0xdead, 0xbeef, XTYP_EXECUTE, 1000, &ret);
ok(hdata != NULL, "DdeClientTransaction failed\n");
ok(ret == DDE_FACK, "wrong status code %x\n", ret);
err = DdeGetLastError(client_pid);
ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
hdata = DdeClientTransaction((LPBYTE)test_cmd_w, lstrlenW(test_cmd_w) * sizeof(WCHAR) + 2,
hconv, (HSZ)0xdead, 0xbeef, XTYP_EXECUTE, 1000, &ret);
ok(hdata != NULL, "DdeClientTransaction failed\n");
ok(ret == DDE_FACK, "wrong status code %x\n", ret);
err = DdeGetLastError(client_pid);
ok(err == DMLERR_NO_ERROR, "wrong dde error %x\n", err);
DdeFreeStringHandle(client_pid, topic);
ret = DdeDisconnect(hconv);
ok(ret == TRUE, "Expected TRUE, got %x\n", ret);
ret = DdeUninitialize(client_pid);
ok(ret == TRUE, "Expected TRUE, got %x\n", ret);
}
static void test_end_to_end_server(HANDLE hproc, HANDLE hthread, BOOL type_a)
{
MSG msg;
HSZ server;
BOOL ret;
DWORD res;
HDDEDATA hdata;
static CHAR test_service[] = "TestDDEService";
trace("start end to end server %d\n", type_a);
server_pid = 0;
if (type_a)
res = DdeInitializeA(&server_pid, server_end_to_end_callback, APPCLASS_STANDARD, 0);
else
res = DdeInitializeW(&server_pid, server_end_to_end_callback, APPCLASS_STANDARD, 0);
ok(res == DMLERR_NO_ERROR, "Expected DMLERR_NO_ERROR, got %d\n", res);
server = DdeCreateStringHandleA(server_pid, test_service, CP_WINANSI);
ok(server != NULL, "Expected non-NULL string handle\n");
hdata = DdeNameService(server_pid, server, 0, DNS_REGISTER);
ok(hdata == (HDDEDATA)TRUE, "Expected TRUE, got %p\n", hdata);
ResumeThread( hthread );
while (MsgWaitForMultipleObjects( 1, &hproc, FALSE, INFINITE, QS_ALLINPUT ) != 0)
{
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
}
ret = DdeUninitialize(server_pid);
ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
GetExitCodeProcess( hproc, &res );
ok( !res, "client failed with %u error(s)\n", res );
}
START_TEST(dde) START_TEST(dde)
{ {
int argc; int argc;
@ -2080,10 +2419,16 @@ START_TEST(dde)
test_ddeml_client(); test_ddeml_client();
else if (!lstrcmpA(argv[2], "msg")) else if (!lstrcmpA(argv[2], "msg"))
test_msg_client(); test_msg_client();
else if (!lstrcmpA(argv[2], "enda"))
test_end_to_end_client(TRUE);
else if (!lstrcmpA(argv[2], "endw"))
test_end_to_end_client(FALSE);
return; return;
} }
test_initialisation();
ZeroMemory(&startup, sizeof(STARTUPINFO)); ZeroMemory(&startup, sizeof(STARTUPINFO));
sprintf(buffer, "%s dde ddeml", argv[0]); sprintf(buffer, "%s dde ddeml", argv[0]);
startup.cb = sizeof(startup); startup.cb = sizeof(startup);
@ -2091,9 +2436,9 @@ START_TEST(dde)
startup.wShowWindow = SW_SHOWNORMAL; startup.wShowWindow = SW_SHOWNORMAL;
CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
0, NULL, NULL, &startup, &proc); CREATE_SUSPENDED, NULL, NULL, &startup, &proc);
test_msg_server(proc.hProcess); test_msg_server(proc.hProcess, proc.hThread);
sprintf(buffer, "%s dde msg", argv[0]); sprintf(buffer, "%s dde msg", argv[0]);
CreateProcessA(NULL, buffer, NULL, NULL, FALSE, CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
@ -2101,6 +2446,32 @@ START_TEST(dde)
test_ddeml_server(proc.hProcess); test_ddeml_server(proc.hProcess);
/* Test the combinations of A and W interfaces with A and W data
end to end to ensure that data conversions are accurate */
sprintf(buffer, "%s dde enda", argv[0]);
CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &startup, &proc);
test_end_to_end_server(proc.hProcess, proc.hThread, TRUE);
sprintf(buffer, "%s dde endw", argv[0]);
CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &startup, &proc);
test_end_to_end_server(proc.hProcess, proc.hThread, FALSE);
sprintf(buffer, "%s dde enda", argv[0]);
CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &startup, &proc);
test_end_to_end_server(proc.hProcess, proc.hThread, FALSE);
sprintf(buffer, "%s dde endw", argv[0]);
CreateProcessA(NULL, buffer, NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &startup, &proc);
test_end_to_end_server(proc.hProcess, proc.hThread, TRUE);
test_dde_aw_transaction(); test_dde_aw_transaction();
test_DdeCreateDataHandle(); test_DdeCreateDataHandle();

View file

@ -874,7 +874,7 @@ static void InitialFocusTest (void)
hResource = FindResourceA(g_hinst,"FOCUS_TEST_DIALOG", (LPSTR)RT_DIALOG); hResource = FindResourceA(g_hinst,"FOCUS_TEST_DIALOG", (LPSTR)RT_DIALOG);
hTemplate = LoadResource(g_hinst, hResource); hTemplate = LoadResource(g_hinst, hResource);
pTemplate = (LPDLGTEMPLATEA)LockResource(hTemplate); pTemplate = LockResource(hTemplate);
g_hwndInitialFocusT1 = 0; g_hwndInitialFocusT1 = 0;
hDlg = CreateDialogIndirectParamA(g_hinst, pTemplate, NULL, focusDlgWinProc, 0); hDlg = CreateDialogIndirectParamA(g_hinst, pTemplate, NULL, focusDlgWinProc, 0);
@ -896,7 +896,8 @@ static void test_GetDlgItemText(void)
ret = GetDlgItemTextA(NULL, 0, string, sizeof(string)/sizeof(string[0])); ret = GetDlgItemTextA(NULL, 0, string, sizeof(string)/sizeof(string[0]));
ok(!ret, "GetDlgItemText(NULL) shouldn't have succeeded\n"); ok(!ret, "GetDlgItemText(NULL) shouldn't have succeeded\n");
ok(string[0] == '\0', "string retrieved using GetDlgItemText should have been NULL terminated\n"); ok(string[0] == '\0' || broken(!strcmp(string, "Overwrite Me")),
"string retrieved using GetDlgItemText should have been NULL terminated\n");
} }
static void test_DialogBoxParamA(void) static void test_DialogBoxParamA(void)
@ -906,12 +907,16 @@ static void test_DialogBoxParamA(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DialogBoxParamA(GetModuleHandle(NULL), "IDD_DIALOG" , hwnd_invalid, 0 , 0); ret = DialogBoxParamA(GetModuleHandle(NULL), "IDD_DIALOG" , hwnd_invalid, 0 , 0);
ok(0 == ret, "DialogBoxParamA returned %d, expected 0\n", ret); ok(0 == ret || broken(ret == -1), "DialogBoxParamA returned %d, expected 0\n", ret);
ok(ERROR_INVALID_WINDOW_HANDLE == GetLastError(),"got %d, expected ERROR_INVALID_WINDOW_HANDLE\n",GetLastError()); ok(ERROR_INVALID_WINDOW_HANDLE == GetLastError() ||
broken(GetLastError() == 0xdeadbeef),
"got %d, expected ERROR_INVALID_WINDOW_HANDLE\n",GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DialogBoxParamA(GetModuleHandle(NULL), "RESOURCE_INVALID" , 0, 0, 0); ret = DialogBoxParamA(GetModuleHandle(NULL), "RESOURCE_INVALID" , 0, 0, 0);
ok(-1 == ret, "DialogBoxParamA returned %d, expected -1\n", ret); ok(-1 == ret, "DialogBoxParamA returned %d, expected -1\n", ret);
ok(ERROR_RESOURCE_NAME_NOT_FOUND == GetLastError(),"got %d, expected ERROR_RESOURCE_NAME_NOT_FOUND\n",GetLastError()); ok(ERROR_RESOURCE_NAME_NOT_FOUND == GetLastError() ||
broken(GetLastError() == 0xdeadbeef),
"got %d, expected ERROR_RESOURCE_NAME_NOT_FOUND\n",GetLastError());
} }
static void test_DisabledDialogTest(void) static void test_DisabledDialogTest(void)

View file

@ -1336,29 +1336,40 @@ static void test_margins_font_change(void)
SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0)); SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(0,0));
SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) == 0, "got %d\n", LOWORD(margins)); ok(LOWORD(margins) == 0 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins)); "got %d\n", LOWORD(margins));
ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
"got %d\n", HIWORD(margins));
SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0)); SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,0));
SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
ok(HIWORD(margins) == 0, "got %d\n", HIWORD(margins)); "got %d\n", LOWORD(margins));
ok(HIWORD(margins) == 0 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
"got %d\n", HIWORD(margins));
SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1)); SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(1,1));
SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0); SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont, 0);
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); "got %d\n", LOWORD(margins));
ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
"got %d\n", HIWORD(margins));
SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO)); SendMessageA(hwEdit, EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN, MAKELONG(EC_USEFONTINFO,EC_USEFONTINFO));
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); ok(LOWORD(margins) == 1 || broken(LOWORD(margins) == LOWORD(font_margins)), /* win95 */
ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); "got %d\n", LOWORD(margins));
ok(HIWORD(margins) == 1 || broken(HIWORD(margins) == HIWORD(font_margins)), /* win95 */
"got %d\n", HIWORD(margins));
SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0); SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) == 1, "got %d\n", LOWORD(margins)); ok(LOWORD(margins) == 1 || broken(LOWORD(margins) != 1 && LOWORD(margins) != LOWORD(font_margins)), /* win95 */
ok(HIWORD(margins) == 1, "got %d\n", HIWORD(margins)); "got %d\n", LOWORD(margins));
ok(HIWORD(margins) == 1 || broken(HIWORD(margins) != 1 && HIWORD(margins) != HIWORD(font_margins)), /* win95 */
"got %d\n", HIWORD(margins));
/* Above a certain size threshold then the margin is updated */ /* Above a certain size threshold then the margin is updated */
SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE); SetWindowPos(hwEdit, NULL, 10, 10, 1000, 100, SWP_NOZORDER | SWP_NOACTIVATE);
@ -1380,7 +1391,8 @@ static void test_margins_font_change(void)
ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins)); ok(HIWORD(margins) == HIWORD(font_margins), "got %d\n", HIWORD(margins));
SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0); SendMessageA(hwEdit, WM_SETFONT, (WPARAM)hfont2, 0);
margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0); margins = SendMessage(hwEdit, EM_GETMARGINS, 0, 0);
ok(LOWORD(margins) != LOWORD(font_margins), "got %d\n", LOWORD(margins)); ok(LOWORD(margins) != LOWORD(font_margins) || broken(LOWORD(margins) == LOWORD(font_margins)), /* win98 */
"got %d\n", LOWORD(margins));
ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins)); ok(HIWORD(margins) != HIWORD(font_margins), "got %d\n", HIWORD(margins));
SendMessageA(hwEdit, WM_SETFONT, 0, 0); SendMessageA(hwEdit, WM_SETFONT, 0, 0);
@ -1989,6 +2001,53 @@ static void UnregisterWindowClasses (void)
UnregisterClassA(szEditTextPositionClass, hinst); UnregisterClassA(szEditTextPositionClass, hinst);
} }
void test_fontsize(void)
{
HWND hwEdit;
HFONT hfont;
LOGFONT lf;
LONG r;
char szLocalString[MAXLEN];
memset(&lf,0,sizeof(LOGFONTA));
strcpy(lf.lfFaceName,"Arial");
lf.lfHeight = -300; /* taller than the edit box */
lf.lfWeight = 500;
hfont = CreateFontIndirect(&lf);
trace("EDIT: Oversized font (Multi line)\n");
hwEdit= CreateWindow("EDIT", NULL, ES_MULTILINE|ES_AUTOHSCROLL,
0, 0, 150, 50, NULL, NULL, hinst, NULL);
SendMessage(hwEdit,WM_SETFONT,(WPARAM)hfont,0);
if (winetest_interactive)
ShowWindow (hwEdit, SW_SHOW);
r = SendMessage(hwEdit, WM_CHAR, 'A', 1);
ok(1 == r, "Expected: %d, got: %d\n", 1, r);
r = SendMessage(hwEdit, WM_CHAR, 'B', 1);
ok(1 == r, "Expected: %d, got: %d\n", 1, r);
r = SendMessage(hwEdit, WM_CHAR, 'C', 1);
ok(1 == r, "Expected: %d, got: %d\n", 1, r);
GetWindowText(hwEdit, szLocalString, MAXLEN);
ok(lstrcmp(szLocalString, "ABC")==0,
"Wrong contents of edit: %s\n", szLocalString);
r = SendMessage(hwEdit, EM_POSFROMCHAR,0,0);
ok(r != -1,"EM_POSFROMCHAR failed index 0\n");
r = SendMessage(hwEdit, EM_POSFROMCHAR,1,0);
ok(r != -1,"EM_POSFROMCHAR failed index 1\n");
r = SendMessage(hwEdit, EM_POSFROMCHAR,2,0);
ok(r != -1,"EM_POSFROMCHAR failed index 2\n");
r = SendMessage(hwEdit, EM_POSFROMCHAR,3,0);
ok(r == -1,"EM_POSFROMCHAR succeeded index 3\n");
DestroyWindow (hwEdit);
DeleteObject(hfont);
}
START_TEST(edit) START_TEST(edit)
{ {
hinst = GetModuleHandleA(NULL); hinst = GetModuleHandleA(NULL);
@ -2012,6 +2071,7 @@ START_TEST(edit)
test_wantreturn_edit_dialog(); test_wantreturn_edit_dialog();
test_singleline_wantreturn_edit_dialog(); test_singleline_wantreturn_edit_dialog();
test_child_edit_wmkeydown(); test_child_edit_wmkeydown();
test_fontsize();
UnregisterWindowClasses(); UnregisterWindowClasses();
} }

View file

@ -357,17 +357,31 @@ static void test_Input_whitebox(void)
DestroyWindow(hWndTest); DestroyWindow(hWndTest);
} }
static void empty_message_queue(void) { /* try to make sure pending X events have been processed before continuing */
static void empty_message_queue(void)
{
MSG msg; MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { int diff = 200;
int min_timeout = 50;
DWORD time = GetTickCount() + diff;
while (diff > 0)
{
if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
diff = time - GetTickCount();
min_timeout = 20;
}
} }
struct transition_s { struct transition_s {
WORD wVk; WORD wVk;
BYTE before_state; BYTE before_state;
BYTE optional;
}; };
typedef enum { typedef enum {
@ -398,6 +412,7 @@ struct sendinput_test_s {
struct message expected_messages[MAXKEYMESSAGES+1]; struct message expected_messages[MAXKEYMESSAGES+1];
} sendinput_test[] = { } sendinput_test[] = {
/* test ALT+F */ /* test ALT+F */
/* 0 */
{VK_LMENU, 0, 0, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}}, {VK_LMENU, 0, 0, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook|wparam, VK_LMENU}, {WM_SYSKEYDOWN}, {0}}}, {{WM_SYSKEYDOWN, hook|wparam, VK_LMENU}, {WM_SYSKEYDOWN}, {0}}},
{'F', 0, 0, {{'F', 0x00}, {0}}, {'F', 0, 0, {{'F', 0x00}, {0}},
@ -410,6 +425,7 @@ struct sendinput_test_s {
{{WM_KEYUP, hook}, {WM_KEYUP}, {0}}}, {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
/* test CTRL+O */ /* test CTRL+O */
/* 4 */
{VK_LCONTROL, 0, 0, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}}, {VK_LCONTROL, 0, 0, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
{{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}}, {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
{'O', 0, 0, {{'O', 0x00}, {0}}, {'O', 0, 0, {{'O', 0x00}, {0}},
@ -420,6 +436,7 @@ struct sendinput_test_s {
{{WM_KEYUP, hook}, {WM_KEYUP}, {0}}}, {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
/* test ALT+CTRL+X */ /* test ALT+CTRL+X */
/* 8 */
{VK_LMENU, 0, 0, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}}, {VK_LMENU, 0, 0, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook}, {WM_SYSKEYDOWN}, {0}}}, {{WM_SYSKEYDOWN, hook}, {WM_SYSKEYDOWN}, {0}}},
{VK_LCONTROL, 0, 0, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}}, {VK_LCONTROL, 0, 0, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
@ -434,6 +451,7 @@ struct sendinput_test_s {
{{WM_KEYUP, hook}, {WM_KEYUP}, {0}}}, {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
/* test SHIFT+A */ /* test SHIFT+A */
/* 14 */
{VK_LSHIFT, 0, 0, {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}}, {VK_LSHIFT, 0, 0, {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
{{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}}, {{WM_KEYDOWN, hook}, {WM_KEYDOWN}, {0}}},
{'A', 0, 0, {{'A', 0x00}, {0}}, {'A', 0, 0, {{'A', 0x00}, {0}},
@ -444,16 +462,19 @@ struct sendinput_test_s {
{{WM_KEYUP, hook}, {WM_KEYUP}, {0}}}, {{WM_KEYUP, hook}, {WM_KEYUP}, {0}}},
/* test L-SHIFT & R-SHIFT: */ /* test L-SHIFT & R-SHIFT: */
/* RSHIFT == LSHIFT */ /* RSHIFT == LSHIFT */
/* 18 */
{VK_RSHIFT, 0, 0, {VK_RSHIFT, 0, 0,
{{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}}, /* recent windows versions (>= w2k3) correctly report an RSHIFT transition */
{{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00, TRUE}, {VK_RSHIFT, 0x00, TRUE}, {0}},
{{WM_KEYDOWN, hook|wparam, VK_RSHIFT}, {{WM_KEYDOWN, hook|wparam, VK_RSHIFT},
{WM_KEYDOWN}, {0}}}, {WM_KEYDOWN}, {0}}},
{VK_RSHIFT, KEYEVENTF_KEYUP, 0, {VK_RSHIFT, KEYEVENTF_KEYUP, 0,
{{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}}, {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80, TRUE}, {VK_RSHIFT, 0x80, TRUE}, {0}},
{{WM_KEYUP, hook, hook|wparam, VK_RSHIFT}, {{WM_KEYUP, hook, hook|wparam, VK_RSHIFT},
{WM_KEYUP}, {0}}}, {WM_KEYUP}, {0}}},
/* LSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */ /* LSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
/* 20 */
{VK_LSHIFT, KEYEVENTF_EXTENDEDKEY, 0, {VK_LSHIFT, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}}, {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_LSHIFT, LLKHF_EXTENDED}, {{WM_KEYDOWN, hook|wparam|lparam, VK_LSHIFT, LLKHF_EXTENDED},
@ -463,6 +484,7 @@ struct sendinput_test_s {
{{WM_KEYUP, hook|wparam|lparam, VK_LSHIFT, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook|wparam|lparam, VK_LSHIFT, LLKHF_UP|LLKHF_EXTENDED},
{WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}}, {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
/* RSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */ /* RSHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
/* 22 */
{VK_RSHIFT, KEYEVENTF_EXTENDEDKEY, 0, {VK_RSHIFT, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}}, {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_RSHIFT, LLKHF_EXTENDED}, {{WM_KEYDOWN, hook|wparam|lparam, VK_RSHIFT, LLKHF_EXTENDED},
@ -471,27 +493,35 @@ struct sendinput_test_s {
{{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}}, {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
{{WM_KEYUP, hook|wparam|lparam, VK_RSHIFT, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook|wparam|lparam, VK_RSHIFT, LLKHF_UP|LLKHF_EXTENDED},
{WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}}, {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
/* Note about wparam for hook with generic key (VK_SHIFT, VK_CONTROL, VK_MENU):
win2k - sends to hook whatever we generated here
winXP+ - Attempts to convert key to L/R key but not always correct
*/
/* SHIFT == LSHIFT */ /* SHIFT == LSHIFT */
/* 24 */
{VK_SHIFT, 0, 0, {VK_SHIFT, 0, 0,
{{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}}, {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_SHIFT, 0}, {{WM_KEYDOWN, hook/* |wparam */|lparam, VK_SHIFT, 0},
{WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}}, {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
{VK_SHIFT, KEYEVENTF_KEYUP, 0, {VK_SHIFT, KEYEVENTF_KEYUP, 0,
{{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}}, {{VK_SHIFT, 0x80}, {VK_LSHIFT, 0x80}, {0}},
{{WM_KEYUP, hook|wparam|lparam, VK_SHIFT, LLKHF_UP}, {{WM_KEYUP, hook/*|wparam*/|lparam, VK_SHIFT, LLKHF_UP},
{WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}}, {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
/* SHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */ /* SHIFT | KEYEVENTF_EXTENDEDKEY == RSHIFT */
/* 26 */
{VK_SHIFT, KEYEVENTF_EXTENDEDKEY, 0, {VK_SHIFT, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}}, {{VK_SHIFT, 0x00}, {VK_RSHIFT, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_SHIFT, LLKHF_EXTENDED}, {{WM_KEYDOWN, hook/*|wparam*/|lparam, VK_SHIFT, LLKHF_EXTENDED},
{WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}}, {WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0}, {0}}},
{VK_SHIFT, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, 0, {VK_SHIFT, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, 0,
{{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}}, {{VK_SHIFT, 0x80}, {VK_RSHIFT, 0x80}, {0}},
{{WM_KEYUP, hook|wparam|lparam, VK_SHIFT, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook/*|wparam*/|lparam, VK_SHIFT, LLKHF_UP|LLKHF_EXTENDED},
{WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}}, {WM_KEYUP, wparam|lparam, VK_SHIFT, KF_UP}, {0}}},
/* test L-CONTROL & R-CONTROL: */ /* test L-CONTROL & R-CONTROL: */
/* RCONTROL == LCONTROL */ /* RCONTROL == LCONTROL */
/* 28 */
{VK_RCONTROL, 0, 0, {VK_RCONTROL, 0, 0,
{{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}}, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam, VK_RCONTROL}, {{WM_KEYDOWN, hook|wparam, VK_RCONTROL},
@ -501,6 +531,7 @@ struct sendinput_test_s {
{{WM_KEYUP, hook|wparam, VK_RCONTROL}, {{WM_KEYUP, hook|wparam, VK_RCONTROL},
{WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP}, {0}}}, {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP}, {0}}},
/* LCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */ /* LCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
/* 30 */
{VK_LCONTROL, KEYEVENTF_EXTENDEDKEY, 0, {VK_LCONTROL, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}}, {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_LCONTROL, LLKHF_EXTENDED}, {{WM_KEYDOWN, hook|wparam|lparam, VK_LCONTROL, LLKHF_EXTENDED},
@ -510,6 +541,7 @@ struct sendinput_test_s {
{{WM_KEYUP, hook|wparam|lparam, VK_LCONTROL, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook|wparam|lparam, VK_LCONTROL, LLKHF_UP|LLKHF_EXTENDED},
{WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP|KF_EXTENDED}, {0}}}, {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP|KF_EXTENDED}, {0}}},
/* RCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */ /* RCONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
/* 32 */
{VK_RCONTROL, KEYEVENTF_EXTENDEDKEY, 0, {VK_RCONTROL, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}}, {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_RCONTROL, LLKHF_EXTENDED}, {{WM_KEYDOWN, hook|wparam|lparam, VK_RCONTROL, LLKHF_EXTENDED},
@ -519,26 +551,29 @@ struct sendinput_test_s {
{{WM_KEYUP, hook|wparam|lparam, VK_RCONTROL, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook|wparam|lparam, VK_RCONTROL, LLKHF_UP|LLKHF_EXTENDED},
{WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP|KF_EXTENDED}, {0}}}, {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP|KF_EXTENDED}, {0}}},
/* CONTROL == LCONTROL */ /* CONTROL == LCONTROL */
/* 34 */
{VK_CONTROL, 0, 0, {VK_CONTROL, 0, 0,
{{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}}, {{VK_CONTROL, 0x00}, {VK_LCONTROL, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam, VK_CONTROL}, {{WM_KEYDOWN, hook/*|wparam, VK_CONTROL*/},
{WM_KEYDOWN, wparam|lparam, VK_CONTROL, 0}, {0}}}, {WM_KEYDOWN, wparam|lparam, VK_CONTROL, 0}, {0}}},
{VK_CONTROL, KEYEVENTF_KEYUP, 0, {VK_CONTROL, KEYEVENTF_KEYUP, 0,
{{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}}, {{VK_CONTROL, 0x80}, {VK_LCONTROL, 0x80}, {0}},
{{WM_KEYUP, hook|wparam, VK_CONTROL}, {{WM_KEYUP, hook/*|wparam, VK_CONTROL*/},
{WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP}, {0}}}, {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP}, {0}}},
/* CONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */ /* CONTROL | KEYEVENTF_EXTENDEDKEY == RCONTROL */
/* 36 */
{VK_CONTROL, KEYEVENTF_EXTENDEDKEY, 0, {VK_CONTROL, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}}, {{VK_CONTROL, 0x00}, {VK_RCONTROL, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_CONTROL, LLKHF_EXTENDED}, {{WM_KEYDOWN, hook/*|wparam*/|lparam, VK_CONTROL, LLKHF_EXTENDED},
{WM_KEYDOWN, wparam|lparam, VK_CONTROL, KF_EXTENDED}, {0}}}, {WM_KEYDOWN, wparam|lparam, VK_CONTROL, KF_EXTENDED}, {0}}},
{VK_CONTROL, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, 0, {VK_CONTROL, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, 0,
{{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}}, {{VK_CONTROL, 0x80}, {VK_RCONTROL, 0x80}, {0}},
{{WM_KEYUP, hook|wparam|lparam, VK_CONTROL, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook/*|wparam*/|lparam, VK_CONTROL, LLKHF_UP|LLKHF_EXTENDED},
{WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP|KF_EXTENDED}, {0}}}, {WM_KEYUP, wparam|lparam, VK_CONTROL, KF_UP|KF_EXTENDED}, {0}}},
/* test L-MENU & R-MENU: */ /* test L-MENU & R-MENU: */
/* RMENU == LMENU */ /* RMENU == LMENU */
/* 38 */
{VK_RMENU, 0, 0, {VK_RMENU, 0, 0,
{{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}}, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook|wparam, VK_RMENU}, {{WM_SYSKEYDOWN, hook|wparam, VK_RMENU},
@ -549,6 +584,7 @@ struct sendinput_test_s {
{WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP}, {WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP},
{WM_SYSCOMMAND}, {0}}}, {WM_SYSCOMMAND}, {0}}},
/* LMENU | KEYEVENTF_EXTENDEDKEY == RMENU */ /* LMENU | KEYEVENTF_EXTENDEDKEY == RMENU */
/* 40 */
{VK_LMENU, KEYEVENTF_EXTENDEDKEY, 0, {VK_LMENU, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}}, {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook|wparam|lparam, VK_LMENU, LLKHF_EXTENDED}, {{WM_SYSKEYDOWN, hook|wparam|lparam, VK_LMENU, LLKHF_EXTENDED},
@ -559,6 +595,7 @@ struct sendinput_test_s {
{WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP|KF_EXTENDED}, {WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP|KF_EXTENDED},
{WM_SYSCOMMAND}, {0}}}, {WM_SYSCOMMAND}, {0}}},
/* RMENU | KEYEVENTF_EXTENDEDKEY == RMENU */ /* RMENU | KEYEVENTF_EXTENDEDKEY == RMENU */
/* 42 */
{VK_RMENU, KEYEVENTF_EXTENDEDKEY, 0, {VK_RMENU, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}}, {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook|wparam|lparam, VK_RMENU, LLKHF_EXTENDED}, {{WM_SYSKEYDOWN, hook|wparam|lparam, VK_RMENU, LLKHF_EXTENDED},
@ -569,27 +606,30 @@ struct sendinput_test_s {
{WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP|KF_EXTENDED}, {WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP|KF_EXTENDED},
{WM_SYSCOMMAND}, {0}}}, {WM_SYSCOMMAND}, {0}}},
/* MENU == LMENU */ /* MENU == LMENU */
/* 44 */
{VK_MENU, 0, 0, {VK_MENU, 0, 0,
{{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}}, {{VK_MENU, 0x00}, {VK_LMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook|wparam, VK_MENU}, {{WM_SYSKEYDOWN, hook/*|wparam, VK_MENU*/},
{WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0}, {0}}}, {WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0}, {0}}},
{VK_MENU, KEYEVENTF_KEYUP, 1, {VK_MENU, KEYEVENTF_KEYUP, 1,
{{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}}, {{VK_MENU, 0x80}, {VK_LMENU, 0x80}, {0}},
{{WM_KEYUP, hook|wparam, VK_MENU}, {{WM_KEYUP, hook/*|wparam, VK_MENU*/},
{WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP}, {WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP},
{WM_SYSCOMMAND}, {0}}}, {WM_SYSCOMMAND}, {0}}},
/* MENU | KEYEVENTF_EXTENDEDKEY == RMENU */ /* MENU | KEYEVENTF_EXTENDEDKEY == RMENU */
/* 46 */
{VK_MENU, KEYEVENTF_EXTENDEDKEY, 0, {VK_MENU, KEYEVENTF_EXTENDEDKEY, 0,
{{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}}, {{VK_MENU, 0x00}, {VK_RMENU, 0x00}, {0}},
{{WM_SYSKEYDOWN, hook|wparam|lparam, VK_MENU, LLKHF_EXTENDED}, {{WM_SYSKEYDOWN, hook/*|wparam*/|lparam, VK_MENU, LLKHF_EXTENDED},
{WM_SYSKEYDOWN, wparam|lparam, VK_MENU, KF_EXTENDED}, {0}}}, {WM_SYSKEYDOWN, wparam|lparam, VK_MENU, KF_EXTENDED}, {0}}},
{VK_MENU, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, 1, {VK_MENU, KEYEVENTF_KEYUP | KEYEVENTF_EXTENDEDKEY, 1,
{{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {0}}, {{VK_MENU, 0x80}, {VK_RMENU, 0x80}, {0}},
{{WM_KEYUP, hook|wparam|lparam, VK_MENU, LLKHF_UP|LLKHF_EXTENDED}, {{WM_KEYUP, hook/*|wparam*/|lparam, VK_MENU, LLKHF_UP|LLKHF_EXTENDED},
{WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP|KF_EXTENDED}, {WM_SYSKEYUP, wparam|lparam, VK_MENU, KF_UP|KF_EXTENDED},
{WM_SYSCOMMAND}, {0}}}, {WM_SYSCOMMAND}, {0}}},
/* test LSHIFT & RSHIFT */ /* test LSHIFT & RSHIFT */
/* 48 */
{VK_LSHIFT, 0, 0, {VK_LSHIFT, 0, 0,
{{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}}, {{VK_SHIFT, 0x00}, {VK_LSHIFT, 0x00}, {0}},
{{WM_KEYDOWN, hook|wparam|lparam, VK_LSHIFT, 0}, {{WM_KEYDOWN, hook|wparam|lparam, VK_LSHIFT, 0},
@ -629,15 +669,15 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
{ {
failcount++; failcount++;
todo_wine { todo_wine {
ok(matched, "%02d: %02x from %02x -> %02x " ok(matched, "%2d (%x/%x): %02x from %02x -> %02x "
"instead of %02x -> %02x\n", id, t->wVk, "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state, t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
~t->before_state&0x80); ~t->before_state&0x80);
} }
} else { } else {
ok(matched, "%02d: %02x from %02x -> %02x " ok(matched || t->optional, "%2d (%x/%x): %02x from %02x -> %02x "
"instead of %02x -> %02x\n", id, t->wVk, "instead of %02x -> %02x\n", id, test->wVk, test->dwFlags,
ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state, t->wVk, ks1[t->wVk]&0x80, ks2[t->wVk]&0x80, t->before_state,
~t->before_state&0x80); ~t->before_state&0x80);
} }
ks2[t->wVk] = ks1[t->wVk]; /* clear the match */ ks2[t->wVk] = ks1[t->wVk]; /* clear the match */
@ -648,11 +688,12 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
{ {
failcount++; failcount++;
todo_wine todo_wine
ok(FALSE, "%02d: %02x from %02x -> %02x unexpected\n", id, i, ks1[i], ks2[i]); ok(FALSE, "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
} }
else else
ok(ks2[i] == ks1[i], "%02d: %02x from %02x -> %02x unexpected\n", ok(ks2[i] == ks1[i], "%2d (%x/%x): %02x from %02x -> %02x unexpected\n",
id, i, ks1[i], ks2[i]); id, test->wVk, test->dwFlags, i, ks1[i], ks2[i]);
while (expected->message && actual_cnt < sent_messages_cnt) while (expected->message && actual_cnt < sent_messages_cnt)
{ {
@ -661,8 +702,8 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
if (expected->message == actual->message) if (expected->message == actual->message)
{ {
ok((expected->flags & hook) == (actual->flags & hook), ok((expected->flags & hook) == (actual->flags & hook),
"%x/%x: the msg 0x%04x should have been sent by a hook\n", "%2d (%x/%x): the msg 0x%04x should have been sent by a hook\n",
test->wVk, test->dwFlags, expected->message); id, test->wVk, test->dwFlags, expected->message);
if (expected->flags & wparam) if (expected->flags & wparam)
{ {
@ -670,13 +711,13 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
{ {
failcount++; failcount++;
todo_wine todo_wine
ok(FALSE, "%x/%x: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n", ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam); id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
} }
else else
ok(expected->wParam == actual->wParam, ok(expected->wParam == actual->wParam,
"%x/%x: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n", "%2d (%x/%x): in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam); id, test->wVk, test->dwFlags, expected->message, expected->wParam, actual->wParam);
} }
if (expected->flags & lparam) if (expected->flags & lparam)
{ {
@ -684,13 +725,13 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
{ {
failcount++; failcount++;
todo_wine todo_wine
ok(FALSE, "%x/%x: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n", ok(FALSE, "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam); id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
} }
else else
ok(expected->lParam == actual->lParam, ok(expected->lParam == actual->lParam,
"%x/%x: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n", "%2d (%x/%x): in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam); id, test->wVk, test->dwFlags, expected->message, expected->lParam, actual->lParam);
} }
} }
else if (expected->flags & optional) else if (expected->flags & optional)
@ -703,13 +744,13 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
failcount++; failcount++;
todo_wine todo_wine
ok(FALSE, ok(FALSE,
"%x/%x: the msg 0x%04x was expected, but got msg 0x%04x instead\n", "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
test->wVk, test->dwFlags, expected->message, actual->message); id, test->wVk, test->dwFlags, expected->message, actual->message);
} }
else else
ok(FALSE, ok(FALSE,
"%x/%x: the msg 0x%04x was expected, but got msg 0x%04x instead\n", "%2d (%x/%x): the msg 0x%04x was expected, but got msg 0x%04x instead\n",
test->wVk, test->dwFlags, expected->message, actual->message); id, test->wVk, test->dwFlags, expected->message, actual->message);
actual_cnt++; actual_cnt++;
expected++; expected++;
@ -725,17 +766,17 @@ static void compare_and_check(int id, BYTE *ks1, BYTE *ks2, struct sendinput_tes
{ {
failcount++; failcount++;
todo_wine todo_wine
ok(FALSE, "%x/%x: the msg sequence is not complete: expected %04x - actual %04x\n", ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message); id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
} }
else else
ok(FALSE, "%x/%x: the msg sequence is not complete: expected %04x - actual %04x\n", ok(FALSE, "%2d (%x/%x): the msg sequence is not complete: expected %04x - actual %04x\n",
test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message); id, test->wVk, test->dwFlags, expected->message, sent_messages[actual_cnt].message);
} }
if( test->_todo_wine && !failcount) /* succeeded yet marked todo */ if( test->_todo_wine && !failcount) /* succeeded yet marked todo */
todo_wine todo_wine
ok(TRUE, "%x/%x: marked \"todo_wine\" but succeeds\n", test->wVk, test->dwFlags); ok(TRUE, "%2d (%x/%x): marked \"todo_wine\" but succeeds\n", id, test->wVk, test->dwFlags);
sent_messages_cnt = 0; sent_messages_cnt = 0;
} }
@ -1000,19 +1041,19 @@ static void test_GetMouseMovePointsEx(void)
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(0, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)+1, &in, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
/* test second and third parameter /* test second and third parameter
@ -1020,7 +1061,7 @@ static void test_GetMouseMovePointsEx(void)
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_NOACCESS == GetLastError(), ok(GetLastError() == ERROR_NOACCESS || GetLastError() == MYERROR,
"expected error ERROR_NOACCESS, got %u\n", GetLastError()); "expected error ERROR_NOACCESS, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
@ -1051,7 +1092,7 @@ static void test_GetMouseMovePointsEx(void)
count = -1; count = -1;
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, count, GMMP_USE_DISPLAY_POINTS);
ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == count, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
@ -1075,7 +1116,7 @@ static void test_GetMouseMovePointsEx(void)
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
/* it was not possible to force an error with the fifth parameter on win2k */ /* it was not possible to force an error with the fifth parameter on win2k */
@ -1084,25 +1125,25 @@ static void test_GetMouseMovePointsEx(void)
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, NULL, out, BUFLIM, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT)-1, &in, NULL, BUFLIM, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), NULL, out, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
SetLastError(MYERROR); SetLastError(MYERROR);
retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS); retval = pGetMouseMovePointsEx(sizeof(MOUSEMOVEPOINT), &in, NULL, BUFLIM+1, GMMP_USE_DISPLAY_POINTS);
ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval); ok(retval == -1, "expected GetMouseMovePointsEx to fail, got %d\n", retval);
ok(ERROR_INVALID_PARAMETER == GetLastError(), ok(GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == MYERROR,
"expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); "expected error ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
#undef BUFLIM #undef BUFLIM
@ -1113,6 +1154,18 @@ static void test_key_map(void)
{ {
HKL kl = GetKeyboardLayout(0); HKL kl = GetKeyboardLayout(0);
UINT kL, kR, s, sL; UINT kL, kR, s, sL;
int i;
static const UINT numpad_collisions[][2] = {
{ VK_NUMPAD0, VK_INSERT },
{ VK_NUMPAD1, VK_END },
{ VK_NUMPAD2, VK_DOWN },
{ VK_NUMPAD3, VK_NEXT },
{ VK_NUMPAD4, VK_LEFT },
{ VK_NUMPAD6, VK_RIGHT },
{ VK_NUMPAD7, VK_HOME },
{ VK_NUMPAD8, VK_UP },
{ VK_NUMPAD9, VK_PRIOR },
};
s = MapVirtualKeyEx(VK_SHIFT, MAPVK_VK_TO_VSC, kl); s = MapVirtualKeyEx(VK_SHIFT, MAPVK_VK_TO_VSC, kl);
ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n"); ok(s != 0, "MapVirtualKeyEx(VK_SHIFT) should return non-zero\n");
@ -1128,6 +1181,60 @@ static void test_key_map(void)
ok(kL == VK_LSHIFT, "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL); ok(kL == VK_LSHIFT, "Scan code -> vKey = %x (not VK_LSHIFT)\n", kL);
kR = MapVirtualKeyEx(0x36, MAPVK_VSC_TO_VK_EX, kl); kR = MapVirtualKeyEx(0x36, MAPVK_VSC_TO_VK_EX, kl);
ok(kR == VK_RSHIFT, "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR); ok(kR == VK_RSHIFT, "Scan code -> vKey = %x (not VK_RSHIFT)\n", kR);
/* test that MAPVK_VSC_TO_VK prefers the non-numpad vkey if there's ambiguity */
for (i = 0; i < sizeof(numpad_collisions)/sizeof(numpad_collisions[0]); i++)
{
UINT numpad_scan = MapVirtualKeyEx(numpad_collisions[i][0], MAPVK_VK_TO_VSC, kl);
UINT other_scan = MapVirtualKeyEx(numpad_collisions[i][1], MAPVK_VK_TO_VSC, kl);
/* do they really collide for this layout? */
if (numpad_scan && other_scan == numpad_scan)
{
UINT vkey = MapVirtualKeyEx(numpad_scan, MAPVK_VSC_TO_VK, kl);
ok(vkey != numpad_collisions[i][0],
"Got numpad vKey %x for scan code %x when there was another choice\n",
vkey, numpad_scan);
}
}
}
static void test_ToUnicode(void)
{
WCHAR wStr[2];
BYTE state[256];
const BYTE SC_RETURN = 0x1c, SC_TAB = 0x0f;
const BYTE HIGHEST_BIT = 0x80;
int i, ret;
for(i=0; i<256; i++)
state[i]=0;
SetLastError(0xdeadbeef);
ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 2, 0);
if (!ret && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
skip("ToUnicode is not implemented\n");
return;
}
ok(ret == 1, "ToUnicode for Return key didn't return 1 (was %i)\n", ret);
if(ret == 1)
ok(wStr[0]=='\r', "ToUnicode for CTRL + Return was %i (expected 13)\n", wStr[0]);
state[VK_CONTROL] |= HIGHEST_BIT;
state[VK_LCONTROL] |= HIGHEST_BIT;
ret = ToUnicode(VK_TAB, SC_TAB, state, wStr, 2, 0);
todo_wine ok(ret == 0, "ToUnicode for CTRL + Tab didn't return 0 (was %i)\n", ret);
ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 2, 0);
ok(ret == 1, "ToUnicode for CTRL + Return didn't return 1 (was %i)\n", ret);
if(ret == 1)
ok(wStr[0]=='\n', "ToUnicode for CTRL + Return was %i (expected 10)\n", wStr[0]);
state[VK_SHIFT] |= HIGHEST_BIT;
state[VK_LSHIFT] |= HIGHEST_BIT;
ret = ToUnicode(VK_RETURN, SC_RETURN, state, wStr, 2, 0);
todo_wine ok(ret == 0, "ToUnicode for CTRL + SHIFT + Return didn't return 0 (was %i)\n", ret);
} }
START_TEST(input) START_TEST(input)
@ -1143,6 +1250,7 @@ START_TEST(input)
test_keynames(); test_keynames();
test_mouse_ll_hook(); test_mouse_ll_hook();
test_key_map(); test_key_map();
test_ToUnicode();
if(pGetMouseMovePointsEx) if(pGetMouseMovePointsEx)
test_GetMouseMovePointsEx(); test_GetMouseMovePointsEx();

View file

@ -44,7 +44,7 @@ static const char * const strings[4] = {
"Fourth added which is very long because at some time we only had a 256 byte character buffer and that was overflowing in one of those applications that had a common dialog file open box and tried to add a 300 characters long custom filter string which of course the code did not like and crashed. Just make sure this string is longer than 256 characters." "Fourth added which is very long because at some time we only had a 256 byte character buffer and that was overflowing in one of those applications that had a common dialog file open box and tried to add a 300 characters long custom filter string which of course the code did not like and crashed. Just make sure this string is longer than 256 characters."
}; };
static const char BAD_EXTENSION[] = "*.txtbad"; static const char BAD_EXTENSION[] = "*.badtxt";
static HWND static HWND
create_listbox (DWORD add_style, HWND parent) create_listbox (DWORD add_style, HWND parent)
@ -103,8 +103,8 @@ buttonpress (HWND handle, WORD x, WORD y)
LPARAM lp=x+(y<<16); LPARAM lp=x+(y<<16);
WAIT; WAIT;
SendMessage (handle, WM_LBUTTONDOWN, (WPARAM) MK_LBUTTON, lp); SendMessage (handle, WM_LBUTTONDOWN, MK_LBUTTON, lp);
SendMessage (handle, WM_LBUTTONUP , (WPARAM) 0 , lp); SendMessage (handle, WM_LBUTTONUP, 0, lp);
REDRAW; REDRAW;
} }
@ -254,7 +254,9 @@ static LRESULT WINAPI main_window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARA
rc_client.left, rc_client.top, rc_client.right, rc_client.bottom); rc_client.left, rc_client.top, rc_client.right, rc_client.bottom);
GetClipBox(dis->hDC, &rc_clip); GetClipBox(dis->hDC, &rc_clip);
trace("clip rect (%d,%d-%d,%d)\n", rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom); trace("clip rect (%d,%d-%d,%d)\n", rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
ok(EqualRect(&rc_client, &rc_clip), "client rect of the listbox should be equal to the clip box\n"); ok(EqualRect(&rc_client, &rc_clip) || IsRectEmpty(&rc_clip),
"client rect of the listbox should be equal to the clip box,"
"or the clip box should be empty\n");
trace("rcItem (%d,%d-%d,%d)\n", dis->rcItem.left, dis->rcItem.top, trace("rcItem (%d,%d-%d,%d)\n", dis->rcItem.left, dis->rcItem.top,
dis->rcItem.right, dis->rcItem.bottom); dis->rcItem.right, dis->rcItem.bottom);
@ -456,18 +458,18 @@ static void test_itemfrompoint(void)
HWND hList = CreateWindow( "ListBox", "list test", HWND hList = CreateWindow( "ListBox", "list test",
WS_VISIBLE|WS_POPUP|LBS_NOINTEGRALHEIGHT, WS_VISIBLE|WS_POPUP|LBS_NOINTEGRALHEIGHT,
1, 1, 600, 100, NULL, NULL, NULL, NULL ); 1, 1, 600, 100, NULL, NULL, NULL, NULL );
LONG r, id; ULONG r, id;
RECT rc; RECT rc;
/* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000 */ /* For an empty listbox win2k returns 0x1ffff, win98 returns 0x10000, nt4 returns 0xffffffff */
r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 )); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 30 ));
ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r ); ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 )); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 700, 30 ));
ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r ); ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 )); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( 30, 300 ));
ok( r == 0x1ffff || r == 0x10000, "ret %x\n", r ); ok( r == 0x1ffff || r == 0x10000 || r == 0xffffffff, "ret %x\n", r );
id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi"); id = SendMessage( hList, LB_ADDSTRING, 0, (LPARAM) "hi");
ok( id == 0, "item id wrong\n"); ok( id == 0, "item id wrong\n");
@ -478,7 +480,8 @@ static void test_itemfrompoint(void)
ok( r == 0x1, "ret %x\n", r ); ok( r == 0x1, "ret %x\n", r );
r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 )); r = SendMessage(hList, LB_ITEMFROMPOINT, 0, MAKELPARAM( /* x */ 30, /* y */ 601 ));
ok( r == 0x10001, "ret %x\n", r ); ok( r == 0x10001 || broken(r == 1), /* nt4 */
"ret %x\n", r );
/* Resize control so that below assertions about sizes are valid */ /* Resize control so that below assertions about sizes are valid */
r = SendMessage( hList, LB_GETITEMRECT, 0, (LPARAM)&rc); r = SendMessage( hList, LB_GETITEMRECT, 0, (LPARAM)&rc);
@ -515,16 +518,20 @@ static void test_itemfrompoint(void)
ok( r == 1, "ret %x\n", r); ok( r == 1, "ret %x\n", r);
r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(1000, 10) );
ok( r == 0x10001, "ret %x\n", r ); ok( r == 0x10001 || broken(r == 1), /* nt4 */
"ret %x\n", r );
r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, -10) );
ok( r == 0x10001, "ret %x\n", r ); ok( r == 0x10001 || broken(r == 1), /* nt4 */
"ret %x\n", r );
r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 100) );
ok( r == 0x10005, "item %x\n", r ); ok( r == 0x10005 || broken(r == 5), /* nt4 */
"item %x\n", r );
r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) ); r = SendMessage( hList, LB_ITEMFROMPOINT, 0, MAKELPARAM(10, 200) );
ok( r == 0x10005, "item %x\n", r ); ok( r == 0x10005 || broken(r == 5), /* nt4 */
"item %x\n", r );
DestroyWindow( hList ); DestroyWindow( hList );
} }
@ -550,13 +557,14 @@ static void test_listbox_item_data(void)
DestroyWindow( hList ); DestroyWindow( hList );
} }
static void test_listbox_LB_DIR() static void test_listbox_LB_DIR(void)
{ {
HWND hList; HWND hList;
int res, itemCount; int res, itemCount;
int itemCount_justFiles; int itemCount_justFiles;
int itemCount_justDrives; int itemCount_justDrives;
int itemCount_allFiles; int itemCount_allFiles;
int itemCount_allDirs;
int i; int i;
char pathBuffer[MAX_PATH]; char pathBuffer[MAX_PATH];
char * p; char * p;
@ -582,6 +590,11 @@ static void test_listbox_LB_DIR()
strcpy(pathBuffer, "*"); strcpy(pathBuffer, "*");
SendMessage(hList, LB_RESETCONTENT, 0, 0); SendMessage(hList, LB_RESETCONTENT, 0, 0);
res = SendMessage(hList, LB_DIR, 0, (LPARAM)pathBuffer); res = SendMessage(hList, LB_DIR, 0, (LPARAM)pathBuffer);
if (res == -1) /* "*" wildcard doesn't work on win9x */
{
strcpy(pathBuffer, "*.*");
res = SendMessage(hList, LB_DIR, 0, (LPARAM)pathBuffer);
}
ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError()); ok (res >= 0, "SendMessage(LB_DIR, 0, *) failed - 0x%08x\n", GetLastError());
/* There should be some content in the listbox */ /* There should be some content in the listbox */
@ -637,15 +650,22 @@ static void test_listbox_LB_DIR()
strcpy(pathBuffer, "*"); strcpy(pathBuffer, "*");
SendMessage(hList, LB_RESETCONTENT, 0, 0); SendMessage(hList, LB_RESETCONTENT, 0, 0);
res = SendMessage(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer); res = SendMessage(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer);
if (res == -1 || res <= itemCount_allFiles) /* "*" wildcard doesn't work on win9x */
{
strcpy(pathBuffer, "*.*");
SendMessage(hList, LB_RESETCONTENT, 0, 0);
res = SendMessage(hList, LB_DIR, DDL_DIRECTORY, (LPARAM)pathBuffer);
}
ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError()); ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY, *) failed - 0x%08x\n", GetLastError());
/* There should be some content in the listbox. /* There should be some content in the listbox.
* All files plus "[..]" * All files plus "[..]"
*/ */
itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0); itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_allFiles + 1, itemCount_allDirs = itemCount - itemCount_allFiles;
"SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected %d\n", ok (itemCount > itemCount_allFiles,
itemCount, itemCount_allFiles + 1); "SendMessage(LB_DIR, DDL_DIRECTORY, *) filled with %d entries, expected > %d\n",
itemCount, itemCount_allFiles);
ok(res + 1 == itemCount, ok(res + 1 == itemCount,
"SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n", "SendMessage(LB_DIR, DDL_DIRECTORY, *) returned incorrect index (expected %d got %d)!\n",
itemCount - 1, res); itemCount - 1, res);
@ -694,7 +714,7 @@ static void test_listbox_LB_DIR()
strcpy(pathBuffer, "*"); strcpy(pathBuffer, "*");
SendMessage(hList, LB_RESETCONTENT, 0, 0); SendMessage(hList, LB_RESETCONTENT, 0, 0);
res = SendMessage(hList, LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer); res = SendMessage(hList, LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
ok (res > 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError()); ok (res >= 0, "SendMessage(LB_DIR, DDL_DRIVES|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError());
/* There should be some content in the listbox. In particular, there should /* There should be some content in the listbox. In particular, there should
* be at least one element before, since the string "[-c-]" should * be at least one element before, since the string "[-c-]" should
@ -749,10 +769,11 @@ static void test_listbox_LB_DIR()
* been added. * been added.
*/ */
itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0); itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justDrives + itemCount_allFiles, ok (itemCount == itemCount_justDrives + itemCount_allFiles ||
"SendMessage(LB_DIR, DDL_DRIVES, w*.c) filled with %d entries, expected %d\n", broken(itemCount == itemCount_justDrives), /* "*" wildcard broken on win9x */
"SendMessage(LB_DIR, DDL_DRIVES, *) filled with %d entries, expected %d\n",
itemCount, itemCount_justDrives + itemCount_allFiles); itemCount, itemCount_justDrives + itemCount_allFiles);
ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, w*.c) returned incorrect index!\n"); ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DRIVES, *) returned incorrect index!\n");
/* This tests behavior when no files match the wildcard */ /* This tests behavior when no files match the wildcard */
strcpy(pathBuffer, BAD_EXTENSION); strcpy(pathBuffer, BAD_EXTENSION);
@ -810,9 +831,10 @@ static void test_listbox_LB_DIR()
* be exactly the number of plain files, plus the number of mapped drives. * be exactly the number of plain files, plus the number of mapped drives.
*/ */
itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0); itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_allFiles + itemCount_justDrives + 1, ok (itemCount == itemCount_allFiles + itemCount_justDrives + itemCount_allDirs ||
broken(itemCount == itemCount_justDrives + itemCount_allDirs), /* "*" wildcard broken on win9x */
"SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n", "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
itemCount, itemCount_allFiles + itemCount_justDrives + 1); itemCount, itemCount_allFiles + itemCount_justDrives + itemCount_allDirs);
ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n"); ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES, w*.c) returned incorrect index!\n");
/* Every single item in the control should start with a w and end in .c, /* Every single item in the control should start with a w and end in .c,
@ -879,18 +901,20 @@ static void test_listbox_LB_DIR()
strcpy(pathBuffer, "*"); strcpy(pathBuffer, "*");
SendMessage(hList, LB_RESETCONTENT, 0, 0); SendMessage(hList, LB_RESETCONTENT, 0, 0);
res = SendMessage(hList, LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, (LPARAM)pathBuffer); res = SendMessage(hList, LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
ok (res == 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed - 0x%08x\n", GetLastError()); ok (res != -1, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) failed err %u\n", GetLastError());
/* There should be exactly one element: "[..]" */
itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0); itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0);
ok (itemCount == 1, ok (itemCount == itemCount_allDirs,
"SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n", "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
itemCount, 1); itemCount, itemCount_allDirs);
ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n"); ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_EXCLUSIVE, *) returned incorrect index!\n");
if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
{
memset(pathBuffer, 0, MAX_PATH); memset(pathBuffer, 0, MAX_PATH);
SendMessage(hList, LB_GETTEXT, 0, (LPARAM)pathBuffer); SendMessage(hList, LB_GETTEXT, 0, (LPARAM)pathBuffer);
ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n"); ok( !strcmp(pathBuffer, "[..]"), "First element is not [..]\n");
}
/* This tests behavior when no files match the wildcard */ /* This tests behavior when no files match the wildcard */
strcpy(pathBuffer, BAD_EXTENSION); strcpy(pathBuffer, BAD_EXTENSION);
@ -923,9 +947,9 @@ static void test_listbox_LB_DIR()
/* There should be no plain files on the listbox */ /* There should be no plain files on the listbox */
itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0); itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justDrives + 1, ok (itemCount == itemCount_justDrives + itemCount_allDirs,
"SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n", "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
itemCount, itemCount_justDrives + 1); itemCount, itemCount_justDrives + itemCount_allDirs);
ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n"); ok(res + 1 == itemCount, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c) returned incorrect index!\n");
for (i = 0; i < itemCount; i++) { for (i = 0; i < itemCount; i++) {
@ -936,7 +960,8 @@ static void test_listbox_LB_DIR()
if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) { if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter); ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
} else { } else {
ok( !strcmp(pathBuffer, "[..]"), "Element %d (%s) does not fit expected [..]\n", i, pathBuffer); ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
"Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
} }
} }
@ -954,7 +979,7 @@ static void test_listbox_LB_DIR()
strcpy(pathBuffer, "w*.c"); strcpy(pathBuffer, "w*.c");
SendMessage(hList, LB_RESETCONTENT, 0, 0); SendMessage(hList, LB_RESETCONTENT, 0, 0);
res = SendMessage(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer); res = SendMessage(hList, LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, (LPARAM)pathBuffer);
ok (res > 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError()); ok (res >= 0, "SendMessage(LB_DIR, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE, w*.c,) failed - 0x%08x\n", GetLastError());
/* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */ /* There should be no plain files on the listbox, and no [..], since it does not fit w*.c */
itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0); itemCount = SendMessage(hList, LB_GETCOUNT, 0, 0);
@ -1046,6 +1071,7 @@ static void test_listbox_dlgdir(void)
HINSTANCE hInst; HINSTANCE hInst;
HWND hWnd; HWND hWnd;
int res, itemCount; int res, itemCount;
int itemCount_allDirs;
int itemCount_justFiles; int itemCount_justFiles;
int itemCount_justDrives; int itemCount_justDrives;
int i; int i;
@ -1125,13 +1151,14 @@ static void test_listbox_dlgdir(void)
ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError()); ok (res == 1, "DlgDirList(*.c, DDL_DIRECTORY) failed - 0x%08x\n", GetLastError());
/* There should be some content in the listbox. In particular, there should /* There should be some content in the listbox. In particular, there should
* be exactly one more element than before, since the string "[..]" should * be exactly more elements than before, since the directories should
* have been added. * have been added.
*/ */
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justFiles + 1, itemCount_allDirs = itemCount - itemCount_justFiles;
"DlgDirList(DDL_DIRECTORY) filled with %d entries, expected %d\n", ok (itemCount >= itemCount_justFiles,
itemCount, itemCount_justFiles + 1); "DlgDirList(DDL_DIRECTORY) filled with %d entries, expected > %d\n",
itemCount, itemCount_justFiles);
/* Every single item in the control should start with a w and end in .c, /* Every single item in the control should start with a w and end in .c,
* except for the "[..]" string, which should appear exactly as it is. * except for the "[..]" string, which should appear exactly as it is.
@ -1140,7 +1167,7 @@ static void test_listbox_dlgdir(void)
memset(pathBuffer, 0, MAX_PATH); memset(pathBuffer, 0, MAX_PATH);
SendMessage(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer); SendMessage(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
p = pathBuffer + strlen(pathBuffer); p = pathBuffer + strlen(pathBuffer);
ok( !strcmp(pathBuffer, "[..]") || ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') && ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
(*(p-1) == 'c' || *(p-1) == 'C') && (*(p-1) == 'c' || *(p-1) == 'C') &&
(*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer); (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
@ -1153,13 +1180,15 @@ static void test_listbox_dlgdir(void)
ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION, res); ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY) returned %d expected 1\n", BAD_EXTENSION, res);
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == 1, "DlgDirList() incorrectly filled the listbox! (expected 1 got %d)\n", ok (itemCount == itemCount_allDirs,
itemCount); "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
itemCount_allDirs, itemCount);
for (i = 0; i < itemCount; i++) { for (i = 0; i < itemCount; i++) {
memset(pathBuffer, 0, MAX_PATH); memset(pathBuffer, 0, MAX_PATH);
SendMessage(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer); SendMessage(g_listBox, LB_GETTEXT, i, (LPARAM)pathBuffer);
p = pathBuffer + strlen(pathBuffer); p = pathBuffer + strlen(pathBuffer);
ok( !strcmp(pathBuffer, "[..]"), "Element %d (%s) does not fit requested [..]\n", i, pathBuffer); ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
"Element %d (%s) does not fit requested [...]\n", i, pathBuffer);
} }
@ -1216,9 +1245,9 @@ static void test_listbox_dlgdir(void)
* plus one "[..]" * plus one "[..]"
*/ */
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justFiles + itemCount_justDrives + 1, ok (itemCount == itemCount_justFiles + itemCount_justDrives + itemCount_allDirs,
"DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n", "DlgDirList(DDL_DIRECTORY|DDL_DRIVES) filled with %d entries, expected %d\n",
itemCount, itemCount_justFiles + itemCount_justDrives + 1); itemCount, itemCount_justFiles + itemCount_justDrives + itemCount_allDirs);
/* Every single item in the control should start with a w and end in .c, /* Every single item in the control should start with a w and end in .c,
* except for the "[..]" string, which should appear exactly as it is, * except for the "[..]" string, which should appear exactly as it is,
@ -1232,7 +1261,7 @@ static void test_listbox_dlgdir(void)
if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) { if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter); ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
} else { } else {
ok( !strcmp(pathBuffer, "[..]") || ok( (pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']') ||
((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') && ((pathBuffer[0] == 'w' || pathBuffer[0] == 'W') &&
(*(p-1) == 'c' || *(p-1) == 'C') && (*(p-1) == 'c' || *(p-1) == 'C') &&
(*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer); (*(p-2) == '.')), "Element %d (%s) does not fit requested w*.c\n", i, pathBuffer);
@ -1246,9 +1275,9 @@ static void test_listbox_dlgdir(void)
ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res); ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES) returned %d expected 1\n", BAD_EXTENSION, res);
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justDrives + 1, ok (itemCount == itemCount_justDrives + itemCount_allDirs,
"DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n", "DlgDirList() incorrectly filled the listbox! (expected %d got %d)\n",
itemCount_justDrives + 1, itemCount); itemCount_justDrives + itemCount_allDirs, itemCount);
@ -1260,14 +1289,16 @@ static void test_listbox_dlgdir(void)
/* There should be exactly one element: "[..]" */ /* There should be exactly one element: "[..]" */
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == 1, ok (itemCount == itemCount_allDirs,
"DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n", "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
itemCount, 1); itemCount, itemCount_allDirs);
if (itemCount && GetCurrentDirectoryA( MAX_PATH, pathBuffer ) > 3) /* there's no [..] in drive root */
{
memset(pathBuffer, 0, MAX_PATH); memset(pathBuffer, 0, MAX_PATH);
SendMessage(g_listBox, LB_GETTEXT, 0, (LPARAM)pathBuffer); SendMessage(g_listBox, LB_GETTEXT, 0, (LPARAM)pathBuffer);
ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n"); ok( !strcmp(pathBuffer, "[..]"), "First (and only) element is not [..]\n");
}
/* Test behavior when no files match the wildcard */ /* Test behavior when no files match the wildcard */
strcpy(pathBuffer, BAD_EXTENSION); strcpy(pathBuffer, BAD_EXTENSION);
@ -1276,7 +1307,7 @@ static void test_listbox_dlgdir(void)
ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res); ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == 1, "DlgDirList() incorrectly filled the listbox!\n"); ok (itemCount == itemCount_allDirs, "DlgDirList() incorrectly filled the listbox!\n");
/* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */ /* Test DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE. */
@ -1287,9 +1318,9 @@ static void test_listbox_dlgdir(void)
/* There should be no plain files on the listbox */ /* There should be no plain files on the listbox */
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justDrives + 1, ok (itemCount == itemCount_justDrives + itemCount_allDirs,
"DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n", "DlgDirList(DDL_DIRECTORY|DDL_EXCLUSIVE) filled with %d entries, expected %d\n",
itemCount, itemCount_justDrives + 1); itemCount, itemCount_justDrives + itemCount_allDirs);
for (i = 0; i < itemCount; i++) { for (i = 0; i < itemCount; i++) {
memset(pathBuffer, 0, MAX_PATH); memset(pathBuffer, 0, MAX_PATH);
@ -1299,7 +1330,8 @@ static void test_listbox_dlgdir(void)
if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) { if (sscanf(pathBuffer, "[-%c-]", &driveletter) == 1) {
ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter); ok( driveletter >= 'a' && driveletter <= 'z', "Drive letter not in range a..z, got ascii %d\n", driveletter);
} else { } else {
ok( !strcmp(pathBuffer, "[..]"), "Element %d (%s) does not fit expected [..]\n", i, pathBuffer); ok( pathBuffer[0] == '[' && pathBuffer[strlen(pathBuffer)-1] == ']',
"Element %d (%s) does not fit expected [...]\n", i, pathBuffer);
} }
} }
@ -1310,7 +1342,8 @@ static void test_listbox_dlgdir(void)
ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res); ok (res == 1, "DlgDirList(%s, DDL_DIRECTORY|DDL_DRIVES|DDL_EXCLUSIVE) returned %d expected 1\n", BAD_EXTENSION, res);
itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0); itemCount = SendMessage(g_listBox, LB_GETCOUNT, 0, 0);
ok (itemCount == itemCount_justDrives + 1, "DlgDirList() incorrectly filled the listbox!\n"); ok (itemCount == itemCount_justDrives + itemCount_allDirs,
"DlgDirList() incorrectly filled the listbox!\n");
/* Now test DlgDirSelectEx() in normal operation */ /* Now test DlgDirSelectEx() in normal operation */

View file

@ -57,6 +57,33 @@ static void init_function_pointers(void)
#undef GET_PROC #undef GET_PROC
} }
static BOOL correct_behavior(void)
{
HMENU hmenu;
MENUITEMINFO info;
BOOL rc;
hmenu = CreateMenu();
memset(&info, 0, sizeof(MENUITEMINFO));
info.cbSize= sizeof(MENUITEMINFO);
SetLastError(0xdeadbeef);
rc = GetMenuItemInfo(hmenu, 0, TRUE, &info);
/* Win9x : 0xdeadbeef
* NT4 : ERROR_INVALID_PARAMETER
* >= W2K : ERROR_MENU_ITEM_NOT_FOUND
*/
if (!rc && GetLastError() != ERROR_MENU_ITEM_NOT_FOUND)
{
win_skip("NT4 and below can't handle a bigger MENUITEMINFO struct\n");
DestroyMenu(hmenu);
return FALSE;
}
DestroyMenu(hmenu);
return TRUE;
}
static LRESULT WINAPI menu_check_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) static LRESULT WINAPI menu_check_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{ {
switch (msg) switch (msg)
@ -357,7 +384,8 @@ static void test_mbs_help( int ispop, int hassub, int mnuopt,
MOD_GotDrawItemMsg = FALSE; MOD_GotDrawItemMsg = FALSE;
mii.fMask = MIIM_FTYPE | MIIM_DATA | MIIM_STATE; mii.fMask = MIIM_FTYPE | MIIM_DATA | MIIM_STATE;
mii.fType = 0; mii.fType = 0;
mii.fState = MF_CHECKED; /* check the menu item unless MNS_CHECKORBMP is set */
mii.fState = (mnuopt != 2 ? MFS_CHECKED : MFS_UNCHECKED);
mii.dwItemData =0; mii.dwItemData =0;
MODsizes[0] = bmpsize; MODsizes[0] = bmpsize;
hastab = 0; hastab = 0;
@ -447,8 +475,14 @@ static void test_mbs_help( int ispop, int hassub, int mnuopt,
if( hbmp == HBMMENU_CALLBACK && MOD_GotDrawItemMsg) { if( hbmp == HBMMENU_CALLBACK && MOD_GotDrawItemMsg) {
/* check the position of the bitmap */ /* check the position of the bitmap */
/* horizontal */ /* horizontal */
expect = ispop ? (4 + ( mnuopt ? 0 : GetSystemMetrics(SM_CXMENUCHECK))) if (!ispop)
: 3; expect = 3;
else if (mnuopt == 0)
expect = 4 + GetSystemMetrics(SM_CXMENUCHECK);
else if (mnuopt == 1)
expect = 4;
else /* mnuopt == 2 */
expect = 2;
ok( expect == MOD_rc[0].left, ok( expect == MOD_rc[0].left,
"bitmap left is %d expected %d\n", MOD_rc[0].left, expect); "bitmap left is %d expected %d\n", MOD_rc[0].left, expect);
failed = failed || !(expect == MOD_rc[0].left); failed = failed || !(expect == MOD_rc[0].left);
@ -1691,7 +1725,7 @@ static struct menu_mouse_tests_s {
static void send_key(WORD wVk) static void send_key(WORD wVk)
{ {
TEST_INPUT i[2]; TEST_INPUT i[2];
memset(&i, 0, 2*sizeof(INPUT)); memset(i, 0, sizeof(i));
i[0].type = i[1].type = INPUT_KEYBOARD; i[0].type = i[1].type = INPUT_KEYBOARD;
i[0].u.ki.wVk = i[1].u.ki.wVk = wVk; i[0].u.ki.wVk = i[1].u.ki.wVk = wVk;
i[1].u.ki.dwFlags = KEYEVENTF_KEYUP; i[1].u.ki.dwFlags = KEYEVENTF_KEYUP;
@ -1706,10 +1740,10 @@ static void click_menu(HANDLE hWnd, struct menu_item_pair_s *mi)
RECT r; RECT r;
int screen_w = GetSystemMetrics(SM_CXSCREEN); int screen_w = GetSystemMetrics(SM_CXSCREEN);
int screen_h = GetSystemMetrics(SM_CYSCREEN); int screen_h = GetSystemMetrics(SM_CYSCREEN);
BOOL ret = GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r);
if(!ret) return;
GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r); memset(i, 0, sizeof(i));
memset(&i, 0, 3*sizeof(INPUT));
i[0].type = i[1].type = i[2].type = INPUT_MOUSE; i[0].type = i[1].type = i[2].type = INPUT_MOUSE;
i[0].u.mi.dx = i[1].u.mi.dx = i[2].u.mi.dx i[0].u.mi.dx = i[1].u.mi.dx = i[2].u.mi.dx
= ((r.left + 5) * 65535) / screen_w; = ((r.left + 5) * 65535) / screen_w;
@ -1785,6 +1819,7 @@ static void test_menu_input(void) {
WNDCLASSA wclass; WNDCLASSA wclass;
HINSTANCE hInstance = GetModuleHandleA( NULL ); HINSTANCE hInstance = GetModuleHandleA( NULL );
HANDLE hThread, hWnd; HANDLE hThread, hWnd;
DWORD tid;
wclass.lpszClassName = "MenuTestClass"; wclass.lpszClassName = "MenuTestClass";
wclass.style = CS_HREDRAW | CS_VREDRAW; wclass.style = CS_HREDRAW | CS_VREDRAW;
@ -1820,7 +1855,7 @@ static void test_menu_input(void) {
ShowWindow(hWnd, SW_SHOW); ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd); UpdateWindow(hWnd);
hThread = CreateThread(NULL, 0, test_menu_input_thread, hWnd, 0, NULL); hThread = CreateThread(NULL, 0, test_menu_input_thread, hWnd, 0, &tid);
while(1) while(1)
{ {
if (WAIT_TIMEOUT != WaitForSingleObject(hThread, 50)) if (WAIT_TIMEOUT != WaitForSingleObject(hThread, 50))
@ -1997,9 +2032,10 @@ static void test_menu_hilitemenuitem( void )
static void check_menu_items(HMENU hmenu, UINT checked_cmd, UINT checked_type, static void check_menu_items(HMENU hmenu, UINT checked_cmd, UINT checked_type,
UINT checked_state) UINT checked_state)
{ {
UINT i, count; INT i, count;
count = GetMenuItemCount(hmenu); count = GetMenuItemCount(hmenu);
ok (count != -1, "GetMenuItemCount returned -1\n");
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
@ -2140,7 +2176,7 @@ static void test_menu_resource_layout(void)
{ MF_SEPARATOR, MF_GRAYED|MF_DISABLED, 8, "" } { MF_SEPARATOR, MF_GRAYED|MF_DISABLED, 8, "" }
}; };
HMENU hmenu; HMENU hmenu;
UINT count, i; INT count, i;
BOOL ret; BOOL ret;
hmenu = LoadMenuIndirect(&menu_template); hmenu = LoadMenuIndirect(&menu_template);
@ -2342,13 +2378,23 @@ START_TEST(menu)
{ {
init_function_pointers(); init_function_pointers();
/* Wine defines MENUITEMINFO for W2K and above. NT4 and below can't
* handle that.
*/
if (correct_behavior())
{
test_menu_add_string();
test_menu_iteminfo();
test_menu_search_bycommand();
test_CheckMenuRadioItem();
test_menu_resource_layout();
test_InsertMenu();
}
register_menu_check_class(); register_menu_check_class();
test_menu_locked_by_window(); test_menu_locked_by_window();
test_menu_ownerdraw(); test_menu_ownerdraw();
test_menu_add_string();
test_menu_iteminfo();
test_menu_search_bycommand();
test_menu_bmp_and_string(); test_menu_bmp_and_string();
if( !pSendInput) if( !pSendInput)
@ -2358,7 +2404,4 @@ START_TEST(menu)
test_menu_flags(); test_menu_flags();
test_menu_hilitemenuitem(); test_menu_hilitemenuitem();
test_CheckMenuRadioItem();
test_menu_resource_layout();
test_InsertMenu();
} }

View file

@ -2,6 +2,7 @@
* Unit tests for monitor APIs * Unit tests for monitor APIs
* *
* Copyright 2005 Huw Davies * Copyright 2005 Huw Davies
* Copyright 2008 Dmitry Timoshkov
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -61,7 +62,7 @@ static BOOL CALLBACK monitor_enum_proc(HMONITOR hmon, HDC hdc, LPRECT lprc,
mi.cbSize = sizeof(mi); mi.cbSize = sizeof(mi);
ok(pGetMonitorInfoA(hmon, (MONITORINFO*)&mi), "GetMonitorInfo failed\n"); ok(pGetMonitorInfoA(hmon, (MONITORINFO*)&mi), "GetMonitorInfo failed\n");
if(mi.dwFlags == MONITORINFOF_PRIMARY) if (mi.dwFlags & MONITORINFOF_PRIMARY)
strcpy(primary, mi.szDevice); strcpy(primary, mi.szDevice);
return TRUE; return TRUE;
@ -73,15 +74,20 @@ static void test_enumdisplaydevices(void)
char primary_device_name[32]; char primary_device_name[32];
char primary_monitor_device_name[32]; char primary_monitor_device_name[32];
DWORD primary_num = -1, num = 0; DWORD primary_num = -1, num = 0;
BOOL ret;
if (!pEnumDisplayDevicesA)
{
skip("EnumDisplayDevicesA is not available\n");
return;
}
dd.cb = sizeof(dd); dd.cb = sizeof(dd);
if(pEnumDisplayDevicesA == NULL) return;
while(1) while(1)
{ {
BOOL ret; BOOL ret;
HDC dc; HDC dc;
ret = pEnumDisplayDevicesA(NULL, num, &dd, 0); ret = pEnumDisplayDevicesA(NULL, num, &dd, 0);
ok(ret || num != 0, "EnumDisplayDevices fails with num == 0\n");
if(!ret) break; if(!ret) break;
if(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) if(dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
{ {
@ -97,22 +103,25 @@ static void test_enumdisplaydevices(void)
} }
num++; num++;
} }
ok(primary_num != -1, "Didn't get the primary device\n");
if(pEnumDisplayMonitors && pGetMonitorInfoA) { if (primary_num == -1 || !pEnumDisplayMonitors || !pGetMonitorInfoA)
ok(pEnumDisplayMonitors(NULL, NULL, monitor_enum_proc, (LPARAM)primary_monitor_device_name), {
"EnumDisplayMonitors failed\n"); win_skip("EnumDisplayMonitors or GetMonitorInfoA are not available\n");
return;
}
primary_monitor_device_name[0] = 0;
ret = pEnumDisplayMonitors(NULL, NULL, monitor_enum_proc, (LPARAM)primary_monitor_device_name);
ok(ret, "EnumDisplayMonitors failed\n");
ok(!strcmp(primary_monitor_device_name, primary_device_name), ok(!strcmp(primary_monitor_device_name, primary_device_name),
"monitor device name %s, device name %s\n", primary_monitor_device_name, "monitor device name %s, device name %s\n", primary_monitor_device_name,
primary_device_name); primary_device_name);
} }
}
struct vid_mode struct vid_mode
{ {
DWORD w, h, bpp, freq, fields; DWORD w, h, bpp, freq, fields;
LONG success; BOOL must_succeed;
}; };
static const struct vid_mode vid_modes_test[] = { static const struct vid_mode vid_modes_test[] = {
@ -120,18 +129,20 @@ static const struct vid_mode vid_modes_test[] = {
{640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY, 1}, {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY, 1},
{640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL , 1}, {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL , 1},
{640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT , 1}, {640, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT , 1},
{640, 480, 0, 0, DM_BITSPERPEL , 1}, {640, 480, 0, 0, DM_BITSPERPEL , 0},
{640, 480, 0, 0, DM_DISPLAYFREQUENCY, 1}, {640, 480, 0, 0, DM_DISPLAYFREQUENCY, 0},
{0, 0, 0, 0, DM_PELSWIDTH, 1}, {0, 0, 0, 0, DM_PELSWIDTH, 0},
{0, 0, 0, 0, DM_PELSHEIGHT, 1}, {0, 0, 0, 0, DM_PELSHEIGHT, 0},
{640, 480, 0, 0, DM_PELSWIDTH, 0}, {640, 480, 0, 0, DM_PELSWIDTH, 0},
{640, 480, 0, 0, DM_PELSHEIGHT, 0}, {640, 480, 0, 0, DM_PELSHEIGHT, 0},
{ 0, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0}, { 0, 480, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0},
{640, 0, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0}, {640, 0, 0, 0, DM_PELSWIDTH | DM_PELSHEIGHT, 0},
{0, 0, 0, 0, DM_DISPLAYFREQUENCY, 0}, /* the following test succeeds under XP SP3
{0, 0, 0, 0, DM_DISPLAYFREQUENCY, 0}
*/
}; };
#define vid_modes_cnt (sizeof(vid_modes_test) / sizeof(vid_modes_test[0])) #define vid_modes_cnt (sizeof(vid_modes_test) / sizeof(vid_modes_test[0]))
@ -155,6 +166,45 @@ static void test_ChangeDisplaySettingsEx(void)
width = dm.dmPelsWidth; width = dm.dmPelsWidth;
dm.dmDriverExtra = 1;
res = ChangeDisplaySettingsA(&dm, CDS_TEST);
ok(res == DISP_CHANGE_SUCCESSFUL,
"ChangeDisplaySettingsA returned %d, expected DISP_CHANGE_SUCCESSFUL\n", res);
ok(dm.dmDriverExtra == 0 || broken(dm.dmDriverExtra == 1) /* win9x */,
"ChangeDisplaySettingsA didn't reset dmDriverExtra to 0\n");
/* crashes under XP SP3 for large dmDriverExtra values */
dm.dmDriverExtra = 1;
res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL);
ok(res == DISP_CHANGE_SUCCESSFUL,
"ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_BADMODE\n", res);
ok(dm.dmDriverExtra == 1, "ChangeDisplaySettingsExA shouldn't reset dmDriverExtra to 0\n");
memset(&dmW, 0, sizeof(dmW));
dmW.dmSize = sizeof(dmW);
dmW.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
dmW.dmPelsWidth = dm.dmPelsWidth;
dmW.dmPelsHeight = dm.dmPelsHeight;
dmW.dmDriverExtra = 1;
SetLastError(0xdeadbeef);
res = ChangeDisplaySettingsW(&dmW, CDS_TEST);
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
{
ok(res == DISP_CHANGE_SUCCESSFUL,
"ChangeDisplaySettingsW returned %d, expected DISP_CHANGE_SUCCESSFUL\n", res);
ok(dmW.dmDriverExtra == 0, "ChangeDisplaySettingsW didn't reset dmDriverExtra to 0\n");
}
/* Apparently XP treats dmDriverExtra being != 0 as an error */
dmW.dmDriverExtra = 1;
res = pChangeDisplaySettingsExW(NULL, &dmW, NULL, CDS_TEST, NULL);
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
{
ok(res == DISP_CHANGE_SUCCESSFUL,
"ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_BADMODE\n", res);
ok(dmW.dmDriverExtra == 1, "ChangeDisplaySettingsExW shouldn't reset dmDriverExtra to 0\n");
}
/* the following 2 tests show that dm.dmSize being 0 is invalid, but /* the following 2 tests show that dm.dmSize being 0 is invalid, but
* ChangeDisplaySettingsExA still reports success. * ChangeDisplaySettingsExA still reports success.
*/ */
@ -162,8 +212,10 @@ static void test_ChangeDisplaySettingsEx(void)
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
dm.dmPelsWidth = width; dm.dmPelsWidth = width;
res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL); res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL);
ok(res == DISP_CHANGE_SUCCESSFUL, ok(res == DISP_CHANGE_SUCCESSFUL ||
"ChangeDisplaySettingsExA returned %d, expected DISP_CHANGE_SUCCESSFUL\n", res); res == DISP_CHANGE_BADMODE || /* Win98, WinMe */
res == DISP_CHANGE_FAILED, /* NT4 */
"ChangeDisplaySettingsExA returned unexpected %d\n", res);
memset(&dmW, 0, sizeof(dmW)); memset(&dmW, 0, sizeof(dmW));
dmW.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; dmW.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
@ -171,8 +223,10 @@ static void test_ChangeDisplaySettingsEx(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
res = pChangeDisplaySettingsExW(NULL, &dmW, NULL, CDS_TEST, NULL); res = pChangeDisplaySettingsExW(NULL, &dmW, NULL, CDS_TEST, NULL);
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
ok(res == DISP_CHANGE_FAILED, ok(res == DISP_CHANGE_FAILED ||
"ChangeDisplaySettingsExW returned %d, expected DISP_CHANGE_FAILED\n", res); res == DISP_CHANGE_BADPARAM || /* NT4 */
res == DISP_CHANGE_BADMODE /* XP SP3 */,
"ChangeDisplaySettingsExW returned %d\n", res);
memset(&dm, 0, sizeof(dm)); memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm); dm.dmSize = sizeof(dm);
@ -184,10 +238,10 @@ static void test_ChangeDisplaySettingsEx(void)
dm.dmBitsPerPel = vid_modes_test[i].bpp; dm.dmBitsPerPel = vid_modes_test[i].bpp;
dm.dmDisplayFrequency = vid_modes_test[i].freq; dm.dmDisplayFrequency = vid_modes_test[i].freq;
dm.dmFields = vid_modes_test[i].fields; dm.dmFields = vid_modes_test[i].fields;
res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_FULLSCREEN, NULL); res = pChangeDisplaySettingsExA(NULL, &dm, NULL, CDS_TEST, NULL);
ok(vid_modes_test[i].success ? ok(vid_modes_test[i].must_succeed ?
(res == DISP_CHANGE_SUCCESSFUL) : (res == DISP_CHANGE_SUCCESSFUL) :
(res == DISP_CHANGE_BADMODE || res == DISP_CHANGE_BADPARAM), (res == DISP_CHANGE_SUCCESSFUL || res == DISP_CHANGE_BADMODE || res == DISP_CHANGE_BADPARAM),
"Unexpected ChangeDisplaySettingsEx() return code for resolution[%d]: %d\n", i, res); "Unexpected ChangeDisplaySettingsEx() return code for resolution[%d]: %d\n", i, res);
if (res == DISP_CHANGE_SUCCESSFUL) if (res == DISP_CHANGE_SUCCESSFUL)
@ -195,6 +249,8 @@ static void test_ChangeDisplaySettingsEx(void)
RECT r, r1, virt; RECT r, r1, virt;
SetRect(&virt, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN)); SetRect(&virt, 0, 0, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN));
if (IsRectEmpty(&virt)) /* NT4 doesn't have SM_CX/YVIRTUALSCREEN */
SetRect(&virt, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
OffsetRect(&virt, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN)); OffsetRect(&virt, GetSystemMetrics(SM_XVIRTUALSCREEN), GetSystemMetrics(SM_YVIRTUALSCREEN));
/* Resolution change resets clip rect */ /* Resolution change resets clip rect */
@ -214,7 +270,10 @@ static void test_ChangeDisplaySettingsEx(void)
SetRect(&r1, virt.left - 10, virt.top - 10, virt.right + 20, virt.bottom + 20); SetRect(&r1, virt.left - 10, virt.top - 10, virt.right + 20, virt.bottom + 20);
ok(ClipCursor(&r1), "ClipCursor() failed\n"); ok(ClipCursor(&r1), "ClipCursor() failed\n");
ok(GetClipCursor(&r), "GetClipCursor() failed\n"); ok(GetClipCursor(&r), "GetClipCursor() failed\n");
ok(EqualRect(&r, &virt), "Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom); ok(EqualRect(&r, &virt) ||
broken(EqualRect(&r, &r1)) /* win9x */,
"Invalid clip rect: (%d %d) x (%d %d)\n", r.left, r.top, r.right, r.bottom);
ClipCursor(&virt);
} }
} }
res = pChangeDisplaySettingsExA(NULL, NULL, NULL, CDS_RESET, NULL); res = pChangeDisplaySettingsExA(NULL, NULL, NULL, CDS_RESET, NULL);
@ -226,6 +285,12 @@ static void test_monitors(void)
HMONITOR monitor, primary; HMONITOR monitor, primary;
POINT pt; POINT pt;
if (!pMonitorFromPoint || !pMonitorFromWindow)
{
skip("MonitorFromPoint or MonitorFromWindow are not available\n");
return;
}
pt.x = pt.y = 0; pt.x = pt.y = 0;
primary = pMonitorFromPoint( pt, MONITOR_DEFAULTTOPRIMARY ); primary = pMonitorFromPoint( pt, MONITOR_DEFAULTTOPRIMARY );
ok( primary != 0, "couldn't get primary monitor\n" ); ok( primary != 0, "couldn't get primary monitor\n" );
@ -238,15 +303,96 @@ static void test_monitors(void)
ok( monitor == primary, "got %p, should get primary %p for MONITOR_DEFAULTTONEAREST\n", monitor, primary ); ok( monitor == primary, "got %p, should get primary %p for MONITOR_DEFAULTTONEAREST\n", monitor, primary );
} }
static BOOL CALLBACK find_primary_mon(HMONITOR hmon, HDC hdc, LPRECT rc, LPARAM lp)
{
MONITORINFO mi;
BOOL ret;
mi.cbSize = sizeof(mi);
ret = pGetMonitorInfoA(hmon, &mi);
ok(ret, "GetMonitorInfo failed\n");
if (mi.dwFlags & MONITORINFOF_PRIMARY)
{
*(HMONITOR *)lp = hmon;
return FALSE;
}
return TRUE;
}
static void test_work_area(void)
{
HMONITOR hmon;
MONITORINFO mi;
RECT rc_work, rc_normal;
HWND hwnd;
WINDOWPLACEMENT wp;
BOOL ret;
if (!pEnumDisplayMonitors || !pGetMonitorInfoA)
{
skip("EnumDisplayMonitors or GetMonitorInfoA are not available\n");
return;
}
hmon = 0;
ret = pEnumDisplayMonitors(NULL, NULL, find_primary_mon, (LPARAM)&hmon);
ok(!ret && hmon != 0, "Failed to find primary monitor\n");
mi.cbSize = sizeof(mi);
SetLastError(0xdeadbeef);
ret = pGetMonitorInfoA(hmon, &mi);
ok(ret, "GetMonitorInfo error %u\n", GetLastError());
ok(mi.dwFlags & MONITORINFOF_PRIMARY, "not a primary monitor\n");
trace("primary monitor (%d,%d-%d,%d)\n",
mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom);
SetLastError(0xdeadbeef);
ret = SystemParametersInfo(SPI_GETWORKAREA, 0, &rc_work, 0);
ok(ret, "SystemParametersInfo error %u\n", GetLastError());
trace("work area (%d,%d-%d,%d)\n", rc_work.left, rc_work.top, rc_work.right, rc_work.bottom);
ok(EqualRect(&rc_work, &mi.rcWork), "work area is different\n");
hwnd = CreateWindowEx(0, "static", NULL, WS_OVERLAPPEDWINDOW|WS_VISIBLE,100,100,10,10,0,0,0,NULL);
ok(hwnd != 0, "CreateWindowEx failed\n");
ret = GetWindowRect(hwnd, &rc_normal);
ok(ret, "GetWindowRect failed\n");
trace("normal (%d,%d-%d,%d)\n", rc_normal.left, rc_normal.top, rc_normal.right, rc_normal.bottom);
wp.length = sizeof(wp);
ret = GetWindowPlacement(hwnd, &wp);
ok(ret, "GetWindowPlacement failed\n");
trace("min: %d,%d max %d,%d normal %d,%d-%d,%d\n",
wp.ptMinPosition.x, wp.ptMinPosition.y,
wp.ptMaxPosition.x, wp.ptMaxPosition.y,
wp.rcNormalPosition.left, wp.rcNormalPosition.top,
wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
OffsetRect(&wp.rcNormalPosition, rc_work.left, rc_work.top);
if (!EqualRect(&mi.rcMonitor, &mi.rcWork)) /* 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");
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
wp.length = sizeof(wp);
ret = GetWindowPlacement(hwnd, &wp);
ok(ret, "GetWindowPlacement failed\n");
trace("min: %d,%d max %d,%d normal %d,%d-%d,%d\n",
wp.ptMinPosition.x, wp.ptMinPosition.y,
wp.ptMaxPosition.x, wp.ptMaxPosition.y,
wp.rcNormalPosition.left, wp.rcNormalPosition.top,
wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
ok(EqualRect(&rc_normal, &wp.rcNormalPosition), "normal pos is different\n");
DestroyWindow(hwnd);
}
START_TEST(monitor) START_TEST(monitor)
{ {
init_function_pointers(); init_function_pointers();
test_enumdisplaydevices(); test_enumdisplaydevices();
if (winetest_interactive)
test_ChangeDisplaySettingsEx(); test_ChangeDisplaySettingsEx();
if (pMonitorFromPoint && pMonitorFromWindow)
test_monitors(); test_monitors();
else test_work_area();
skip("MonitorFromPoint and/or MonitorFromWindow are not available\n");
} }

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,16 @@ static void test_LoadStringW(void)
/* Check that the string which is returned by LoadStringW matches /* Check that the string which is returned by LoadStringW matches
the string at the pointer returned by LoadStringW when called with buflen = 0 */ the string at the pointer returned by LoadStringW when called with buflen = 0 */
SetLastError(0xdeadbeef);
length1 = LoadStringW(hInst, 2, (WCHAR *) &resourcepointer, 0); /* get pointer to resource. */ length1 = LoadStringW(hInst, 2, (WCHAR *) &resourcepointer, 0); /* get pointer to resource. */
if (!length1)
{
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
win_skip( "LoadStringW not implemented\n" );
else
win_skip( "LoadStringW does not return a pointer to the resource\n" );
return;
}
length2 = LoadStringW(hInst, 2, returnedstringw, sizeof(returnedstringw) /sizeof(WCHAR)); /* get resource string */ length2 = LoadStringW(hInst, 2, returnedstringw, sizeof(returnedstringw) /sizeof(WCHAR)); /* get resource string */
ok(length2 > 0, "LoadStringW failed to load resource 2, ret %d, err %d\n", length2, GetLastError()); ok(length2 > 0, "LoadStringW failed to load resource 2, ret %d, err %d\n", length2, GetLastError());
ok(length1 == length2, "LoadStringW returned different values dependent on buflen. ret1 %d, ret2 %d\n", ok(length1 == length2, "LoadStringW returned different values dependent on buflen. ret1 %d, ret2 %d\n",
@ -114,7 +123,8 @@ static void test_LoadStringA (void)
"LoadString failed: ret %d err %d\n", ret, GetLastError()); "LoadString failed: ret %d err %d\n", ret, GetLastError());
ret = LoadStringA(hInst, 0, buf, 0); ret = LoadStringA(hInst, 0, buf, 0);
ok( ret == -1, "LoadStringA did not return -1 when called with buflen = 0, got %d, err %d\n", ok( ret == -1 || broken(ret == 0),
"LoadStringA did not return -1 when called with buflen = 0, got %d, err %d\n",
ret, GetLastError()); ret, GetLastError());
} }
@ -170,41 +180,43 @@ static void test_accel1(void)
ok( hAccel != NULL, "create accelerator table\n"); ok( hAccel != NULL, "create accelerator table\n");
r = CopyAcceleratorTable( hAccel, NULL, 0 ); r = CopyAcceleratorTable( hAccel, NULL, 0 );
ok( r == n, "two entries in table\n"); ok( r == n || broken(r == 2), /* win9x */
"two entries in table %u/%u\n", r, n);
r = CopyAcceleratorTable( hAccel, &ac[0], r ); r = CopyAcceleratorTable( hAccel, &ac[0], n );
ok( r == n, "still should be two entries in table\n"); ok( r == n || broken(r == 2), /* win9x */
"still should be two entries in table %u/%u\n", r, n);
n=0; n=0;
ok( ac[n].cmd == 1000, "cmd 0 not preserved\n"); ok( ac[n].cmd == 1000, "cmd 0 not preserved\n");
ok( ac[n].key == 'A', "key 0 not preserved\n"); ok( ac[n].key == 'A', "key 0 not preserved\n");
ok( ac[n].fVirt == (FVIRTKEY | FNOINVERT), "fVirt 0 not preserved\n"); ok( ac[n].fVirt == (FVIRTKEY | FNOINVERT), "fVirt 0 not preserved\n");
n++; if (++n == r) goto done;
ok( ac[n].cmd == 0xffff, "cmd 1 not preserved\n"); ok( ac[n].cmd == 0xffff, "cmd 1 not preserved\n");
ok( ac[n].key == 0xffff, "key 1 not preserved\n"); ok( ac[n].key == 0xffff, "key 1 not preserved\n");
ok( ac[n].fVirt == 0x007f, "fVirt 1 not changed\n"); ok( ac[n].fVirt == 0x007f, "fVirt 1 not changed\n");
n++; if (++n == r) goto done;
ok( ac[n].cmd == 0xfff0, "cmd 2 not preserved\n"); ok( ac[n].cmd == 0xfff0, "cmd 2 not preserved\n");
ok( ac[n].key == 0x00ff, "key 2 not preserved\n"); ok( ac[n].key == 0x00ff, "key 2 not preserved\n");
ok( ac[n].fVirt == 0x0070, "fVirt 2 not changed\n"); ok( ac[n].fVirt == 0x0070, "fVirt 2 not changed\n");
n++; if (++n == r) goto done;
ok( ac[n].cmd == 0xfff0, "cmd 3 not preserved\n"); ok( ac[n].cmd == 0xfff0, "cmd 3 not preserved\n");
ok( ac[n].key == 0x00ff, "key 3 not preserved\n"); ok( ac[n].key == 0x00ff, "key 3 not preserved\n");
ok( ac[n].fVirt == 0x0000, "fVirt 3 not changed\n"); ok( ac[n].fVirt == 0x0000, "fVirt 3 not changed\n");
n++; if (++n == r) goto done;
ok( ac[n].cmd == 0xfff0, "cmd 4 not preserved\n"); ok( ac[n].cmd == 0xfff0, "cmd 4 not preserved\n");
ok( ac[n].key == 0xffff, "key 4 not preserved\n"); ok( ac[n].key == 0xffff, "key 4 not preserved\n");
ok( ac[n].fVirt == 0x0001, "fVirt 4 not changed\n"); ok( ac[n].fVirt == 0x0001, "fVirt 4 not changed\n");
done:
r = DestroyAcceleratorTable( hAccel ); r = DestroyAcceleratorTable( hAccel );
ok( r, "destroy accelerator table\n"); ok( r, "destroy accelerator table\n");
hAccel = CreateAcceleratorTable( &ac[0], 0 ); hAccel = CreateAcceleratorTable( &ac[0], 0 );
ok( !hAccel, "zero elements should fail\n"); ok( !hAccel || broken(hAccel != NULL), /* nt4 */ "zero elements should fail\n");
/* these will on crash win2k /* these will on crash win2k
hAccel = CreateAcceleratorTable( NULL, 1 ); hAccel = CreateAcceleratorTable( NULL, 1 );
@ -220,6 +232,7 @@ static void test_accel2(void)
{ {
ACCEL ac[2], out[2]; ACCEL ac[2], out[2];
HACCEL hac; HACCEL hac;
int res;
ac[0].cmd = 0; ac[0].cmd = 0;
ac[0].fVirt = 0; ac[0].fVirt = 0;
@ -236,8 +249,8 @@ static void test_accel2(void)
/* try a zero count */ /* try a zero count */
hac = CreateAcceleratorTable( &ac[0], 0 ); hac = CreateAcceleratorTable( &ac[0], 0 );
ok( !hac , "fail\n"); ok( !hac || broken(hac != NULL), /* nt4 */ "fail\n");
ok( !DestroyAcceleratorTable( hac ), "destroy failed\n"); if (!hac) ok( !DestroyAcceleratorTable( hac ), "destroy failed\n");
/* creating one accelerator should work */ /* creating one accelerator should work */
hac = CreateAcceleratorTable( &ac[0], 1 ); hac = CreateAcceleratorTable( &ac[0], 1 );
@ -248,9 +261,12 @@ static void test_accel2(void)
/* how about two of the same type? */ /* how about two of the same type? */
hac = CreateAcceleratorTable( &ac[0], 2); hac = CreateAcceleratorTable( &ac[0], 2);
ok( hac != NULL , "fail\n"); ok( hac != NULL , "fail\n");
ok( 2 == CopyAcceleratorTable( hac, NULL, 100 ), "copy null failed\n"); res = CopyAcceleratorTable( hac, NULL, 100 );
ok( 2 == CopyAcceleratorTable( hac, NULL, 0 ), "copy null failed\n"); ok( res == 2 || broken(res == 0), /* win9x */ "copy null failed %d\n", res);
ok( 2 == CopyAcceleratorTable( hac, NULL, 1 ), "copy null failed\n"); res = CopyAcceleratorTable( hac, NULL, 0 );
ok( res == 2, "copy null failed %d\n", res);
res = CopyAcceleratorTable( hac, NULL, 1 );
ok( res == 2 || broken(res == 0), /* win9x */ "copy null failed %d\n", res);
ok( 1 == CopyAcceleratorTable( hac, out, 1 ), "copy 1 failed\n"); ok( 1 == CopyAcceleratorTable( hac, out, 1 ), "copy 1 failed\n");
ok( 2 == CopyAcceleratorTable( hac, out, 2 ), "copy 2 failed\n"); ok( 2 == CopyAcceleratorTable( hac, out, 2 ), "copy 2 failed\n");
ok( DestroyAcceleratorTable( hac ), "destroy failed\n"); ok( DestroyAcceleratorTable( hac ), "destroy failed\n");
@ -301,14 +317,18 @@ static void test_accel2(void)
memset( ac, 0xff, sizeof ac ); memset( ac, 0xff, sizeof ac );
hac = CreateAcceleratorTable( &ac[0], 2); hac = CreateAcceleratorTable( &ac[0], 2);
ok( hac != NULL , "fail\n"); ok( hac != NULL , "fail\n");
ok( 2 == CopyAcceleratorTable( hac, out, 2 ), "copy 2 failed\n"); res = CopyAcceleratorTable( hac, out, 2 );
ok( res == 2 || broken(res == 1), /* win9x */ "copy 2 failed %d\n", res);
/* ok( memcmp( ac, out, sizeof ac ), "tables not different\n"); */ /* ok( memcmp( ac, out, sizeof ac ), "tables not different\n"); */
ok( out[0].cmd == ac[0].cmd, "cmd modified\n"); ok( out[0].cmd == ac[0].cmd, "cmd modified\n");
ok( out[0].fVirt == (ac[0].fVirt&0x7f), "fVirt not modified\n"); ok( out[0].fVirt == (ac[0].fVirt&0x7f), "fVirt not modified\n");
ok( out[0].key == ac[0].key, "key modified\n"); ok( out[0].key == ac[0].key, "key modified\n");
if (res == 2)
{
ok( out[1].cmd == ac[1].cmd, "cmd modified\n"); ok( out[1].cmd == ac[1].cmd, "cmd modified\n");
ok( out[1].fVirt == (ac[1].fVirt&0x7f), "fVirt not modified\n"); ok( out[1].fVirt == (ac[1].fVirt&0x7f), "fVirt not modified\n");
ok( out[1].key == ac[1].key, "key modified\n"); ok( out[1].key == ac[1].key, "key modified\n");
}
ok( DestroyAcceleratorTable( hac ), "destroy failed\n"); ok( DestroyAcceleratorTable( hac ), "destroy failed\n");
} }
@ -333,9 +353,13 @@ static void test_PrivateExtractIcons(void) {
cIcons = pPrivateExtractIconsA(szShell32Dll, 0, 16, 16, ahIcon, aIconId, 3, 0); cIcons = pPrivateExtractIconsA(szShell32Dll, 0, 16, 16, ahIcon, aIconId, 3, 0);
ok(cIcons == 3, "Three icons requested got cIcons=%d\n", cIcons); ok(cIcons == 3, "Three icons requested got cIcons=%d\n", cIcons);
cIcons = pPrivateExtractIconsA(szShell32Dll, 0, MAKELONG(32,16), MAKELONG(32,16), /* count must be a multiple of two when getting two sizes */
cIcons = pPrivateExtractIconsA(szShell32Dll, 0, MAKELONG(16,32), MAKELONG(16,32),
ahIcon, aIconId, 3, 0); ahIcon, aIconId, 3, 0);
ok(cIcons == 4, "Three icons requested, four expected, got cIcons=%d\n", cIcons); ok(cIcons == 0 /* vista */ || cIcons == 4, "Three icons requested got cIcons=%d\n", cIcons);
cIcons = pPrivateExtractIconsA(szShell32Dll, 0, MAKELONG(16,32), MAKELONG(16,32),
ahIcon, aIconId, 4, 0);
ok(cIcons == 4, "Four icons requested got cIcons=%d\n", cIcons);
} }
static void test_LoadImage(void) static void test_LoadImage(void)

View file

@ -165,13 +165,16 @@ FONT 8, "MS Shell Dlg"
{ {
POPUP "&File" POPUP "&File"
{ {
MENUITEM "&New", 100 POPUP "&New..."
{
MENUITEM "&New file", 100
}
MENUITEM "&Open", 101 MENUITEM "&Open", 101
MENUITEM "&Save", 102 MENUITEM "&Save", 102
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "E&xit", 103 MENUITEM "E&xit", 103
} }
POPUP "Edit" POPUP "&Edit"
{ {
MENUITEM "&Undo", 200 MENUITEM "&Undo", 200
MENUITEM SEPARATOR MENUITEM SEPARATOR

View file

@ -127,6 +127,74 @@ static void scrollbar_test3(void)
} }
static void scrollbar_test4(void)
{
BOOL ret;
SCROLLBARINFO sbi;
RECT rect;
BOOL (WINAPI *pGetScrollBarInfo)(HWND, LONG, LPSCROLLBARINFO);
pGetScrollBarInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetScrollBarInfo");
if (!pGetScrollBarInfo)
{
win_skip("GetScrollBarInfo is not available\n");
return;
}
/* Test GetScrollBarInfo to make sure it returns rcScrollBar in screen
* coordinates. */
sbi.cbSize = sizeof(sbi);
ret = pGetScrollBarInfo( hScroll, OBJID_CLIENT, &sbi);
ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
GetWindowRect( hScroll, &rect );
ok( ret, "The GetWindowRect() call should not fail.\n" );
ok( !(sbi.rgstate[0] & (STATE_SYSTEM_INVISIBLE|STATE_SYSTEM_OFFSCREEN)),
"unexpected rgstate(0x%x)\n", sbi.rgstate[0]);
ok( EqualRect(&rect, &sbi.rcScrollBar),
"WindowRect(%d, %d, %d, %d) != rcScrollBar(%d, %d, %d, %d)\n",
rect.top, rect.left, rect.bottom, rect.right,
sbi.rcScrollBar.top, sbi.rcScrollBar.left,
sbi.rcScrollBar.bottom, sbi.rcScrollBar.right );
/* Test windows horizontal and vertical scrollbar to make sure rcScrollBar
* is still returned in screen coordinates by moving the window, and
* making sure that it shifts the rcScrollBar value. */
ShowWindow( hMainWnd, SW_SHOW );
sbi.cbSize = sizeof(sbi);
ret = pGetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi);
ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
GetWindowRect( hMainWnd, &rect );
ok( ret, "The GetWindowRect() call should not fail.\n" );
MoveWindow( hMainWnd, rect.left+5, rect.top+5,
rect.right-rect.left, rect.bottom-rect.top, TRUE );
rect = sbi.rcScrollBar;
OffsetRect(&rect, 5, 5);
ret = pGetScrollBarInfo( hMainWnd, OBJID_HSCROLL, &sbi);
ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
ok( EqualRect(&rect, &sbi.rcScrollBar),
"PreviousRect(%d, %d, %d, %d) != CurrentRect(%d, %d, %d, %d)\n",
rect.top, rect.left, rect.bottom, rect.right,
sbi.rcScrollBar.top, sbi.rcScrollBar.left,
sbi.rcScrollBar.bottom, sbi.rcScrollBar.right );
sbi.cbSize = sizeof(sbi);
ret = pGetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi);
ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
GetWindowRect( hMainWnd, &rect );
ok( ret, "The GetWindowRect() call should not fail.\n" );
MoveWindow( hMainWnd, rect.left+5, rect.top+5,
rect.right-rect.left, rect.bottom-rect.top, TRUE );
rect = sbi.rcScrollBar;
OffsetRect(&rect, 5, 5);
ret = pGetScrollBarInfo( hMainWnd, OBJID_VSCROLL, &sbi);
ok( ret, "The GetScrollBarInfo() call should not fail.\n" );
ok( EqualRect(&rect, &sbi.rcScrollBar),
"PreviousRect(%d, %d, %d, %d) != CurrentRect(%d, %d, %d, %d)\n",
rect.top, rect.left, rect.bottom, rect.right,
sbi.rcScrollBar.top, sbi.rcScrollBar.left,
sbi.rcScrollBar.bottom, sbi.rcScrollBar.right );
}
START_TEST ( scroll ) START_TEST ( scroll )
{ {
WNDCLASSA wc; WNDCLASSA wc;
@ -143,7 +211,8 @@ START_TEST ( scroll )
wc.lpfnWndProc = MyWndProc; wc.lpfnWndProc = MyWndProc;
RegisterClassA(&wc); RegisterClassA(&wc);
hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll", WS_OVERLAPPEDWINDOW, hMainWnd = CreateWindowExA( 0, "MyTestWnd", "Scroll",
WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0 ); CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0 );
if ( !ok( hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n" ) ) if ( !ok( hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n" ) )
@ -154,6 +223,7 @@ START_TEST ( scroll )
scrollbar_test1(); scrollbar_test1();
scrollbar_test2(); scrollbar_test2();
scrollbar_test3(); scrollbar_test3();
scrollbar_test4();
DestroyWindow(hScroll); DestroyWindow(hScroll);
DestroyWindow(hMainWnd); DestroyWindow(hMainWnd);

View file

@ -33,12 +33,12 @@
static HWND hMainWnd; static HWND hMainWnd;
#define expect_eq(expr, value, type, fmt) { type val = expr; ok(val == (value), #expr " expected " #fmt " got " #fmt "\n", (value), val); } #define expect_eq(expr, value, type, fmt) { type val = expr; ok(val == (value), #expr " expected " fmt " got " fmt "\n", (value), val); }
#define expect_rect(r, _left, _top, _right, _bottom) ok(r.left == _left && r.top == _top && \ #define expect_rect(r, _left, _top, _right, _bottom) ok(r.left == _left && r.top == _top && \
r.bottom == _bottom && r.right == _right, "Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", \ r.bottom == _bottom && r.right == _right, "Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", \
r.left, r.top, r.right, r.bottom, _left, _top, _right, _bottom); r.left, r.top, r.right, r.bottom, _left, _top, _right, _bottom);
int g_nReceivedColorStatic = 0; static int g_nReceivedColorStatic = 0;
static HWND build_static(DWORD style) static HWND build_static(DWORD style)
{ {
@ -63,7 +63,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lpara
return DefWindowProc(hwnd, msg, wparam, lparam); return DefWindowProc(hwnd, msg, wparam, lparam);
} }
void test_updates(int style, int flags) static void test_updates(int style, int flags)
{ {
RECT r1 = {20, 20, 30, 30}; RECT r1 = {20, 20, 30, 30};
HWND hStatic = build_static(style); HWND hStatic = build_static(style);
@ -89,6 +89,10 @@ void test_updates(int style, int flags)
if (flags & TODO_COUNT) if (flags & TODO_COUNT)
todo_wine { expect_eq(g_nReceivedColorStatic, exp, int, "%d"); } todo_wine { expect_eq(g_nReceivedColorStatic, exp, int, "%d"); }
else if (style == SS_ICON || style == SS_BITMAP)
ok( g_nReceivedColorStatic == exp ||
broken(g_nReceivedColorStatic == 0), /* win9x */
"expected %u got %u\n", exp, g_nReceivedColorStatic );
else else
expect_eq(g_nReceivedColorStatic, exp, int, "%d"); expect_eq(g_nReceivedColorStatic, exp, int, "%d");
DestroyWindow(hStatic); DestroyWindow(hStatic);
@ -108,7 +112,7 @@ START_TEST(static)
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszClassName = szClassName; wndclass.lpszClassName = szClassName;
wndclass.lpszMenuName = NULL; wndclass.lpszMenuName = NULL;
RegisterClassEx(&wndclass); RegisterClassEx(&wndclass);

View file

@ -22,8 +22,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#undef _WIN32_WINNT #define SPI_SETWHEELSCROLLCHARS 109
#define _WIN32_WINNT 0x0500 /* For SPI_GETMOUSEHOVERWIDTH and more */
#include "wine/test.h" #include "wine/test.h"
#include "windef.h" #include "windef.h"
@ -129,12 +128,16 @@ static HDC hdc;
#define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive" #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
#define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop" #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
#define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows" #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
#define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
#define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
#define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse" #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
#define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth" #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
#define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse" #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
#define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight" #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
#define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse" #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
#define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime" #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
#define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
#define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
#define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop" #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
#define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines" #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
#define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop" #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
@ -219,7 +222,7 @@ static BOOL test_error_msg ( int rc, const char *name )
if (rc==0) if (rc==0)
{ {
if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE) if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
{ {
trace("%s not supported on this platform. Skipping test\n", name); trace("%s not supported on this platform. Skipping test\n", name);
} }
@ -1773,7 +1776,7 @@ static void test_SPI_SETSHOWSOUNDS( void ) /* 57 */
rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0, rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
test_change_message( SPI_SETSHOWSOUNDS, 0 ); test_change_message( SPI_SETSHOWSOUNDS, 1 );
test_reg_key( SPI_SETSHOWSOUNDS_REGKEY, test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
SPI_SETSHOWSOUNDS_VALNAME, SPI_SETSHOWSOUNDS_VALNAME,
vals[i] ? "1" : "0" ); vals[i] ? "1" : "0" );
@ -1809,7 +1812,7 @@ static void test_SPI_SETKEYBOARDPREF( void ) /* 69 */
rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0, rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
test_change_message( SPI_SETKEYBOARDPREF, 0 ); test_change_message( SPI_SETKEYBOARDPREF, 1 );
test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY, test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY, SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
vals[i] ? "1" : "0" ); vals[i] ? "1" : "0" );
@ -1843,7 +1846,7 @@ static void test_SPI_SETSCREENREADER( void ) /* 71 */
rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0, rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
test_change_message( SPI_SETSCREENREADER, 0 ); test_change_message( SPI_SETSCREENREADER, 1 );
test_reg_key_ex2( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY, test_reg_key_ex2( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY, SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
vals[i] ? "1" : "0" ); vals[i] ? "1" : "0" );
@ -1912,14 +1915,17 @@ static void test_SPI_SETLOWPOWERACTIVE( void ) /* 85 */
rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0, rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
test_change_message( SPI_SETLOWPOWERACTIVE, 0 ); test_change_message( SPI_SETLOWPOWERACTIVE, 1 );
test_reg_key( SPI_SETLOWPOWERACTIVE_REGKEY, test_reg_key( SPI_SETLOWPOWERACTIVE_REGKEY,
SPI_SETLOWPOWERACTIVE_VALNAME, SPI_SETLOWPOWERACTIVE_VALNAME,
vals[i] ? "1" : "0" ); vals[i] ? "1" : "0" );
/* SPI_SETLOWPOWERACTIVE is not persistent in win2k3 and above */
rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 ); rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
eq( v, vals[i], "SPI_GETLOWPOWERACTIVE", "%d" ); ok(v == vals[i] ||
v == 0, /* win2k3 */
"SPI_GETLOWPOWERACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
} }
rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE ); rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
@ -1946,20 +1952,57 @@ static void test_SPI_SETPOWEROFFACTIVE( void ) /* 86 */
rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0, rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ); SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
test_change_message( SPI_SETPOWEROFFACTIVE, 0 ); test_change_message( SPI_SETPOWEROFFACTIVE, 1 );
test_reg_key( SPI_SETPOWEROFFACTIVE_REGKEY, test_reg_key( SPI_SETPOWEROFFACTIVE_REGKEY,
SPI_SETPOWEROFFACTIVE_VALNAME, SPI_SETPOWEROFFACTIVE_VALNAME,
vals[i] ? "1" : "0" ); vals[i] ? "1" : "0" );
/* SPI_SETPOWEROFFACTIVE is not persistent in win2k3 and above */
rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 ); rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError()); ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
eq( v, vals[i], "SPI_GETPOWEROFFACTIVE", "%d" ); ok(v == vals[i] ||
v == 0, /* win2k3 */
"SPI_GETPOWEROFFACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
} }
rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE ); rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError()); ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
} }
static void test_SPI_SETSNAPTODEFBUTTON( void ) /* 95 */
{
BOOL rc;
BOOL old_b;
const UINT vals[]={TRUE,FALSE};
unsigned int i;
trace("testing SPI_{GET,SET}SNAPTODEFBUTTON\n");
SetLastError(0xdeadbeef);
rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &old_b, 0 );
if (!test_error_msg(rc,"SPI_GETSNAPTODEFBUTTON"))
return;
for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
{
UINT v;
rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
test_change_message( SPI_SETSNAPTODEFBUTTON, 0 );
test_reg_key( SPI_SETSNAPTODEFBUTTON_REGKEY,
SPI_SETSNAPTODEFBUTTON_VALNAME,
vals[i] ? "1" : "0" );
rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &v, 0 );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
eq( v, vals[i], "SPI_GETSNAPTODEFBUTTON", "%d" );
}
rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, old_b, 0, SPIF_UPDATEINIFILE );
ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
}
static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */ static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */
{ {
BOOL rc; BOOL rc;
@ -2157,6 +2200,44 @@ static void test_SPI_SETMENUSHOWDELAY( void ) /* 107 */
ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError()); ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
} }
static void test_SPI_SETWHEELSCROLLCHARS( void ) /* 108 */
{
BOOL rc;
UINT old_chars;
const UINT vals[]={32767,0};
unsigned int i;
trace("testing SPI_{GET,SET}WHEELSCROLLCHARS\n");
SetLastError(0xdeadbeef);
rc=SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &old_chars, 0 );
/* SPI_{GET,SET}WHEELSCROLLCHARS not supported on Windows 95 */
if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLCHARS"))
return;
for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
{
UINT v;
char buf[10];
rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, vals[i], 0,
SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
if (!test_error_msg(rc,"SPI_SETWHEELSCROLLCHARS")) return;
test_change_message( SPI_SETWHEELSCROLLCHARS, 0 );
sprintf( buf, "%d", vals[i] );
test_reg_key( SPI_SETMOUSESCROLLCHARS_REGKEY,
SPI_SETMOUSESCROLLCHARS_VALNAME, buf );
SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &v, 0 );
ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLCHARS", "%d" );
}
rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, old_chars, 0,
SPIF_UPDATEINIFILE );
ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
}
static void test_SPI_SETWALLPAPER( void ) /* 115 */ static void test_SPI_SETWALLPAPER( void ) /* 115 */
{ {
BOOL rc; BOOL rc;
@ -2294,11 +2375,13 @@ static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
test_SPI_SETFONTSMOOTHING(); /* 75 */ test_SPI_SETFONTSMOOTHING(); /* 75 */
test_SPI_SETLOWPOWERACTIVE(); /* 85 */ test_SPI_SETLOWPOWERACTIVE(); /* 85 */
test_SPI_SETPOWEROFFACTIVE(); /* 86 */ test_SPI_SETPOWEROFFACTIVE(); /* 86 */
test_SPI_SETSNAPTODEFBUTTON(); /* 95 */
test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */ test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */
test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */ test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */
test_SPI_SETMOUSEHOVERTIME(); /* 103 */ test_SPI_SETMOUSEHOVERTIME(); /* 103 */
test_SPI_SETWHEELSCROLLLINES(); /* 105 */ test_SPI_SETWHEELSCROLLLINES(); /* 105 */
test_SPI_SETMENUSHOWDELAY(); /* 107 */ test_SPI_SETMENUSHOWDELAY(); /* 107 */
test_SPI_SETWHEELSCROLLCHARS(); /* 108 */
test_SPI_SETWALLPAPER(); /* 115 */ test_SPI_SETWALLPAPER(); /* 115 */
test_WM_DISPLAYCHANGE(); test_WM_DISPLAYCHANGE();
@ -2389,6 +2472,8 @@ static void test_GetSystemMetrics( void)
INT CaptionWidth; INT CaptionWidth;
MINIMIZEDMETRICS minim; MINIMIZEDMETRICS minim;
NONCLIENTMETRICS ncm; NONCLIENTMETRICS ncm;
SIZE screen;
minim.cbSize = sizeof( minim); minim.cbSize = sizeof( minim);
ncm.cbSize = sizeof( ncm); ncm.cbSize = sizeof( ncm);
SystemParametersInfo( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0); SystemParametersInfo( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
@ -2464,8 +2549,9 @@ static void test_GetSystemMetrics( void)
/* SM_SECURE */ /* SM_SECURE */
ok_gsm( SM_CXEDGE, 2); ok_gsm( SM_CXEDGE, 2);
ok_gsm( SM_CYEDGE, 2); ok_gsm( SM_CYEDGE, 2);
ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + minim.iHorzGap ); /* sign-extension for iHorzGap/iVertGap is broken on Win9x */
ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + minim.iVertGap ); ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + (short)minim.iHorzGap );
ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + (short)minim.iVertGap );
/* SM_CXSMICON */ /* SM_CXSMICON */
/* SM_CYSMICON */ /* SM_CYSMICON */
ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1); ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
@ -2481,10 +2567,15 @@ static void test_GetSystemMetrics( void)
/* SM_ARRANGE */ /* SM_ARRANGE */
ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6); ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5); ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
ok_gsm( SM_CXMAXTRACK, GetSystemMetrics( SM_CXVIRTUALSCREEN) + screen.cx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
4 + 2 * GetSystemMetrics( SM_CXFRAME)); screen.cy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
ok_gsm( SM_CYMAXTRACK, GetSystemMetrics( SM_CYVIRTUALSCREEN) + if (!screen.cx || !screen.cy) /* not supported on NT4 */
4 + 2 * GetSystemMetrics( SM_CYFRAME)); {
screen.cx = GetSystemMetrics( SM_CXSCREEN );
screen.cy = GetSystemMetrics( SM_CYSCREEN );
}
ok_gsm( SM_CXMAXTRACK, screen.cx + 4 + 2 * GetSystemMetrics(SM_CXFRAME));
ok_gsm( SM_CYMAXTRACK, screen.cy + 4 + 2 * GetSystemMetrics(SM_CYFRAME));
/* the next two cannot really be tested as they depend on (application) /* the next two cannot really be tested as they depend on (application)
* toolbars */ * toolbars */
/* SM_CXMAXIMIZED */ /* SM_CXMAXIMIZED */

View file

@ -27,6 +27,9 @@
#include "winuser.h" #include "winuser.h"
#include "winerror.h" #include "winerror.h"
#define MODIFIED(rect) (rect.left = 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100)
#define SAME(rect) (rect.left = 10 && rect.right == 100 && rect.top == 10 && rect.bottom == 100)
#define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top)
static void test_DrawTextCalcRect(void) static void test_DrawTextCalcRect(void)
{ {
@ -40,9 +43,11 @@ static void test_DrawTextCalcRect(void)
's','t','r','i','n','g','\0'}; 's','t','r','i','n','g','\0'};
static CHAR emptystring[] = ""; static CHAR emptystring[] = "";
static WCHAR emptystringW[] = { 0 }; static WCHAR emptystringW[] = { 0 };
INT textlen, textheight; INT textlen, textheight, heightcheck;
RECT rect = { 0, 0, 100, 0 }; RECT rect = { 0, 0, 100, 0 };
BOOL ret; BOOL ret;
DRAWTEXTPARAMS dtp;
BOOL conform_xp = TRUE;
/* Initialization */ /* Initialization */
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP,
@ -105,64 +110,441 @@ static void test_DrawTextCalcRect(void)
rect.bottom); rect.bottom);
/* empty or null text should in some cases calc an empty rectangle */ /* empty or null text should in some cases calc an empty rectangle */
/* note: testing the function's return value is useless, it differs
* ( 0 or 1) on every Windows version I tried */
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL ); heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL );
ok( !(rect.left == rect.right && rect.bottom == rect.top), ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty.\n"); "rectangle should NOT be empty got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
if (textheight != 0) /* Windows 98 */
{
win_skip("XP conformity failed, skipping XP tests. Probably win9x\n");
conform_xp = FALSE;
}
else
ok(textheight==0,"Got textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
SetLastError( 0); SetLastError( 0);
textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL ); heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL );
ok( (rect.left == rect.right && rect.bottom == rect.top), ok( EMPTY(rect),
"rectangle should be empty.\n"); "rectangle should be empty got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT);
ok( EMPTY(rect),
"rectangle should be empty got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
SetLastError( 0); SetLastError( 0);
textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL ); heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
ok( (rect.left == rect.right && rect.bottom == rect.top), ok( EMPTY(rect) || !MODIFIED(rect),
"rectangle should be empty.\n"); "rectangle should be empty or not modified got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
if (!textheight) /* Windows NT 4 */
{
if (conform_xp)
win_skip("XP conformity failed, skipping XP tests. Probably winNT\n");
conform_xp = FALSE;
}
else
ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL ); textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT);
ok( !(rect.left == rect.right && rect.bottom == rect.top), ok( EMPTY(rect) || !MODIFIED(rect),
"rectangle should NOT be empty.\n"); "rectangle should be empty or NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
/* DT_SINGLELINE tests */
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100);
SetLastError( 0);
heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && MODIFIED(rect),
"rectangle should be modified got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && MODIFIED (rect),
"rectangle should be modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100);
SetLastError( 0);
heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( (!EMPTY(rect) && MODIFIED(rect)) || !MODIFIED(rect),
"rectangle should be modified got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( (!EMPTY(rect) && MODIFIED(rect)) || !MODIFIED(rect),
"rectangle should be modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExA\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
/* further tests with 0 count, NULL and empty strings */
heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0);
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0);
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0);
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextA\n");
textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0);
ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL );
ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0);
if (conform_xp)
ok(textheight!=0,"Failed to get textheight from DrawTextA\n");
textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL );
if (conform_xp)
ok(textheight!=0,"Failed to get textheight from DrawTextExA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0);
ok(textheight==0,"Got textheight from DrawTextA\n");
textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL );
ok(textheight==0,"Got textheight from DrawTextA\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
/* invalid dtp size test */
dtp.cbSize = -1; /* Invalid */
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExA\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
/* Wide char versions */ /* Wide char versions */
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
SetLastError( 0); SetLastError( 0);
textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL ); heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL );
if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) { if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
ok( !(rect.left == rect.right && rect.bottom == rect.top), ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty.\n"); "rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL ); textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT);
ok( (rect.left == rect.right && rect.bottom == rect.top), ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should be empty.\n"); "rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL ); heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL );
ok( !(rect.left == rect.right && rect.bottom == rect.top), ok( EMPTY(rect),
"rectangle should NOT be empty.\n"); "rectangle should be empty got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100); SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL ); textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT);
ok( !(rect.left == rect.right && rect.bottom == rect.top), ok( EMPTY(rect),
"rectangle should NOT be empty.\n"); "rectangle should be empty got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (textheight) /* windows 2000 */
{
if (conform_xp)
win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n");
conform_xp = FALSE;
}
else
ok(textheight==0,"Got textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
if (conform_xp) {
/* Crashes on NT4 */
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight==0,"Got textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight==0,"Got textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
}
/* DT_SINGLELINE tests */
heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && MODIFIED(rect),
"rectangle should be modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && MODIFIED(rect),
"rectangle should be modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
if (conform_xp) {
/* Crashes on NT4 */
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight==0,"Got textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
ok(textheight==0,"Got textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
}
SetRect( &rect, 10,10, 100, 100);
heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL );
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExW\n");
SetRect( &rect, 10,10, 100, 100);
textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE);
ok( !EMPTY(rect) && !MODIFIED(rect),
"rectangle should NOT be empty and NOT modified got %d,%d-%d,%d\n",
rect.left, rect.top, rect.right, rect.bottom );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
/* further tests with NULL and empty strings */
heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0);
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0);
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0);
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextW\n");
textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL );
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0);
ok(textheight!=0,"Failed to get textheight from DrawTextW\n");
textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL );
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
if (conform_xp) {
/* Crashes on NT4 */
heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0);
ok(textheight==0,"Got textheight from DrawTextW\n");
textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL );
ok(textheight==0,"Got textheight from DrawTextExW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0);
ok(textheight==0,"Got textheight from DrawTextW\n");
textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL );
ok(textheight==0,"Got textheight from DrawTextW\n");
ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n");
}
dtp.cbSize = -1; /* Invalid */
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp);
ok(textheight!=0,"Failed to get textheight from DrawTextExW\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp);
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExW\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp);
if (conform_xp)
ok(textheight==0,"Got textheight from DrawTextExW\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExW\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
if (conform_xp) {
/* Crashes on NT4 */
dtp.uiLengthDrawn = 1337;
textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp);
ok(textheight==0,"Got textheight from DrawTextExW\n");
ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn);
}
} }
/* More test cases from bug 12226 */ /* More test cases from bug 12226 */
SetRect(&rect, 0, 0, 0, 0); SetRect(&rect, 0, 0, 0, 0);
textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
todo_wine ok(textheight, "DrawTextA error %u\n", GetLastError()); ok(textheight, "DrawTextA error %u\n", GetLastError());
ok(0 == rect.left, "expected 0, got %d\n", rect.left); ok(0 == rect.left, "expected 0, got %d\n", rect.left);
ok(0 == rect.right, "expected 0, got %d\n", rect.right); ok(0 == rect.right, "expected 0, got %d\n", rect.right);
ok(0 == rect.top, "expected 0, got %d\n", rect.top); ok(0 == rect.top, "expected 0, got %d\n", rect.top);
todo_wine ok(rect.bottom, "rect.bottom should not be 0\n"); ok(rect.bottom, "rect.bottom should not be 0\n");
SetRect(&rect, 0, 0, 0, 0); SetRect(&rect, 0, 0, 0, 0);
textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE);
todo_wine ok(textheight, "DrawTextW error %u\n", GetLastError()); if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip( "DrawTextW not implemented\n" );
}
else
{
ok(textheight, "DrawTextW error %u\n", GetLastError());
ok(0 == rect.left, "expected 0, got %d\n", rect.left); ok(0 == rect.left, "expected 0, got %d\n", rect.left);
ok(0 == rect.right, "expected 0, got %d\n", rect.right); ok(0 == rect.right, "expected 0, got %d\n", rect.right);
ok(0 == rect.top, "expected 0, got %d\n", rect.top); ok(0 == rect.top, "expected 0, got %d\n", rect.top);
todo_wine ok(rect.bottom, "rect.bottom should not be 0\n"); ok(rect.bottom, "rect.bottom should not be 0\n");
}
SelectObject(hdc, hOldFont); SelectObject(hdc, hOldFont);
ret = DeleteObject(hFont); ret = DeleteObject(hFont);
@ -292,13 +674,13 @@ static void test_DrawState(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DrawState(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text), ret = DrawState(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text),
0, 0, 10, 10, DST_TEXT); 0, 0, 10, 10, DST_TEXT);
ok(!ret, "DrawState succeeded\n"); ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError()); ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = DrawState(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0, ret = DrawState(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0,
0, 0, 10, 10, DST_TEXT); 0, 0, 10, 10, DST_TEXT);
ok(!ret, "DrawState succeeded\n"); ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n");
ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError()); ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError());
ReleaseDC(hwnd, hdc); ReleaseDC(hwnd, hdc);

File diff suppressed because it is too large Load diff

View file

@ -122,7 +122,9 @@ static void test_handles(void)
flags = 0; flags = 0;
ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" ); ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" );
ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), "handle %p PROTECT_FROM_CLOSE set\n", w1 ); ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ||
broken(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), /* set on nt4 */
"handle %p PROTECT_FROM_CLOSE set\n", w1 );
ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0, ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0,
TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" ); TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
@ -201,7 +203,11 @@ static void test_handles(void)
ok( GetLastError() == ERROR_BUSY, "bad last error %d\n", GetLastError() ); ok( GetLastError() == ERROR_BUSY, "bad last error %d\n", GetLastError() );
SetLastError( 0xdeadbeef ); SetLastError( 0xdeadbeef );
ok( !CloseHandle(d1), "closing thread desktop handle failed\n" ); if (CloseHandle( d1 )) /* succeeds on nt4 */
{
win_skip( "NT4 desktop handle management is completely different\n" );
return;
}
ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() ); ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() );
ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0, ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0,