4 * Copyright 2008 Nikolay Sivov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/test.h"
29 #define DEFINE_EXPECT(func) \
30 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
32 #define SET_EXPECT(func) \
33 do { called_ ## func = FALSE; expect_ ## func = TRUE; } while(0)
35 #define CHECK_EXPECT2(func) \
37 ok(expect_ ##func, "unexpected call " #func "\n"); \
38 called_ ## func = TRUE; \
41 #define CHECK_EXPECT(func) \
43 CHECK_EXPECT2(func); \
44 expect_ ## func = FALSE; \
47 #define CHECK_CALLED(func) \
49 ok(called_ ## func, "expected " #func "\n"); \
50 expect_ ## func = called_ ## func = FALSE; \
53 DEFINE_EXPECT(Accessible_QI_IEnumVARIANT
);
54 DEFINE_EXPECT(Accessible_get_accChildCount
);
55 DEFINE_EXPECT(Accessible_get_accChild
);
57 static HANDLE (WINAPI
*pGetProcessHandleFromHwnd
)(HWND
);
59 static BOOL
init(void)
61 HMODULE oleacc
= GetModuleHandleA("oleacc.dll");
63 pGetProcessHandleFromHwnd
= (void*)GetProcAddress(oleacc
, "GetProcessHandleFromHwnd");
64 if(!pGetProcessHandleFromHwnd
) {
65 win_skip("GetProcessHandleFromHwnd not available\n");
72 static HRESULT WINAPI
Accessible_QueryInterface(
73 IAccessible
*iface
, REFIID riid
, void **ppvObject
)
75 if(IsEqualIID(riid
, &IID_IEnumVARIANT
)) {
76 CHECK_EXPECT(Accessible_QI_IEnumVARIANT
);
80 ok(0, "unexpected QI call: %s\n", wine_dbgstr_guid(riid
));
84 static ULONG WINAPI
Accessible_AddRef(IAccessible
*iface
)
89 static ULONG WINAPI
Accessible_Release(IAccessible
*iface
)
94 static HRESULT WINAPI
Accessible_GetTypeInfoCount(
95 IAccessible
*iface
, UINT
*pctinfo
)
97 ok(0, "unexpected call\n");
101 static HRESULT WINAPI
Accessible_GetTypeInfo(IAccessible
*iface
,
102 UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
104 ok(0, "unexpected call\n");
108 static HRESULT WINAPI
Accessible_GetIDsOfNames(IAccessible
*iface
, REFIID riid
,
109 LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
111 ok(0, "unexpected call\n");
115 static HRESULT WINAPI
Accessible_Invoke(IAccessible
*iface
, DISPID dispIdMember
,
116 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
117 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
119 ok(0, "unexpected call\n");
123 static HRESULT WINAPI
Accessible_get_accParent(
124 IAccessible
*iface
, IDispatch
**ppdispParent
)
126 ok(0, "unexpected call\n");
130 static HRESULT WINAPI
Accessible_get_accChildCount(
131 IAccessible
*iface
, LONG
*pcountChildren
)
133 CHECK_EXPECT(Accessible_get_accChildCount
);
138 static HRESULT WINAPI
Accessible_get_accChild(IAccessible
*iface
,
139 VARIANT varChildID
, IDispatch
**ppdispChild
)
141 CHECK_EXPECT(Accessible_get_accChild
);
142 ok(V_VT(&varChildID
) == VT_I4
, "V_VT(&varChildID) = %d\n", V_VT(&varChildID
));
143 ok(V_I4(&varChildID
) == 1, "V_I4(&varChildID) = %d\n", V_I4(&varChildID
));
149 static HRESULT WINAPI
Accessible_get_accName(IAccessible
*iface
,
150 VARIANT varID
, BSTR
*pszName
)
152 ok(0, "unexpected call\n");
156 static HRESULT WINAPI
Accessible_get_accValue(IAccessible
*iface
,
157 VARIANT varID
, BSTR
*pszValue
)
159 ok(0, "unexpected call\n");
163 static HRESULT WINAPI
Accessible_get_accDescription(IAccessible
*iface
,
164 VARIANT varID
, BSTR
*pszDescription
)
166 ok(0, "unexpected call\n");
170 static HRESULT WINAPI
Accessible_get_accRole(IAccessible
*iface
,
171 VARIANT varID
, VARIANT
*pvarRole
)
173 ok(0, "unexpected call\n");
177 static HRESULT WINAPI
Accessible_get_accState(IAccessible
*iface
,
178 VARIANT varID
, VARIANT
*pvarState
)
180 ok(0, "unexpected call\n");
184 static HRESULT WINAPI
Accessible_get_accHelp(IAccessible
*iface
,
185 VARIANT varID
, BSTR
*pszHelp
)
187 ok(0, "unexpected call\n");
191 static HRESULT WINAPI
Accessible_get_accHelpTopic(IAccessible
*iface
,
192 BSTR
*pszHelpFile
, VARIANT varID
, LONG
*pidTopic
)
194 ok(0, "unexpected call\n");
198 static HRESULT WINAPI
Accessible_get_accKeyboardShortcut(IAccessible
*iface
,
199 VARIANT varID
, BSTR
*pszKeyboardShortcut
)
201 ok(0, "unexpected call\n");
205 static HRESULT WINAPI
Accessible_get_accFocus(IAccessible
*iface
, VARIANT
*pvarID
)
207 ok(0, "unexpected call\n");
211 static HRESULT WINAPI
Accessible_get_accSelection(
212 IAccessible
*iface
, VARIANT
*pvarID
)
214 ok(0, "unexpected call\n");
218 static HRESULT WINAPI
Accessible_get_accDefaultAction(IAccessible
*iface
,
219 VARIANT varID
, BSTR
*pszDefaultAction
)
221 ok(0, "unexpected call\n");
225 static HRESULT WINAPI
Accessible_accSelect(IAccessible
*iface
,
226 LONG flagsSelect
, VARIANT varID
)
228 ok(0, "unexpected call\n");
232 static HRESULT WINAPI
Accessible_accLocation(IAccessible
*iface
, LONG
*pxLeft
,
233 LONG
*pyTop
, LONG
*pcxWidth
, LONG
*pcyHeight
, VARIANT varID
)
235 ok(0, "unexpected call\n");
239 static HRESULT WINAPI
Accessible_accNavigate(IAccessible
*iface
,
240 LONG navDir
, VARIANT varStart
, VARIANT
*pvarEnd
)
242 ok(0, "unexpected call\n");
246 static HRESULT WINAPI
Accessible_accHitTest(IAccessible
*iface
,
247 LONG xLeft
, LONG yTop
, VARIANT
*pvarID
)
249 ok(0, "unexpected call\n");
253 static HRESULT WINAPI
Accessible_accDoDefaultAction(
254 IAccessible
*iface
, VARIANT varID
)
256 ok(0, "unexpected call\n");
260 static HRESULT WINAPI
Accessible_put_accName(IAccessible
*iface
,
261 VARIANT varID
, BSTR pszName
)
263 ok(0, "unexpected call\n");
267 static HRESULT WINAPI
Accessible_put_accValue(IAccessible
*iface
,
268 VARIANT varID
, BSTR pszValue
)
270 ok(0, "unexpected call\n");
274 static IAccessibleVtbl AccessibleVtbl
= {
275 Accessible_QueryInterface
,
278 Accessible_GetTypeInfoCount
,
279 Accessible_GetTypeInfo
,
280 Accessible_GetIDsOfNames
,
282 Accessible_get_accParent
,
283 Accessible_get_accChildCount
,
284 Accessible_get_accChild
,
285 Accessible_get_accName
,
286 Accessible_get_accValue
,
287 Accessible_get_accDescription
,
288 Accessible_get_accRole
,
289 Accessible_get_accState
,
290 Accessible_get_accHelp
,
291 Accessible_get_accHelpTopic
,
292 Accessible_get_accKeyboardShortcut
,
293 Accessible_get_accFocus
,
294 Accessible_get_accSelection
,
295 Accessible_get_accDefaultAction
,
296 Accessible_accSelect
,
297 Accessible_accLocation
,
298 Accessible_accNavigate
,
299 Accessible_accHitTest
,
300 Accessible_accDoDefaultAction
,
301 Accessible_put_accName
,
302 Accessible_put_accValue
305 static IAccessible Accessible
= {&AccessibleVtbl
};
307 static void test_getroletext(void)
311 WCHAR bufW
[2], *buffW
;
313 /* wrong role number */
314 ret
= GetRoleTextA(-1, NULL
, 0);
315 ok(ret
== 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret
);
317 ret
= GetRoleTextA(-1, buf
, 2);
318 ok(ret
== 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret
);
319 ok(buf
[0] == 0, "GetRoleTextA doesn't return NULL char on wrong role number\n");
321 ret
= GetRoleTextA(-1, buf
, 0);
322 ok(ret
== 0, "GetRoleTextA doesn't return zero on wrong role number, got %d\n", ret
);
323 ok(buf
[0] == '*', "GetRoleTextA modified buffer on wrong role number\n");
325 ret
= GetRoleTextW(-1, NULL
, 0);
326 ok(ret
== 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret
);
328 ret
= GetRoleTextW(-1, bufW
, 2);
329 ok(ret
== 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret
);
330 ok(bufW
[0] == '\0', "GetRoleTextW doesn't return NULL char on wrong role number\n");
332 ret
= GetRoleTextW(-1, bufW
, 0);
333 ok(ret
== 0, "GetRoleTextW doesn't return zero on wrong role number, got %d\n", ret
);
335 /* zero role number - not documented */
336 ret
= GetRoleTextA(0, NULL
, 0);
337 ok(ret
> 0, "GetRoleTextA doesn't return (>0) for zero role number, got %d\n", ret
);
338 ret
= GetRoleTextW(0, NULL
, 0);
339 ok(ret
> 0, "GetRoleTextW doesn't return (>0) for zero role number, got %d\n", ret
);
341 /* NULL buffer, return length */
342 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, NULL
, 0);
343 ok(ret
> 0, "GetRoleTextA doesn't return length on NULL buffer, got %d\n", ret
);
344 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, NULL
, 1);
345 ok(ret
> 0, "GetRoleTextA doesn't return length on NULL buffer, got %d\n", ret
);
346 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, NULL
, 0);
347 ok(ret
> 0, "GetRoleTextW doesn't return length on NULL buffer, got %d\n", ret
);
348 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, NULL
, 1);
349 ok(ret
> 0, "GetRoleTextW doesn't return length on NULL buffer, got %d\n", ret
);
351 /* use a smaller buffer */
353 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, buf
, 0);
354 ok(!ret
, "GetRoleTextA doesn't return 0, got %d\n", ret
);
355 ok(buf
[0] == '*', "GetRoleTextA modified buffer\n");
357 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, (WCHAR
*)&buffW
, 0);
358 ok(ret
, "GetRoleTextW doesn't return length\n");
359 ok(buffW
!= NULL
, "GetRoleTextW doesn't modify buffer\n");
361 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, buf
, 1);
362 ok(ret
== 0, "GetRoleTextA returned wrong length\n");
363 ok(buf
[0] == '\0', "GetRoleTextA returned not zero-length buffer\n");
365 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, buf
, 2);
366 ok(!ret
, "GetRoleTextA returned wrong length, got %d, expected 0\n", ret
);
367 ok(!buf
[0] || broken(buf
[0]!='*') /* WinXP */,
368 "GetRoleTextA returned not zero-length buffer : (%c)\n", buf
[0]);
371 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, bufW
, 1);
372 ok(ret
== 0, "GetRoleTextW returned wrong length, got %d, expected 1\n", ret
);
373 ok(bufW
[0] == '\0', "GetRoleTextW returned not zero-length buffer\n");
375 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, bufW
, 2);
376 ok(ret
== 1, "GetRoleTextW returned wrong length, got %d, expected 1\n", ret
);
377 ok(bufW
[1] == '\0', "GetRoleTextW returned not zero-length buffer\n");
379 /* use bigger buffer */
380 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, NULL
, 0);
381 buff
= HeapAlloc(GetProcessHeap(), 0, 2*ret
);
383 ret
= GetRoleTextA(ROLE_SYSTEM_TITLEBAR
, buff
, 2*ret
);
384 ok(buff
[2*ret
-1] == '*', "GetRoleTextA shouldn't modify this part of buffer\n");
385 HeapFree(GetProcessHeap(), 0, buff
);
387 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, NULL
, 0);
388 buffW
= HeapAlloc(GetProcessHeap(), 0, 2*ret
*sizeof(WCHAR
));
389 buffW
[2*ret
-1] = '*';
390 ret
= GetRoleTextW(ROLE_SYSTEM_TITLEBAR
, buffW
, 2*ret
);
391 ok(buffW
[2*ret
-1] == '*', "GetRoleTextW shouldn't modify this part of buffer\n");
392 HeapFree(GetProcessHeap(), 0, buffW
);
394 /* check returned length for all roles */
395 for(role
= 0; role
<= ROLE_SYSTEM_OUTLINEBUTTON
; role
++){
399 /* NT4 and W2K don't clear the buffer on a nonexistent role in the A-call */
400 memset(buff2
, 0, sizeof(buff2
));
402 ret
= GetRoleTextA(role
, NULL
, 0);
403 ok(ret
> 0, "Expected the role to be present\n");
405 GetRoleTextA(role
, buff2
, sizeof(buff2
));
406 ok(ret
== lstrlenA(buff2
),
407 "GetRoleTextA: returned length doesn't match returned buffer for role %d\n", role
);
409 /* Win98 and WinMe don't clear the buffer on a nonexistent role in the W-call */
410 memset(buff2W
, 0, sizeof(buff2W
));
412 ret
= GetRoleTextW(role
, NULL
, 0);
413 GetRoleTextW(role
, buff2W
, ARRAY_SIZE(buff2W
));
414 ok(ret
== lstrlenW(buff2W
),
415 "GetRoleTextW: returned length doesn't match returned buffer for role %d\n", role
);
419 static void test_GetStateText(void)
421 WCHAR buf
[1024], buf2
[1024];
427 ret2
= GetStateTextW(0, NULL
, 1024);
428 ok(ret2
, "GetStateText failed\n");
431 ret
= GetStateTextW(0, (WCHAR
*)&ptr
, 0);
432 ok(ret
== ret2
, "got %d, expected %d\n", ret
, ret2
);
433 ok(ptr
!= NULL
, "ptr was not changed\n");
435 ret
= GetStateTextW(0, buf
, 1024);
436 ok(ret
== ret2
, "got %d, expected %d\n", ret
, ret2
);
437 ok(!memcmp(buf
, ptr
, ret
*sizeof(WCHAR
)), "got %s, expected %s\n",
438 wine_dbgstr_wn(buf
, ret
), wine_dbgstr_wn(ptr
, ret
));
440 ret
= GetStateTextW(0, buf
, 1);
441 ok(!ret
, "got %d, expected 0\n", ret
);
442 ok(!buf
[0], "buf[0] = '%c'\n", buf
[0]);
444 for(i
=0; i
<31; i
++) {
445 ret
= GetStateTextW(1<<i
, buf
, 1024);
446 ok(ret
, "%d) GetStateText failed\n", i
);
448 ret
= GetStateTextW(1u<<31, buf
, 1024);
449 ok(!ret
, "31) GetStateText succeeded: %d\n", ret
);
451 ret
= GetStateTextW(2, buf
, 1024);
452 ok(ret
, "GetStateText failed\n");
453 ret2
= GetStateTextW(3, buf2
, 1024);
454 ok(ret2
, "GetStateText failed\n");
455 ok(ret
== ret2
, "got %d, expected %d\n", ret2
, ret
);
456 ok(!memcmp(buf
, buf2
, ret
*sizeof(WCHAR
)),
457 "GetStateText(2,...) returned different data than GetStateText(3,...)\n");
459 ret2
= GetStateTextA(0, NULL
, 1024);
460 ok(ret2
, "GetStateText failed\n");
463 ret
= GetStateTextA(0, (CHAR
*)&ptr
, 0);
464 ok(!ret
, "got %d\n", ret
);
465 ok(ptr
== NULL
, "ptr was changed\n");
467 ret
= GetStateTextA(0, NULL
, 0);
468 ok(ret
== ret2
, "got %d, expected %d\n", ret
, ret2
);
470 ret
= GetStateTextA(0, bufa
, 1024);
471 ok(ret
== ret2
, "got %d, expected %d\n", ret
, ret2
);
473 ret
= GetStateTextA(0, bufa
, 1);
474 ok(!ret
, "got %d, expected 0\n", ret
);
475 ok(!bufa
[0], "bufa[0] = '%c'\n", bufa
[0]);
477 for(i
=0; i
<31; i
++) {
478 ret
= GetStateTextA(1<<i
, bufa
, 1024);
479 ok(ret
, "%d) GetStateText failed\n", i
);
481 ret
= GetStateTextA(1u<<31, bufa
, 1024);
482 ok(!ret
, "31) GetStateText succeeded: %d\n", ret
);
485 static int Object_ref
= 1;
486 static HRESULT WINAPI
Object_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ppv
)
488 if(IsEqualIID(riid
, &IID_IUnknown
)) {
490 IUnknown_AddRef(iface
);
493 return E_NOINTERFACE
;
496 static ULONG WINAPI
Object_AddRef(IUnknown
*iface
)
498 return InterlockedIncrement(&Object_ref
);
501 static ULONG WINAPI
Object_Release(IUnknown
*iface
)
503 return InterlockedDecrement(&Object_ref
);
506 static IUnknownVtbl ObjectVtbl
= {
507 Object_QueryInterface
,
512 static IUnknown Object
= {&ObjectVtbl
};
514 static void test_LresultFromObject(const char *name
)
516 PROCESS_INFORMATION proc
;
517 STARTUPINFOA startup
;
518 char cmdline
[MAX_PATH
];
523 lres
= LresultFromObject(NULL
, 0, 0);
524 ok(lres
== E_INVALIDARG
, "got %lx\n", lres
);
526 hres
= ObjectFromLresult(0, &IID_IUnknown
, 0, (void**)&unk
);
527 ok(hres
== E_FAIL
, "got %x\n", hres
);
528 hres
= ObjectFromLresult(0x10000, &IID_IUnknown
, 0, (void**)&unk
);
529 ok(hres
== E_FAIL
, "got %x\n", hres
);
531 ok(Object_ref
== 1, "Object_ref = %d\n", Object_ref
);
532 lres
= LresultFromObject(&IID_IUnknown
, 0, &Object
);
533 ok(SUCCEEDED(lres
), "got %lx\n", lres
);
534 ok(Object_ref
> 1, "Object_ref = %d\n", Object_ref
);
536 hres
= ObjectFromLresult(lres
, &IID_IUnknown
, 0, (void**)&unk
);
537 ok(hres
== S_OK
, "hres = %x\n", hres
);
538 ok(unk
== &Object
, "unk != &Object\n");
539 IUnknown_Release(unk
);
540 ok(Object_ref
== 1, "Object_ref = %d\n", Object_ref
);
542 lres
= LresultFromObject(&IID_IUnknown
, 0, &Object
);
543 ok(SUCCEEDED(lres
), "got %lx\n", lres
);
544 ok(Object_ref
> 1, "Object_ref = %d\n", Object_ref
);
546 sprintf(cmdline
, "\"%s\" main ObjectFromLresult %s", name
, wine_dbgstr_longlong(lres
));
547 memset(&startup
, 0, sizeof(startup
));
548 startup
.cb
= sizeof(startup
);
549 CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &startup
, &proc
);
550 wait_child_process(proc
.hProcess
);
551 ok(Object_ref
== 1, "Object_ref = %d\n", Object_ref
);
554 static LRESULT WINAPI
test_window_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
558 if(lparam
== OBJID_QUERYCLASSNAMEIDX
) {
559 ok(!wparam
, "wparam = %lx\n", wparam
);
563 ok(wparam
==0xffffffff, "wparam = %lx\n", wparam
);
564 if(lparam
== (DWORD
)OBJID_CURSOR
)
566 if(lparam
== (DWORD
)OBJID_CLIENT
)
567 return LresultFromObject(&IID_IUnknown
, wparam
, &Object
);
568 if(lparam
== (DWORD
)OBJID_WINDOW
)
571 ok(0, "unexpected (%ld)\n", lparam
);
575 return DefWindowProcA(hwnd
, msg
, wparam
, lparam
);
578 static BOOL
register_window_class(void)
582 memset(&cls
, 0, sizeof(cls
));
583 cls
.lpfnWndProc
= test_window_proc
;
584 cls
.lpszClassName
= "oleacc_test";
585 cls
.hInstance
= GetModuleHandleA(NULL
);
587 return RegisterClassA(&cls
);
590 static void unregister_window_class(void)
592 UnregisterClassA("oleacc_test", NULL
);
595 static void test_AccessibleObjectFromWindow(void)
601 hr
= AccessibleObjectFromWindow(NULL
, OBJID_CURSOR
, &IID_IUnknown
, NULL
);
602 ok(hr
== E_INVALIDARG
, "got %x\n", hr
);
604 hr
= AccessibleObjectFromWindow(NULL
, OBJID_CURSOR
, &IID_IUnknown
, (void**)&unk
);
605 todo_wine
ok(hr
== S_OK
, "got %x\n", hr
);
606 if(hr
== S_OK
) IUnknown_Release(unk
);
608 hwnd
= CreateWindowA("oleacc_test", "test", WS_OVERLAPPEDWINDOW
,
609 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
610 ok(hwnd
!= NULL
, "CreateWindow failed\n");
612 hr
= AccessibleObjectFromWindow(hwnd
, OBJID_CURSOR
, &IID_IUnknown
, (void**)&unk
);
613 ok(hr
== E_UNEXPECTED
, "got %x\n", hr
);
615 ok(Object_ref
== 1, "Object_ref = %d\n", Object_ref
);
616 hr
= AccessibleObjectFromWindow(hwnd
, OBJID_CLIENT
, &IID_IUnknown
, (void**)&unk
);
617 ok(hr
== S_OK
, "got %x\n", hr
);
618 ok(Object_ref
== 2, "Object_ref = %d\n", Object_ref
);
619 IUnknown_Release(unk
);
624 static void test_GetProcessHandleFromHwnd(void)
629 proc
= pGetProcessHandleFromHwnd(NULL
);
630 ok(!proc
, "proc = %p\n", proc
);
632 hwnd
= CreateWindowA("static", "", 0, 0, 0, 0, 0, NULL
, NULL
, NULL
, NULL
);
633 ok(hwnd
!= NULL
, "CreateWindow failed\n");
635 proc
= pGetProcessHandleFromHwnd(hwnd
);
636 ok(proc
!= NULL
, "proc == NULL\n");
642 static void test_AccessibleChildren(IAccessible
*acc
)
649 hr
= AccessibleChildren(NULL
, 0, 0, children
, &count
);
650 ok(hr
== E_INVALIDARG
, "AccessibleChildren returned %x\n", hr
);
651 ok(count
== -1, "count = %d\n", count
);
652 hr
= AccessibleChildren(acc
, 0, 0, NULL
, &count
);
653 ok(hr
== E_INVALIDARG
, "AccessibleChildren returned %x\n", hr
);
654 ok(count
== -1, "count = %d\n", count
);
655 hr
= AccessibleChildren(acc
, 0, 0, children
, NULL
);
656 ok(hr
== E_INVALIDARG
, "AccessibleChildren returned %x\n", hr
);
658 if(acc
== &Accessible
) {
659 SET_EXPECT(Accessible_QI_IEnumVARIANT
);
660 SET_EXPECT(Accessible_get_accChildCount
);
662 hr
= AccessibleChildren(acc
, 0, 0, children
, &count
);
663 ok(hr
== S_OK
, "AccessibleChildren returned %x\n", hr
);
664 if(acc
== &Accessible
) {
665 CHECK_CALLED(Accessible_QI_IEnumVARIANT
);
666 CHECK_CALLED(Accessible_get_accChildCount
);
668 ok(!count
, "count = %d\n", count
);
670 if(acc
== &Accessible
) {
671 SET_EXPECT(Accessible_QI_IEnumVARIANT
);
672 SET_EXPECT(Accessible_get_accChildCount
);
674 hr
= AccessibleChildren(acc
, 5, 0, children
, &count
);
675 ok(hr
== S_OK
, "AccessibleChildren returned %x\n", hr
);
676 if(acc
== &Accessible
) {
677 CHECK_CALLED(Accessible_QI_IEnumVARIANT
);
678 CHECK_CALLED(Accessible_get_accChildCount
);
680 ok(!count
, "count = %d\n", count
);
682 memset(children
, 0xfe, sizeof(children
));
683 V_VT(children
) = VT_DISPATCH
;
684 if(acc
== &Accessible
) {
685 SET_EXPECT(Accessible_QI_IEnumVARIANT
);
686 SET_EXPECT(Accessible_get_accChildCount
);
687 SET_EXPECT(Accessible_get_accChild
);
689 hr
= AccessibleChildren(acc
, 0, 1, children
, &count
);
690 ok(hr
== S_OK
, "AccessibleChildren returned %x\n", hr
);
691 if(acc
== &Accessible
) {
692 CHECK_CALLED(Accessible_QI_IEnumVARIANT
);
693 CHECK_CALLED(Accessible_get_accChildCount
);
694 CHECK_CALLED(Accessible_get_accChild
);
696 ok(V_VT(children
) == VT_I4
, "V_VT(children) = %d\n", V_VT(children
));
697 ok(V_I4(children
) == 1, "V_I4(children) = %d\n", V_I4(children
));
699 ok(V_VT(children
) == VT_DISPATCH
, "V_VT(children) = %d\n", V_VT(children
));
700 IDispatch_Release(V_DISPATCH(children
));
702 ok(count
== 1, "count = %d\n", count
);
704 if(acc
== &Accessible
) {
705 SET_EXPECT(Accessible_QI_IEnumVARIANT
);
706 SET_EXPECT(Accessible_get_accChildCount
);
707 SET_EXPECT(Accessible_get_accChild
);
709 hr
= AccessibleChildren(acc
, 0, 3, children
, &count
);
710 ok(hr
== S_FALSE
, "AccessibleChildren returned %x\n", hr
);
711 if(acc
== &Accessible
) {
712 CHECK_CALLED(Accessible_QI_IEnumVARIANT
);
713 CHECK_CALLED(Accessible_get_accChildCount
);
714 CHECK_CALLED(Accessible_get_accChild
);
716 ok(V_VT(children
) == VT_I4
, "V_VT(children) = %d\n", V_VT(children
));
717 ok(V_I4(children
) == 1, "V_I4(children) = %d\n", V_I4(children
));
719 ok(count
== 1, "count = %d\n", count
);
720 ok(V_VT(children
+1) == VT_EMPTY
, "V_VT(children+1) = %d\n", V_VT(children
+1));
722 ok(V_VT(children
) == VT_DISPATCH
, "V_VT(children) = %d\n", V_VT(children
));
723 IDispatch_Release(V_DISPATCH(children
));
725 ok(count
== 2, "count = %d\n", count
);
726 ok(V_VT(children
+1) == VT_DISPATCH
, "V_VT(children+1) = %d\n", V_VT(children
+1));
727 IDispatch_Release(V_DISPATCH(children
+1));
729 ok(V_VT(children
+2) == VT_EMPTY
, "V_VT(children+2) = %d\n", V_VT(children
+2));
732 static void test_default_client_accessible_object(void)
738 HWND chld
, btn
, hwnd
, hwnd2
;
744 LONG l
, left
, top
, width
, height
;
747 hwnd
= CreateWindowA("oleacc_test", "wnd &t &junk", WS_OVERLAPPEDWINDOW
,
748 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
749 ok(hwnd
!= NULL
, "CreateWindow failed\n");
750 chld
= CreateWindowA("static", "static &t &junk", WS_CHILD
| WS_VISIBLE
,
751 0, 0, 50, 50, hwnd
, NULL
, NULL
, NULL
);
752 ok(chld
!= NULL
, "CreateWindow failed\n");
753 btn
= CreateWindowA("BUTTON", "btn &t &junk", WS_TABSTOP
| WS_VISIBLE
| WS_CHILD
| BS_DEFPUSHBUTTON
,
754 50, 0, 50, 50, hwnd
, NULL
, NULL
, NULL
);
755 ok(btn
!= NULL
, "CreateWindow failed\n");
757 hr
= CreateStdAccessibleObject(NULL
, OBJID_CLIENT
, &IID_IAccessible
, (void**)&acc
);
758 ok(hr
== E_FAIL
, "got %x\n", hr
);
761 /* Test the static message */
762 hr
= CreateStdAccessibleObject(chld
, OBJID_CLIENT
, &IID_IAccessible
, (void**)&acc
);
763 ok(hr
== S_OK
, "got %x\n", hr
);
766 V_I4(&vid
) = CHILDID_SELF
;
767 hr
= IAccessible_get_accName(acc
, vid
, &str
);
768 ok(hr
== S_OK
, "got %x\n", hr
);
769 ok(!lstrcmpW(str
, L
"static t &junk"), "name = %s\n", wine_dbgstr_w(str
));
772 hr
= IAccessible_get_accKeyboardShortcut(acc
, vid
, &str
);
773 ok(hr
== S_OK
, "got %x\n", hr
);
774 ok(!lstrcmpW(str
, L
"Alt+t"), "str = %s\n", wine_dbgstr_w(str
));
777 IAccessible_Release(acc
);
780 /* Test the button */
781 hr
= CreateStdAccessibleObject(btn
, OBJID_CLIENT
, &IID_IAccessible
, (void**)&acc
);
782 ok(hr
== S_OK
, "got %x\n", hr
);
785 V_I4(&vid
) = CHILDID_SELF
;
786 hr
= IAccessible_get_accName(acc
, vid
, &str
);
787 ok(hr
== S_OK
, "got %x\n", hr
);
788 ok(!lstrcmpW(str
, L
"btn t &junk"), "name = %s\n", wine_dbgstr_w(str
));
791 hr
= IAccessible_get_accKeyboardShortcut(acc
, vid
, &str
);
792 ok(hr
== S_OK
, "got %x\n", hr
);
793 ok(!lstrcmpW(str
, L
"Alt+t"), "str = %s\n", wine_dbgstr_w(str
));
796 IAccessible_Release(acc
);
799 /* Now we can test and destroy the top-level window */
800 hr
= CreateStdAccessibleObject(hwnd
, OBJID_CLIENT
, &IID_IAccessible
, (void**)&acc
);
801 ok(hr
== S_OK
, "got %x\n", hr
);
803 hr
= IAccessible_QueryInterface(acc
, &IID_IOleWindow
, (void**)&ow
);
804 ok(hr
== S_OK
, "got %x\n", hr
);
805 hr
= IOleWindow_GetWindow(ow
, &hwnd2
);
806 ok(hr
== S_OK
, "got %x\n", hr
);
807 ok(hwnd
== hwnd2
, "hwnd2 = %p, expected %p\n", hwnd2
, hwnd
);
808 hr
= WindowFromAccessibleObject(acc
, &hwnd2
);
809 ok(hr
== S_OK
, "got %x\n", hr
);
810 ok(hwnd
== hwnd2
, "hwnd2 = %p, expected %p\n", hwnd2
, hwnd
);
811 IOleWindow_Release(ow
);
813 hr
= IAccessible_get_accChildCount(acc
, &l
);
814 ok(hr
== S_OK
, "got %x\n", hr
);
815 ok(l
== 2, "l = %d\n", l
);
818 V_I4(&vid
) = CHILDID_SELF
;
819 disp
= (void*)0xdeadbeef;
820 hr
= IAccessible_get_accChild(acc
, vid
, &disp
);
821 ok(hr
== E_INVALIDARG
, "get_accChild returned %x\n", hr
);
822 ok(disp
== NULL
, "disp = %p\n", disp
);
825 disp
= (void*)0xdeadbeef;
826 hr
= IAccessible_get_accChild(acc
, vid
, &disp
);
827 ok(hr
== E_INVALIDARG
, "get_accChild returned %x\n", hr
);
828 ok(disp
== NULL
, "disp = %p\n", disp
);
830 hr
= IAccessible_QueryInterface(acc
, &IID_IEnumVARIANT
, (void**)&ev
);
831 ok(hr
== S_OK
, "got %x\n", hr
);
833 hr
= IEnumVARIANT_Skip(ev
, 100);
834 ok(hr
== S_FALSE
, "Skip returned %x\n", hr
);
838 hr
= IEnumVARIANT_Next(ev
, 1, &v
, &fetched
);
839 ok(hr
== S_FALSE
, "got %x\n", hr
);
840 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
841 ok(fetched
== 0, "fetched = %d\n", fetched
);
843 hr
= IEnumVARIANT_Reset(ev
);
844 ok(hr
== S_OK
, "got %x\n", hr
);
848 hr
= IEnumVARIANT_Next(ev
, 1, &v
, &fetched
);
849 ok(hr
== S_OK
, "got %x\n", hr
);
850 ok(V_VT(&v
) == VT_DISPATCH
, "V_VT(&v) = %d\n", V_VT(&v
));
851 IDispatch_Release(V_DISPATCH(&v
));
852 ok(fetched
== 1, "fetched = %d\n", fetched
);
853 IEnumVARIANT_Release(ev
);
855 test_AccessibleChildren(acc
);
858 V_I4(&vid
) = CHILDID_SELF
;
859 hr
= IAccessible_get_accName(acc
, vid
, &str
);
860 ok(hr
== S_OK
, "got %x\n", hr
);
861 /* Window names don't have keyboard shortcuts */
862 todo_wine
ok(!lstrcmpW(str
, L
"wnd &t &junk") ||
863 broken(!lstrcmpW(str
, L
"wnd t &junk")), /* Windows < 10 1607 */
864 "name = %s\n", wine_dbgstr_w(str
));
867 hr
= IAccessible_get_accKeyboardShortcut(acc
, vid
, &str
);
868 todo_wine
ok(hr
== S_FALSE
|| broken(hr
== S_OK
), "got %x\n", hr
);
869 todo_wine
ok(str
== NULL
|| broken(!lstrcmpW(str
, L
"Alt+t")), "str = %s\n", wine_dbgstr_w(str
));
873 str
= (void*)0xdeadbeef;
874 hr
= IAccessible_get_accName(acc
, vid
, &str
);
875 ok(hr
== E_INVALIDARG
, "got %x\n", hr
);
876 ok(!str
, "str != NULL\n");
877 V_I4(&vid
) = CHILDID_SELF
;
879 str
= (void*)0xdeadbeef;
880 hr
= IAccessible_get_accValue(acc
, vid
, &str
);
881 ok(hr
== S_FALSE
, "got %x\n", hr
);
882 ok(!str
, "str != NULL\n");
884 str
= (void*)0xdeadbeef;
885 hr
= IAccessible_get_accDescription(acc
, vid
, &str
);
886 ok(hr
== S_FALSE
, "got %x\n", hr
);
887 ok(!str
, "str != NULL\n");
889 V_VT(&v
) = VT_DISPATCH
;
890 V_DISPATCH(&v
) = (void*)0xdeadbeef;
891 hr
= IAccessible_get_accRole(acc
, vid
, &v
);
892 ok(hr
== S_OK
, "got %x\n", hr
);
893 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
894 ok(V_I4(&v
) == ROLE_SYSTEM_CLIENT
, "V_I4(&v) = %d\n", V_I4(&v
));
896 V_VT(&v
) = VT_DISPATCH
;
897 V_DISPATCH(&v
) = (void*)0xdeadbeef;
898 hr
= IAccessible_get_accState(acc
, vid
, &v
);
899 ok(hr
== S_OK
, "got %x\n", hr
);
900 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
901 ok(V_I4(&v
) == (STATE_SYSTEM_FOCUSABLE
|STATE_SYSTEM_INVISIBLE
),
902 "V_I4(&v) = %x\n", V_I4(&v
));
904 str
= (void*)0xdeadbeef;
905 hr
= IAccessible_get_accHelp(acc
, vid
, &str
);
906 ok(hr
== S_FALSE
, "got %x\n", hr
);
907 ok(!str
, "str != NULL\n");
909 str
= (void*)0xdeadbeef;
910 hr
= IAccessible_get_accDefaultAction(acc
, vid
, &str
);
911 ok(hr
== S_FALSE
, "got %x\n", hr
);
912 ok(!str
, "str != NULL\n");
915 ok(ClientToScreen(hwnd
, &pt
), "ClientToScreen failed\n");
916 hr
= IAccessible_accHitTest(acc
, pt
.x
, pt
.y
, &v
);
917 ok(hr
== S_OK
, "got %x\n", hr
);
918 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
919 ok(V_I4(&v
) == 0, "V_I4(&v) = %d\n", V_I4(&v
));
922 ok(ClientToScreen(hwnd
, &pt
), "ClientToScreen failed\n");
923 hr
= IAccessible_accHitTest(acc
, pt
.x
, pt
.y
, &v
);
924 ok(hr
== S_OK
, "got %x\n", hr
);
925 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
926 ok(V_I4(&v
) == 0, "V_I4(&v) = %d\n", V_I4(&v
));
928 ShowWindow(hwnd
, TRUE
);
930 ok(ClientToScreen(hwnd
, &pt
), "ClientToScreen failed\n");
931 hr
= IAccessible_accHitTest(acc
, pt
.x
, pt
.y
, &v
);
932 ok(hr
== S_OK
, "got %x\n", hr
);
933 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
934 ok(V_I4(&v
) == 0, "V_I4(&v) = %d\n", V_I4(&v
));
937 ok(ClientToScreen(hwnd
, &pt
), "ClientToScreen failed\n");
938 hr
= IAccessible_accHitTest(acc
, pt
.x
, pt
.y
, &v
);
939 ok(hr
== S_OK
, "got %x\n", hr
);
940 ok(V_VT(&v
) == VT_DISPATCH
, "V_VT(&v) = %d\n", V_VT(&v
));
941 ok(V_DISPATCH(&v
) != NULL
, "V_DISPATCH(&v) = %p\n", V_DISPATCH(&v
));
944 ShowWindow(chld
, FALSE
);
946 ok(ClientToScreen(hwnd
, &pt
), "ClientToScreen failed\n");
947 hr
= IAccessible_accHitTest(acc
, pt
.x
, pt
.y
, &v
);
948 ok(hr
== S_OK
, "got %x\n", hr
);
949 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
950 ok(V_I4(&v
) == 0, "V_I4(&v) = %d\n", V_I4(&v
));
952 hr
= IAccessible_get_accParent(acc
, &disp
);
953 ok(hr
== S_OK
, "got %x\n", hr
);
954 ok(disp
!= NULL
, "disp == NULL\n");
955 IDispatch_Release(disp
);
957 ok(GetClientRect(hwnd
, &rect
), "GetClientRect failed\n");
960 MapWindowPoints(hwnd
, NULL
, &pt
, 1);
965 MapWindowPoints(hwnd
, NULL
, &pt
, 1);
966 hr
= IAccessible_accLocation(acc
, &left
, &top
, &width
, &height
, vid
);
967 ok(hr
== S_OK
, "got %x\n", hr
);
968 ok(left
== rect
.left
, "left = %d, expected %d\n", left
, rect
.left
);
969 ok(top
== rect
.top
, "top = %d, expected %d\n", top
, rect
.top
);
970 ok(width
== pt
.x
-rect
.left
, "width = %d, expected %d\n", width
, pt
.x
-rect
.left
);
971 ok(height
== pt
.y
-rect
.top
, "height = %d, expected %d\n", height
, pt
.y
-rect
.top
);
975 hr
= IAccessible_get_accChildCount(acc
, &l
);
976 ok(hr
== S_OK
, "got %x\n", hr
);
977 ok(l
== 0, "l = %d\n", l
);
979 hr
= IAccessible_get_accName(acc
, vid
, &str
);
980 ok(hr
== E_INVALIDARG
, "got %x\n", hr
);
982 hr
= IAccessible_get_accValue(acc
, vid
, &str
);
983 ok(hr
== S_FALSE
, "got %x\n", hr
);
985 hr
= IAccessible_get_accRole(acc
, vid
, &v
);
986 ok(hr
== S_OK
, "got %x\n", hr
);
987 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
988 ok(V_I4(&v
) == ROLE_SYSTEM_CLIENT
, "V_I4(&v) = %d\n", V_I4(&v
));
990 hr
= IAccessible_get_accState(acc
, vid
, &v
);
991 ok(hr
== S_OK
, "got %x\n", hr
);
992 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
993 ok(V_I4(&v
) == STATE_SYSTEM_INVISIBLE
, "V_I4(&v) = %x\n", V_I4(&v
));
995 hr
= IAccessible_accHitTest(acc
, 200, 200, &v
);
996 ok(hr
== S_OK
, "got %x\n", hr
);
997 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
998 ok(V_I4(&v
) == 0, "V_I4(&v) = %d\n", V_I4(&v
));
1000 disp
= (void*)0xdeadbeef;
1001 hr
= IAccessible_get_accParent(acc
, &disp
);
1002 ok(hr
== E_FAIL
, "got %x\n", hr
);
1003 ok(disp
== NULL
, "disp = %p\n", disp
);
1005 hr
= IAccessible_accLocation(acc
, &left
, &top
, &width
, &height
, vid
);
1006 ok(hr
== S_OK
, "got %x\n", hr
);
1007 ok(left
== 0, "left = %d\n", left
);
1008 ok(top
== 0, "top = %d\n", top
);
1009 ok(width
== 0, "width = %d\n", width
);
1010 ok(height
== 0, "height = %d\n", height
);
1012 IAccessible_Release(acc
);
1015 static void test_CAccPropServices(void)
1017 IAccPropServices
*acc_prop_services
;
1020 hres
= CoCreateInstance(&CLSID_CAccPropServices
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1021 &IID_IAccPropServices
, (void**)&acc_prop_services
);
1022 ok(hres
== S_OK
, "Could not create CAccPropServices instance: %08x\n", hres
);
1024 IAccPropServices_Release(acc_prop_services
);
1035 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
1037 argc
= winetest_get_mainargs(&argv
);
1038 if(argc
== 4 && !strcmp(argv
[2], "ObjectFromLresult")) {
1043 lres
= strtoll( argv
[3], NULL
, 16 );
1044 hres
= ObjectFromLresult(lres
, &IID_IUnknown
, 0, (void**)&unk
);
1045 ok(hres
== S_OK
, "hres = %x\n", hres
);
1046 IUnknown_Release(unk
);
1052 if(!register_window_class()) {
1053 skip("can't register test window class\n");
1058 test_GetStateText();
1059 test_LresultFromObject(argv
[0]);
1060 test_AccessibleObjectFromWindow();
1061 test_GetProcessHandleFromHwnd();
1062 test_default_client_accessible_object();
1063 test_AccessibleChildren(&Accessible
);
1065 unregister_window_class();
1069 test_CAccPropServices();