mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2025-08-29 02:33:58 +02:00
605 lines
20 KiB
C
605 lines
20 KiB
C
/* Unit tests for the syslink control.
|
|
*
|
|
* Copyright 2011 Francois Gouget for CodeWeavers
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#define COBJMACROS
|
|
#include <windows.h>
|
|
#include <commctrl.h>
|
|
|
|
#include <initguid.h>
|
|
#include <oleacc.h>
|
|
|
|
#include "wine/test.h"
|
|
#include "v6util.h"
|
|
#include "msg.h"
|
|
|
|
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
|
|
#define NUM_MSG_SEQUENCE 2
|
|
#define PARENT_SEQ_INDEX 0
|
|
#define SYSLINK_SEQ_INDEX 1
|
|
|
|
static HWND hWndParent;
|
|
static int g_link_id;
|
|
|
|
static struct msg_sequence *sequences[NUM_MSG_SEQUENCE];
|
|
|
|
static void CALLBACK msg_winevent_proc(HWINEVENTHOOK hevent,
|
|
DWORD event,
|
|
HWND hwnd,
|
|
LONG object_id,
|
|
LONG child_id,
|
|
DWORD thread_id,
|
|
DWORD event_time)
|
|
{
|
|
struct message msg = {0};
|
|
WCHAR class_name[256];
|
|
|
|
/* ignore events not from a syslink control */
|
|
if (!GetClassNameW(hwnd, class_name, ARRAY_SIZE(class_name)) ||
|
|
wcscmp(class_name, WC_LINK) != 0)
|
|
return;
|
|
|
|
msg.message = event;
|
|
msg.flags = winevent_hook|wparam|lparam;
|
|
msg.wParam = object_id;
|
|
msg.lParam = child_id;
|
|
add_message(sequences, SYSLINK_SEQ_INDEX, &msg);
|
|
}
|
|
|
|
static void init_winevent_hook(void) {
|
|
hwineventhook = SetWinEventHook(EVENT_MIN, EVENT_MAX, GetModuleHandleA(0), msg_winevent_proc,
|
|
0, GetCurrentThreadId(), WINEVENT_INCONTEXT);
|
|
if (!hwineventhook)
|
|
win_skip( "no win event hook support\n" );
|
|
}
|
|
|
|
static void uninit_winevent_hook(void) {
|
|
if (!hwineventhook)
|
|
return;
|
|
|
|
UnhookWinEvent(hwineventhook);
|
|
hwineventhook = 0;
|
|
}
|
|
|
|
static const struct message create_syslink_wnd_seq[] = {
|
|
{ EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_WINDOW, CHILDID_SELF },
|
|
{0}
|
|
};
|
|
|
|
static const struct message parent_create_syslink_wnd_seq[] = {
|
|
{ WM_GETFONT, sent|optional}, /* Only on XP */
|
|
{ WM_QUERYUISTATE, sent|optional},
|
|
{ WM_CTLCOLORSTATIC, sent},
|
|
{ WM_NOTIFY, sent|wparam, 0},
|
|
{ WM_PARENTNOTIFY, sent|wparam, WM_CREATE},
|
|
{0}
|
|
};
|
|
|
|
static const struct message visible_syslink_wnd_seq[] = {
|
|
{ WM_STYLECHANGING, sent|wparam, GWL_STYLE},
|
|
{ WM_STYLECHANGED, sent|wparam, GWL_STYLE},
|
|
{ WM_PAINT, sent},
|
|
{0}
|
|
};
|
|
|
|
static const struct message parent_visible_syslink_wnd_seq[] = {
|
|
{ WM_CTLCOLORSTATIC, sent},
|
|
{ WM_NOTIFY, sent|wparam, 0},
|
|
{0}
|
|
};
|
|
|
|
static const struct message settext_syslink_wnd_seq[] = {
|
|
{ WM_SETTEXT, sent },
|
|
{ EVENT_OBJECT_NAMECHANGE, winevent_hook|wparam|lparam, OBJID_WINDOW, CHILDID_SELF },
|
|
{ WM_PAINT, sent },
|
|
{ WM_ERASEBKGND, sent|defwinproc|optional }, /* Wine only */
|
|
{0}
|
|
};
|
|
|
|
static const struct message parent_settext_syslink_wnd_seq[] = {
|
|
{ WM_CTLCOLORSTATIC, sent },
|
|
{ WM_NOTIFY, sent|wparam|lparam|optional, 0, NM_CUSTOMDRAW }, /* FIXME: Not sent on Wine */
|
|
{0}
|
|
};
|
|
|
|
/* Try to make sure pending X events have been processed before continuing */
|
|
static void flush_events(void)
|
|
{
|
|
MSG msg;
|
|
int diff = 200;
|
|
int min_timeout = 100;
|
|
DWORD time = GetTickCount() + diff;
|
|
|
|
while (diff > 0)
|
|
{
|
|
if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
|
|
while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
|
|
diff = time - GetTickCount();
|
|
}
|
|
}
|
|
|
|
static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static LONG defwndproc_counter = 0;
|
|
LRESULT ret;
|
|
struct message msg;
|
|
|
|
/* log system messages, except for painting */
|
|
if (message < WM_USER &&
|
|
message != WM_PAINT &&
|
|
message != WM_ERASEBKGND &&
|
|
message != WM_NCPAINT &&
|
|
message != WM_NCHITTEST &&
|
|
message != WM_GETTEXT &&
|
|
message != WM_GETICON &&
|
|
message != WM_DEVICECHANGE)
|
|
{
|
|
msg.message = message;
|
|
msg.flags = sent|wparam|lparam;
|
|
if (defwndproc_counter) msg.flags |= defwinproc;
|
|
msg.wParam = wParam;
|
|
msg.lParam = lParam;
|
|
if (message == WM_NOTIFY && lParam)
|
|
msg.lParam = ((NMHDR*)lParam)->code;
|
|
add_message(sequences, PARENT_SEQ_INDEX, &msg);
|
|
}
|
|
|
|
switch(message)
|
|
{
|
|
case WM_NOTIFY:
|
|
{
|
|
NMLINK *nml = ((NMLINK *)lParam);
|
|
if (nml && NM_CLICK == nml->hdr.code)
|
|
{
|
|
g_link_id = nml->item.iLink;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
defwndproc_counter++;
|
|
ret = DefWindowProcW(hwnd, message, wParam, lParam);
|
|
defwndproc_counter--;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static BOOL register_parent_wnd_class(void)
|
|
{
|
|
WNDCLASSW cls;
|
|
|
|
cls.style = 0;
|
|
cls.lpfnWndProc = parent_wnd_proc;
|
|
cls.cbClsExtra = 0;
|
|
cls.cbWndExtra = 0;
|
|
cls.hInstance = GetModuleHandleW(NULL);
|
|
cls.hIcon = 0;
|
|
cls.hCursor = LoadCursorW(0, (LPCWSTR)IDC_ARROW);
|
|
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
|
cls.lpszMenuName = NULL;
|
|
cls.lpszClassName = L"Syslink test parent class";
|
|
return RegisterClassW(&cls);
|
|
}
|
|
|
|
static HWND create_parent_window(void)
|
|
{
|
|
if (!register_parent_wnd_class())
|
|
return NULL;
|
|
|
|
return CreateWindowExW(0, L"Syslink test parent class", L"Syslink test parent window",
|
|
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
|
|
WS_MAXIMIZEBOX | WS_VISIBLE,
|
|
0, 0, 200, 100, GetDesktopWindow(),
|
|
NULL, GetModuleHandleW(NULL), NULL);
|
|
}
|
|
|
|
static WNDPROC syslink_oldproc;
|
|
|
|
static LRESULT WINAPI syslink_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static LONG defwndproc_counter = 0;
|
|
struct message msg = { 0 };
|
|
LRESULT ret;
|
|
|
|
msg.message = message;
|
|
msg.flags = sent|wparam|lparam;
|
|
if (defwndproc_counter) msg.flags |= defwinproc;
|
|
msg.wParam = wParam;
|
|
msg.lParam = lParam;
|
|
add_message(sequences, SYSLINK_SEQ_INDEX, &msg);
|
|
|
|
defwndproc_counter++;
|
|
ret = CallWindowProcW(syslink_oldproc, hwnd, message, wParam, lParam);
|
|
defwndproc_counter--;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static HWND create_syslink(DWORD style, HWND parent)
|
|
{
|
|
HWND hWndSysLink;
|
|
|
|
/* Only Unicode will do here */
|
|
hWndSysLink = CreateWindowExW(0, WC_LINK, L"Head <a href=\"link1\">Name1</a> Middle <a href=\"link2\">Name2</a> Tail",
|
|
style, 0, 0, 150, 50,
|
|
parent, NULL, GetModuleHandleW(NULL), NULL);
|
|
if (!hWndSysLink) return NULL;
|
|
|
|
if (GetWindowLongPtrW(hWndSysLink, GWLP_USERDATA))
|
|
/* On Windows XP SysLink takes GWLP_USERDATA for itself! */
|
|
trace("SysLink makes use of GWLP_USERDATA\n");
|
|
|
|
syslink_oldproc = (WNDPROC)SetWindowLongPtrW(hWndSysLink, GWLP_WNDPROC, (LONG_PTR)syslink_subclass_proc);
|
|
|
|
return hWndSysLink;
|
|
}
|
|
|
|
static void test_create_syslink(void)
|
|
{
|
|
HWND hWndSysLink;
|
|
LONG oldstyle;
|
|
LRESULT ret;
|
|
LITEM item;
|
|
|
|
/* Create an invisible SysLink control */
|
|
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
|
hWndSysLink = create_syslink(WS_CHILD | WS_TABSTOP, hWndParent);
|
|
ok(hWndSysLink != NULL, "Expected non NULL value (le %lu)\n", GetLastError());
|
|
flush_events();
|
|
ok_sequence(sequences, SYSLINK_SEQ_INDEX, create_syslink_wnd_seq, "create SysLink", FALSE);
|
|
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_syslink_wnd_seq, "create SysLink (parent)", TRUE);
|
|
|
|
/* Get first item */
|
|
item.mask = LIF_ITEMINDEX|LIF_ITEMID|LIF_URL;
|
|
item.iLink = 0;
|
|
ret = SendMessageW(hWndSysLink, LM_GETITEM, 0, (LPARAM)&item);
|
|
ok(ret == 1, "LM_GETITEM failed\n");
|
|
ok(!wcscmp(item.szUrl, L"link1"), "unexpected url %s\n", debugstr_w(item.szUrl));
|
|
|
|
/* Make the SysLink control visible */
|
|
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
|
oldstyle = GetWindowLongA(hWndSysLink, GWL_STYLE);
|
|
SetWindowLongA(hWndSysLink, GWL_STYLE, oldstyle | WS_VISIBLE);
|
|
RedrawWindow(hWndSysLink, NULL, NULL, RDW_INVALIDATE);
|
|
flush_events();
|
|
ok_sequence(sequences, SYSLINK_SEQ_INDEX, visible_syslink_wnd_seq, "visible SysLink", TRUE);
|
|
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_visible_syslink_wnd_seq, "visible SysLink (parent)", TRUE);
|
|
|
|
/* Change contents */
|
|
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
|
SetWindowTextW(hWndSysLink, L"Head <a href=\"link\">link</a> Tail");
|
|
flush_events();
|
|
ok_sequence(sequences, SYSLINK_SEQ_INDEX, settext_syslink_wnd_seq, "SetWindowText", FALSE);
|
|
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_settext_syslink_wnd_seq, "SetWindowText (parent)", FALSE);
|
|
|
|
/* Get first item */
|
|
item.mask = LIF_ITEMINDEX|LIF_ITEMID|LIF_URL;
|
|
item.iLink = 0;
|
|
ret = SendMessageW(hWndSysLink, LM_GETITEM, 0, (LPARAM)&item);
|
|
ok(ret == 1, "LM_GETITEM failed\n");
|
|
ok(!wcscmp(item.szUrl, L"link"), "unexpected url %s\n", debugstr_w(item.szUrl));
|
|
|
|
DestroyWindow(hWndSysLink);
|
|
}
|
|
|
|
static void test_LM_GETIDEALHEIGHT(void)
|
|
{
|
|
HWND hwnd;
|
|
LONG ret;
|
|
|
|
hwnd = create_syslink(WS_CHILD | WS_TABSTOP | WS_VISIBLE, hWndParent);
|
|
ok(hwnd != NULL, "Failed to create SysLink window.\n");
|
|
|
|
ret = SendMessageA(hwnd, LM_GETIDEALHEIGHT, 0, 0);
|
|
ok(ret > 0, "Unexpected ideal height, %ld.\n", ret);
|
|
|
|
DestroyWindow(hwnd);
|
|
}
|
|
|
|
static void test_LM_GETIDEALSIZE(void)
|
|
{
|
|
HWND hwnd;
|
|
LONG ret;
|
|
SIZE sz;
|
|
|
|
hwnd = create_syslink(WS_CHILD | WS_TABSTOP | WS_VISIBLE, hWndParent);
|
|
ok(hwnd != NULL, "Failed to create SysLink window.\n");
|
|
|
|
memset(&sz, 0, sizeof(sz));
|
|
ret = SendMessageA(hwnd, LM_GETIDEALSIZE, 0, (LPARAM)&sz);
|
|
ok(ret > 0, "Unexpected return value, %ld.\n", ret);
|
|
if (sz.cy == 0)
|
|
win_skip("LM_GETIDEALSIZE is not supported.\n");
|
|
else
|
|
{
|
|
ok(sz.cx > 5, "Unexpected ideal width, %ld.\n", sz.cx);
|
|
ok(sz.cy == ret, "Unexpected ideal height, %ld.\n", sz.cy);
|
|
}
|
|
|
|
DestroyWindow(hwnd);
|
|
}
|
|
|
|
static void test_link_id(void)
|
|
{
|
|
HWND hwnd;
|
|
|
|
hwnd = create_syslink(WS_CHILD | WS_TABSTOP | WS_VISIBLE, hWndParent);
|
|
ok(hwnd != NULL, "Failed to create SysLink window.\n");
|
|
|
|
/* test link1 at (50, 10) */
|
|
g_link_id = 0;
|
|
SendMessageA(hwnd, WM_LBUTTONDOWN, 1, MAKELPARAM(50, 10));
|
|
SendMessageA(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(50, 10));
|
|
ok(g_link_id == 0, "Got unexpected link id %d.\n", g_link_id);
|
|
|
|
/* test link2 at (25, 25) */
|
|
g_link_id = 0;
|
|
SendMessageA(hwnd, WM_LBUTTONDOWN, 1, MAKELPARAM(25, 25));
|
|
SendMessageA(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(25, 25));
|
|
ok(g_link_id == 1, "Got unexpected link id %d.\n", g_link_id);
|
|
|
|
DestroyWindow(hwnd);
|
|
}
|
|
|
|
static void wait_link_click(DWORD timeout)
|
|
{
|
|
DWORD start_time = GetTickCount();
|
|
DWORD time_waited;
|
|
|
|
if (g_link_id == -1)
|
|
flush_events();
|
|
|
|
while (g_link_id == -1 && (time_waited = GetTickCount() - start_time) < timeout)
|
|
{
|
|
MsgWaitForMultipleObjects(0, NULL, FALSE, timeout - time_waited, QS_ALLEVENTS);
|
|
flush_events();
|
|
}
|
|
}
|
|
|
|
static void test_msaa(void)
|
|
{
|
|
HWND hwnd, ret_hwnd;
|
|
HRESULT hr;
|
|
LRESULT lr;
|
|
IAccessible *acc;
|
|
VARIANT varChild, varResult;
|
|
BSTR name;
|
|
LONG left, top, width, height, hwnd_left, hwnd_top, count=0;
|
|
IDispatch *child;
|
|
IOleWindow *ole_window;
|
|
|
|
hwnd = create_syslink(WS_CHILD | WS_TABSTOP | WS_VISIBLE, hWndParent);
|
|
ok(hwnd != NULL, "Failed to create SysLink window.\n");
|
|
|
|
lr = SendMessageA(hwnd, WM_GETOBJECT, 0, OBJID_CLIENT);
|
|
ok(lr != 0, "No IAccessible object\n");
|
|
if (lr == 0)
|
|
{
|
|
DestroyWindow(hwnd);
|
|
return;
|
|
}
|
|
|
|
hr = ObjectFromLresult(lr, &IID_IAccessible, 0, (void**)&acc);
|
|
ok(hr == S_OK, "ObjectFromLresult failed, hr=%lx", hr);
|
|
|
|
VariantInit(&varChild);
|
|
VariantInit(&varResult);
|
|
|
|
V_VT(&varChild) = VT_I4;
|
|
V_I4(&varChild) = CHILDID_SELF;
|
|
|
|
hr = IAccessible_get_accRole(acc, varChild, &varResult);
|
|
ok(hr == S_OK, "accRole failed, hr=%lx\n", hr);
|
|
ok(V_VT(&varResult) == VT_I4, "accRole returned vt=%x\n", V_VT(&varResult));
|
|
ok(V_I4(&varResult) == ROLE_SYSTEM_CLIENT, "accRole returned %li\n", V_I4(&varResult));
|
|
|
|
VariantClear(&varResult);
|
|
hr = IAccessible_get_accState(acc, varChild, &varResult);
|
|
ok(hr == S_OK, "accState failed, hr=%lx\n", hr);
|
|
ok(V_VT(&varResult) == VT_I4, "accState returned vt=%x\n", V_VT(&varResult));
|
|
ok(V_I4(&varResult) == STATE_SYSTEM_FOCUSABLE, "accState returned %li\n", V_I4(&varResult));
|
|
|
|
hr = IAccessible_get_accName(acc, varChild, &name);
|
|
ok(hr == S_OK, "accName failed, hr=%lx\n", hr);
|
|
if (SUCCEEDED(hr)) {
|
|
ok(!!name && !wcscmp(name, L"Head Name1 Middle Name2 Tail"),
|
|
"unexpected name %s\n", debugstr_w(name));
|
|
SysFreeString(name);
|
|
}
|
|
|
|
hr = IAccessible_get_accDefaultAction(acc, varChild, &name);
|
|
ok(hr == S_FALSE, "accDefaultAction failed, hr=%lx\n", hr);
|
|
if (SUCCEEDED(hr))
|
|
ok(!name, "unexpected default action %s\n", debugstr_w(name));
|
|
|
|
hr = IAccessible_accDoDefaultAction(acc, varChild);
|
|
ok(hr == E_INVALIDARG, "accDoDefaultAction should fail, hr=%lx\n", hr);
|
|
|
|
hr = IAccessible_accLocation(acc, &left, &top, &width, &height, varChild);
|
|
ok(hr == S_OK, "accLocation failed, hr=%lx\n", hr);
|
|
hwnd_left = left;
|
|
hwnd_top = top;
|
|
|
|
hr = IAccessible_get_accChildCount(acc, &count);
|
|
ok(hr == S_OK, "accChildCount failed, hr=%lx\n", hr);
|
|
ok(count == 2, "accChildCount returned %li\n", count);
|
|
|
|
/* child 1 */
|
|
V_I4(&varChild) = 1;
|
|
hr = IAccessible_get_accChild(acc, varChild, &child);
|
|
ok(hr == S_FALSE, "accChild hr=%lx\n", hr);
|
|
ok(!child, "accChild returned IDispatch\n");
|
|
|
|
hr = IAccessible_get_accRole(acc, varChild, &varResult);
|
|
ok(hr == S_OK, "accRole failed, hr=%lx\n", hr);
|
|
ok(V_VT(&varResult) == VT_I4, "accRole returned vt=%x\n", V_VT(&varResult));
|
|
ok(V_I4(&varResult) == ROLE_SYSTEM_LINK, "accRole returned %li\n", V_I4(&varResult));
|
|
|
|
VariantClear(&varResult);
|
|
hr = IAccessible_get_accState(acc, varChild, &varResult);
|
|
ok(hr == S_OK, "accState failed, hr=%lx\n", hr);
|
|
ok(V_VT(&varResult) == VT_I4, "accState returned vt=%x\n", V_VT(&varResult));
|
|
ok(V_I4(&varResult) == (STATE_SYSTEM_FOCUSABLE|STATE_SYSTEM_LINKED), "accState returned %li\n", V_I4(&varResult));
|
|
|
|
hr = IAccessible_get_accName(acc, varChild, &name);
|
|
ok(hr == S_OK, "accName failed, hr=%lx\n", hr);
|
|
if (SUCCEEDED(hr)) {
|
|
ok(!!name && !wcscmp(name, L"Name1"),
|
|
"unexpected name %s\n", debugstr_w(name));
|
|
SysFreeString(name);
|
|
}
|
|
|
|
hr = IAccessible_get_accDefaultAction(acc, varChild, &name);
|
|
ok(hr == S_OK, "accDefaultAction failed, hr=%lx\n", hr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
|
|
{
|
|
skip("Non-English locale (test with hardcoded 'Click')\n");
|
|
}
|
|
else
|
|
{
|
|
ok(!!name && !wcscmp(name, L"Click"),
|
|
"unexpected name %s\n", debugstr_w(name));
|
|
}
|
|
SysFreeString(name);
|
|
}
|
|
|
|
g_link_id = -1;
|
|
hr = IAccessible_accDoDefaultAction(acc, varChild);
|
|
ok(hr == S_OK, "accDoDefaultAction failed, hr=%lx\n", hr);
|
|
wait_link_click(500);
|
|
ok(g_link_id == 0, "Got unexpected link id %d.\n", g_link_id);
|
|
|
|
g_link_id = -1;
|
|
hr = IAccessible_accLocation(acc, &left, &top, &width, &height, varChild);
|
|
ok(hr == S_OK, "accLocation failed, hr=%lx\n", hr);
|
|
SendMessageA(hwnd, WM_LBUTTONDOWN, 1, MAKELPARAM(left - hwnd_left + width / 2, top - hwnd_top + height / 2));
|
|
SendMessageA(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(left - hwnd_left + width / 2, top - hwnd_top + height / 2));
|
|
ok(g_link_id == 0, "Got unexpected link id %d.\n", g_link_id);
|
|
|
|
/* child 2 */
|
|
V_I4(&varChild) = 2;
|
|
hr = IAccessible_get_accChild(acc, varChild, &child);
|
|
ok(hr == S_FALSE, "accChild hr=%lx\n", hr);
|
|
ok(!child, "accChild returned IDispatch\n");
|
|
|
|
hr = IAccessible_get_accRole(acc, varChild, &varResult);
|
|
ok(hr == S_OK, "accRole failed, hr=%lx\n", hr);
|
|
ok(V_VT(&varResult) == VT_I4, "accRole returned vt=%x\n", V_VT(&varResult));
|
|
ok(V_I4(&varResult) == ROLE_SYSTEM_LINK, "accRole returned %li\n", V_I4(&varResult));
|
|
|
|
VariantClear(&varResult);
|
|
hr = IAccessible_get_accState(acc, varChild, &varResult);
|
|
ok(hr == S_OK, "accState failed, hr=%lx\n", hr);
|
|
ok(V_VT(&varResult) == VT_I4, "accState returned vt=%x\n", V_VT(&varResult));
|
|
ok(V_I4(&varResult) == (STATE_SYSTEM_FOCUSABLE|STATE_SYSTEM_LINKED), "accState returned %li\n", V_I4(&varResult));
|
|
|
|
hr = IAccessible_get_accName(acc, varChild, &name);
|
|
ok(hr == S_OK, "accName failed, hr=%lx\n", hr);
|
|
if (SUCCEEDED(hr)) {
|
|
ok(!!name && !wcscmp(name, L"Name2"),
|
|
"unexpected name %s\n", debugstr_w(name));
|
|
SysFreeString(name);
|
|
}
|
|
|
|
hr = IAccessible_get_accDefaultAction(acc, varChild, &name);
|
|
ok(hr == S_OK, "accDefaultAction failed, hr=%lx\n", hr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (PRIMARYLANGID(GetSystemDefaultLangID()) != LANG_ENGLISH)
|
|
{
|
|
skip("Non-English locale (test with hardcoded 'Click')\n");
|
|
}
|
|
else
|
|
{
|
|
ok(!!name && !wcscmp(name, L"Click"),
|
|
"unexpected name %s\n", debugstr_w(name));
|
|
}
|
|
SysFreeString(name);
|
|
}
|
|
|
|
g_link_id = -1;
|
|
hr = IAccessible_accDoDefaultAction(acc, varChild);
|
|
ok(hr == S_OK, "accDoDefaultAction failed, hr=%lx\n", hr);
|
|
wait_link_click(500);
|
|
ok(g_link_id == 1, "Got unexpected link id %d.\n", g_link_id);
|
|
|
|
g_link_id = -1;
|
|
hr = IAccessible_accLocation(acc, &left, &top, &width, &height, varChild);
|
|
ok(hr == S_OK, "accLocation failed, hr=%lx\n", hr);
|
|
SendMessageA(hwnd, WM_LBUTTONDOWN, 1, MAKELPARAM(left - hwnd_left + width / 2, top - hwnd_top + height / 2));
|
|
SendMessageA(hwnd, WM_LBUTTONUP, 0, MAKELPARAM(left - hwnd_left + width / 2, top - hwnd_top + height / 2));
|
|
ok(g_link_id == 1, "Got unexpected link id %d.\n", g_link_id);
|
|
|
|
hr = IAccessible_QueryInterface(acc, &IID_IOleWindow, (void**)&ole_window);
|
|
ok(hr == S_OK, "QueryInterface failed, hr=%lx\n", hr);
|
|
|
|
if (SUCCEEDED(hr)) {
|
|
hr = IOleWindow_GetWindow(ole_window, &ret_hwnd);
|
|
ok(hr == S_OK, "GetWindow failed, hr=%lx\n", hr);
|
|
ok(ret_hwnd == hwnd, "GetWindow returned wrong hwnd\n");
|
|
|
|
IOleWindow_Release(ole_window);
|
|
}
|
|
|
|
IAccessible_Release(acc);
|
|
|
|
DestroyWindow(hwnd);
|
|
}
|
|
|
|
START_TEST(syslink)
|
|
{
|
|
ULONG_PTR ctx_cookie;
|
|
HMODULE hComctl32;
|
|
POINT orig_pos;
|
|
HANDLE hCtx;
|
|
|
|
if (!load_v6_module(&ctx_cookie, &hCtx))
|
|
return;
|
|
|
|
/* LoadLibrary is needed. This file has no reference to functions in comctl32 */
|
|
hComctl32 = LoadLibraryA("comctl32.dll");
|
|
ok(hComctl32 != NULL, "Failed to load comctl32.dll.\n");
|
|
|
|
/* Move the cursor off the parent window */
|
|
GetCursorPos(&orig_pos);
|
|
SetCursorPos(400, 400);
|
|
|
|
init_msg_sequences(sequences, NUM_MSG_SEQUENCE);
|
|
|
|
init_winevent_hook();
|
|
|
|
/* Create parent window */
|
|
hWndParent = create_parent_window();
|
|
ok(hWndParent != NULL, "Failed to create parent Window!\n");
|
|
flush_events();
|
|
|
|
test_create_syslink();
|
|
test_LM_GETIDEALHEIGHT();
|
|
test_LM_GETIDEALSIZE();
|
|
test_link_id();
|
|
test_msaa();
|
|
|
|
uninit_winevent_hook();
|
|
|
|
DestroyWindow(hWndParent);
|
|
unload_v6_module(ctx_cookie, hCtx);
|
|
SetCursorPos(orig_pos.x, orig_pos.y);
|
|
}
|