4 * Copyright 2019 Nikolay Sivov for CodeWeavers
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
25 #include "uiautomation.h"
27 #include "wine/iaccessible2.h"
29 #include "wine/test.h"
31 static HRESULT (WINAPI
*pUiaProviderFromIAccessible
)(IAccessible
*, long, DWORD
, IRawElementProviderSimple
**);
33 #define DEFINE_EXPECT(func) \
34 static int expect_ ## func = 0, called_ ## func = 0
36 #define SET_EXPECT(func) \
37 do { called_ ## func = 0; expect_ ## func = 1; } while(0)
39 #define SET_EXPECT_MULTI(func, num) \
40 do { called_ ## func = 0; expect_ ## func = num; } while(0)
42 #define CHECK_EXPECT2(func) \
44 ok(expect_ ##func, "unexpected call " #func "\n"); \
48 #define CHECK_EXPECT(func) \
50 CHECK_EXPECT2(func); \
54 #define CHECK_CALLED(func) \
56 ok(called_ ## func, "expected " #func "\n"); \
57 expect_ ## func = called_ ## func = 0; \
60 #define CHECK_CALLED_MULTI(func, num) \
62 ok(called_ ## func == num, "expected " #func " %d times (got %d)\n", num, called_ ## func); \
63 expect_ ## func = called_ ## func = 0; \
66 #define NAVDIR_INTERNAL_HWND 10
68 DEFINE_EXPECT(winproc_GETOBJECT_CLIENT
);
69 DEFINE_EXPECT(winproc_GETOBJECT_UiaRoot
);
70 DEFINE_EXPECT(Accessible_accNavigate
);
71 DEFINE_EXPECT(Accessible_get_accParent
);
72 DEFINE_EXPECT(Accessible_get_accChildCount
);
73 DEFINE_EXPECT(Accessible_get_accName
);
74 DEFINE_EXPECT(Accessible_get_accRole
);
75 DEFINE_EXPECT(Accessible_get_accState
);
76 DEFINE_EXPECT(Accessible_accLocation
);
77 DEFINE_EXPECT(Accessible_get_accChild
);
78 DEFINE_EXPECT(Accessible_get_uniqueID
);
79 DEFINE_EXPECT(Accessible2_get_accParent
);
80 DEFINE_EXPECT(Accessible2_get_accChildCount
);
81 DEFINE_EXPECT(Accessible2_get_accName
);
82 DEFINE_EXPECT(Accessible2_get_accRole
);
83 DEFINE_EXPECT(Accessible2_get_accState
);
84 DEFINE_EXPECT(Accessible2_accLocation
);
85 DEFINE_EXPECT(Accessible2_QI_IAccIdentity
);
86 DEFINE_EXPECT(Accessible2_get_uniqueID
);
87 DEFINE_EXPECT(Accessible_child_accNavigate
);
88 DEFINE_EXPECT(Accessible_child_get_accParent
);
89 DEFINE_EXPECT(Accessible_child_get_accChildCount
);
90 DEFINE_EXPECT(Accessible_child_get_accName
);
91 DEFINE_EXPECT(Accessible_child_get_accRole
);
92 DEFINE_EXPECT(Accessible_child_get_accState
);
93 DEFINE_EXPECT(Accessible_child_accLocation
);
94 DEFINE_EXPECT(Accessible_child2_accNavigate
);
95 DEFINE_EXPECT(Accessible_child2_get_accParent
);
96 DEFINE_EXPECT(Accessible_child2_get_accChildCount
);
97 DEFINE_EXPECT(Accessible_child2_get_accName
);
98 DEFINE_EXPECT(Accessible_child2_get_accRole
);
99 DEFINE_EXPECT(Accessible_child2_get_accState
);
100 DEFINE_EXPECT(Accessible_child2_accLocation
);
102 static BOOL
check_variant_i4(VARIANT
*v
, int val
)
104 if (V_VT(v
) == VT_I4
&& V_I4(v
) == val
)
110 static BOOL
check_variant_bool(VARIANT
*v
, BOOL val
)
112 if (V_VT(v
) == VT_BOOL
&& V_BOOL(v
) == (val
? VARIANT_TRUE
: VARIANT_FALSE
))
118 static BOOL
iface_cmp(IUnknown
*iface1
, IUnknown
*iface2
)
120 IUnknown
*unk1
, *unk2
;
123 IUnknown_QueryInterface(iface1
, &IID_IUnknown
, (void**)&unk1
);
124 IUnknown_QueryInterface(iface2
, &IID_IUnknown
, (void**)&unk2
);
125 cmp
= (unk1
== unk2
) ? TRUE
: FALSE
;
127 IUnknown_Release(unk1
);
128 IUnknown_Release(unk2
);
132 static struct Accessible
134 IAccessible IAccessible_iface
;
135 IAccessible2 IAccessible2_iface
;
136 IOleWindow IOleWindow_iface
;
137 IServiceProvider IServiceProvider_iface
;
147 LONG left
, top
, width
, height
;
150 } Accessible
, Accessible2
, Accessible_child
, Accessible_child2
;
152 static inline struct Accessible
* impl_from_Accessible(IAccessible
*iface
)
154 return CONTAINING_RECORD(iface
, struct Accessible
, IAccessible_iface
);
157 static HRESULT WINAPI
Accessible_QueryInterface(IAccessible
*iface
, REFIID riid
, void **obj
)
159 struct Accessible
*This
= impl_from_Accessible(iface
);
162 if (IsEqualIID(riid
, &IID_IAccIdentity
))
164 if (This
== &Accessible2
)
165 CHECK_EXPECT(Accessible2_QI_IAccIdentity
);
166 ok(This
== &Accessible2
, "unexpected call\n");
167 return E_NOINTERFACE
;
170 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IDispatch
) ||
171 IsEqualIID(riid
, &IID_IAccessible
))
173 else if (IsEqualIID(riid
, &IID_IOleWindow
))
174 *obj
= &This
->IOleWindow_iface
;
175 else if (IsEqualIID(riid
, &IID_IServiceProvider
))
176 *obj
= &This
->IServiceProvider_iface
;
177 else if (IsEqualIID(riid
, &IID_IAccessible2
) && This
->enable_ia2
)
178 *obj
= &This
->IAccessible2_iface
;
180 return E_NOINTERFACE
;
182 IAccessible_AddRef(iface
);
186 static ULONG WINAPI
Accessible_AddRef(IAccessible
*iface
)
188 struct Accessible
*This
= impl_from_Accessible(iface
);
189 return InterlockedIncrement(&This
->ref
);
192 static ULONG WINAPI
Accessible_Release(IAccessible
*iface
)
194 struct Accessible
*This
= impl_from_Accessible(iface
);
195 return InterlockedDecrement(&This
->ref
);
198 static HRESULT WINAPI
Accessible_GetTypeInfoCount(IAccessible
*iface
, UINT
*pctinfo
)
200 ok(0, "unexpected call\n");
204 static HRESULT WINAPI
Accessible_GetTypeInfo(IAccessible
*iface
, UINT iTInfo
,
205 LCID lcid
, ITypeInfo
**out_tinfo
)
207 ok(0, "unexpected call\n");
211 static HRESULT WINAPI
Accessible_GetIDsOfNames(IAccessible
*iface
, REFIID riid
,
212 LPOLESTR
*rg_names
, UINT name_count
, LCID lcid
, DISPID
*rg_disp_id
)
214 ok(0, "unexpected call\n");
218 static HRESULT WINAPI
Accessible_Invoke(IAccessible
*iface
, DISPID disp_id_member
,
219 REFIID riid
, LCID lcid
, WORD flags
, DISPPARAMS
*disp_params
,
220 VARIANT
*var_result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
222 ok(0, "unexpected call\n");
226 static HRESULT WINAPI
Accessible_get_accParent(IAccessible
*iface
, IDispatch
**out_parent
)
228 struct Accessible
*This
= impl_from_Accessible(iface
);
230 if (This
== &Accessible_child
)
231 CHECK_EXPECT(Accessible_child_get_accParent
);
232 else if (This
== &Accessible_child2
)
233 CHECK_EXPECT(Accessible_child2_get_accParent
);
234 else if (This
== &Accessible2
)
235 CHECK_EXPECT(Accessible2_get_accParent
);
237 CHECK_EXPECT(Accessible_get_accParent
);
240 return IAccessible_QueryInterface(This
->parent
, &IID_IDispatch
, (void **)out_parent
);
246 static HRESULT WINAPI
Accessible_get_accChildCount(IAccessible
*iface
, LONG
*out_count
)
248 struct Accessible
*This
= impl_from_Accessible(iface
);
250 if (This
== &Accessible_child
)
251 CHECK_EXPECT(Accessible_child_get_accChildCount
);
252 else if (This
== &Accessible_child2
)
253 CHECK_EXPECT(Accessible_child2_get_accChildCount
);
254 else if (This
== &Accessible2
)
255 CHECK_EXPECT(Accessible2_get_accChildCount
);
257 CHECK_EXPECT(Accessible_get_accChildCount
);
259 if (This
->child_count
)
261 *out_count
= This
->child_count
;
268 static HRESULT WINAPI
Accessible_get_accChild(IAccessible
*iface
, VARIANT child_id
,
269 IDispatch
**out_child
)
271 struct Accessible
*This
= impl_from_Accessible(iface
);
273 CHECK_EXPECT(Accessible_get_accChild
);
274 ok(This
== &Accessible
, "unexpected call\n");
277 if (V_VT(&child_id
) != VT_I4
)
280 if (This
== &Accessible
)
282 switch (V_I4(&child_id
))
285 return IAccessible_QueryInterface(&This
->IAccessible_iface
, &IID_IDispatch
, (void **)out_child
);
287 /* Simple element children. */
293 return IAccessible_QueryInterface(&Accessible_child
.IAccessible_iface
, &IID_IDispatch
, (void **)out_child
);
296 return IAccessible_QueryInterface(&Accessible_child2
.IAccessible_iface
, &IID_IDispatch
, (void **)out_child
);
306 static HRESULT WINAPI
Accessible_get_accName(IAccessible
*iface
, VARIANT child_id
,
309 struct Accessible
*This
= impl_from_Accessible(iface
);
312 if (This
== &Accessible_child
)
313 CHECK_EXPECT(Accessible_child_get_accName
);
314 else if (This
== &Accessible_child2
)
315 CHECK_EXPECT(Accessible_child2_get_accName
);
316 else if (This
== &Accessible2
)
317 CHECK_EXPECT(Accessible2_get_accName
);
319 CHECK_EXPECT(Accessible_get_accName
);
323 *out_name
= SysAllocString(This
->name
);
330 static HRESULT WINAPI
Accessible_get_accValue(IAccessible
*iface
, VARIANT child_id
,
333 ok(0, "unexpected call\n");
337 static HRESULT WINAPI
Accessible_get_accDescription(IAccessible
*iface
, VARIANT child_id
,
338 BSTR
*out_description
)
340 ok(0, "unexpected call\n");
344 static HRESULT WINAPI
Accessible_get_accRole(IAccessible
*iface
, VARIANT child_id
,
347 struct Accessible
*This
= impl_from_Accessible(iface
);
349 if (This
== &Accessible_child
)
350 CHECK_EXPECT(Accessible_child_get_accRole
);
351 else if (This
== &Accessible_child2
)
352 CHECK_EXPECT(Accessible_child2_get_accRole
);
353 else if (This
== &Accessible2
)
354 CHECK_EXPECT(Accessible2_get_accRole
);
356 CHECK_EXPECT(Accessible_get_accRole
);
360 V_VT(out_role
) = VT_I4
;
361 V_I4(out_role
) = This
->role
;
368 static HRESULT WINAPI
Accessible_get_accState(IAccessible
*iface
, VARIANT child_id
,
371 struct Accessible
*This
= impl_from_Accessible(iface
);
373 if (This
== &Accessible_child
)
374 CHECK_EXPECT(Accessible_child_get_accState
);
375 else if (This
== &Accessible_child2
)
376 CHECK_EXPECT(Accessible_child2_get_accState
);
377 else if (This
== &Accessible2
)
378 CHECK_EXPECT(Accessible2_get_accState
);
380 CHECK_EXPECT(Accessible_get_accState
);
382 if (V_VT(&child_id
) != VT_I4
)
385 if (This
== &Accessible
&& V_I4(&child_id
) != CHILDID_SELF
)
387 switch (V_I4(&child_id
))
390 V_VT(out_state
) = VT_I4
;
391 V_I4(out_state
) = STATE_SYSTEM_INVISIBLE
;
395 V_VT(out_state
) = VT_I4
;
396 V_I4(out_state
) = STATE_SYSTEM_FOCUSABLE
;
408 V_VT(out_state
) = VT_I4
;
409 V_I4(out_state
) = This
->state
;
416 static HRESULT WINAPI
Accessible_get_accHelp(IAccessible
*iface
, VARIANT child_id
,
419 ok(0, "unexpected call\n");
423 static HRESULT WINAPI
Accessible_get_accHelpTopic(IAccessible
*iface
,
424 BSTR
*out_help_file
, VARIANT child_id
, LONG
*out_topic_id
)
426 ok(0, "unexpected call\n");
430 static HRESULT WINAPI
Accessible_get_accKeyboardShortcut(IAccessible
*iface
, VARIANT child_id
,
431 BSTR
*out_kbd_shortcut
)
433 ok(0, "unexpected call\n");
437 static HRESULT WINAPI
Accessible_get_accFocus(IAccessible
*iface
, VARIANT
*pchild_id
)
439 ok(0, "unexpected call\n");
443 static HRESULT WINAPI
Accessible_get_accSelection(IAccessible
*iface
, VARIANT
*out_selection
)
445 ok(0, "unexpected call\n");
449 static HRESULT WINAPI
Accessible_get_accDefaultAction(IAccessible
*iface
, VARIANT child_id
,
450 BSTR
*out_default_action
)
452 ok(0, "unexpected call\n");
456 static HRESULT WINAPI
Accessible_accSelect(IAccessible
*iface
, LONG select_flags
,
459 ok(0, "unexpected call\n");
463 static HRESULT WINAPI
Accessible_accLocation(IAccessible
*iface
, LONG
*out_left
,
464 LONG
*out_top
, LONG
*out_width
, LONG
*out_height
, VARIANT child_id
)
466 struct Accessible
*This
= impl_from_Accessible(iface
);
468 if (This
== &Accessible_child
)
469 CHECK_EXPECT(Accessible_child_accLocation
);
470 else if (This
== &Accessible_child2
)
471 CHECK_EXPECT(Accessible_child2_accLocation
);
472 else if (This
== &Accessible2
)
473 CHECK_EXPECT(Accessible2_accLocation
);
475 CHECK_EXPECT(Accessible_accLocation
);
477 if (This
->width
&& This
->height
)
479 *out_left
= This
->left
;
480 *out_top
= This
->top
;
481 *out_width
= This
->width
;
482 *out_height
= This
->height
;
489 static HRESULT WINAPI
Accessible_accNavigate(IAccessible
*iface
, LONG nav_direction
,
490 VARIANT child_id_start
, VARIANT
*out_var
)
492 struct Accessible
*This
= impl_from_Accessible(iface
);
494 if (This
== &Accessible_child
)
495 CHECK_EXPECT(Accessible_child_accNavigate
);
496 else if (This
== &Accessible_child2
)
497 CHECK_EXPECT(Accessible_child2_accNavigate
);
499 CHECK_EXPECT(Accessible_accNavigate
);
500 VariantInit(out_var
);
503 * This is an undocumented way for UI Automation to get an HWND for
504 * IAccessible's contained in a Direct Annotation wrapper object.
506 if ((nav_direction
== NAVDIR_INTERNAL_HWND
) && check_variant_i4(&child_id_start
, CHILDID_SELF
) &&
509 V_VT(out_var
) = VT_I4
;
510 V_I4(out_var
) = HandleToUlong(This
->acc_hwnd
);
516 static HRESULT WINAPI
Accessible_accHitTest(IAccessible
*iface
, LONG left
, LONG top
,
517 VARIANT
*out_child_id
)
519 ok(0, "unexpected call\n");
523 static HRESULT WINAPI
Accessible_accDoDefaultAction(IAccessible
*iface
, VARIANT child_id
)
525 ok(0, "unexpected call\n");
529 static HRESULT WINAPI
Accessible_put_accName(IAccessible
*iface
, VARIANT child_id
,
532 ok(0, "unexpected call\n");
536 static HRESULT WINAPI
Accessible_put_accValue(IAccessible
*iface
, VARIANT child_id
,
539 ok(0, "unexpected call\n");
543 static IAccessibleVtbl AccessibleVtbl
= {
544 Accessible_QueryInterface
,
547 Accessible_GetTypeInfoCount
,
548 Accessible_GetTypeInfo
,
549 Accessible_GetIDsOfNames
,
551 Accessible_get_accParent
,
552 Accessible_get_accChildCount
,
553 Accessible_get_accChild
,
554 Accessible_get_accName
,
555 Accessible_get_accValue
,
556 Accessible_get_accDescription
,
557 Accessible_get_accRole
,
558 Accessible_get_accState
,
559 Accessible_get_accHelp
,
560 Accessible_get_accHelpTopic
,
561 Accessible_get_accKeyboardShortcut
,
562 Accessible_get_accFocus
,
563 Accessible_get_accSelection
,
564 Accessible_get_accDefaultAction
,
565 Accessible_accSelect
,
566 Accessible_accLocation
,
567 Accessible_accNavigate
,
568 Accessible_accHitTest
,
569 Accessible_accDoDefaultAction
,
570 Accessible_put_accName
,
571 Accessible_put_accValue
574 static inline struct Accessible
* impl_from_Accessible2(IAccessible2
*iface
)
576 return CONTAINING_RECORD(iface
, struct Accessible
, IAccessible2_iface
);
579 static HRESULT WINAPI
Accessible2_QueryInterface(IAccessible2
*iface
, REFIID riid
, void **obj
)
581 struct Accessible
*This
= impl_from_Accessible2(iface
);
582 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, obj
);
585 static ULONG WINAPI
Accessible2_AddRef(IAccessible2
*iface
)
587 struct Accessible
*This
= impl_from_Accessible2(iface
);
588 return IAccessible_AddRef(&This
->IAccessible_iface
);
591 static ULONG WINAPI
Accessible2_Release(IAccessible2
*iface
)
593 struct Accessible
*This
= impl_from_Accessible2(iface
);
594 return IAccessible_Release(&This
->IAccessible_iface
);
597 static HRESULT WINAPI
Accessible2_GetTypeInfoCount(IAccessible2
*iface
, UINT
*pctinfo
)
599 struct Accessible
*This
= impl_from_Accessible2(iface
);
600 return IAccessible_GetTypeInfoCount(&This
->IAccessible_iface
, pctinfo
);
603 static HRESULT WINAPI
Accessible2_GetTypeInfo(IAccessible2
*iface
, UINT iTInfo
,
604 LCID lcid
, ITypeInfo
**out_tinfo
)
606 struct Accessible
*This
= impl_from_Accessible2(iface
);
607 return IAccessible_GetTypeInfo(&This
->IAccessible_iface
, iTInfo
, lcid
, out_tinfo
);
610 static HRESULT WINAPI
Accessible2_GetIDsOfNames(IAccessible2
*iface
, REFIID riid
,
611 LPOLESTR
*rg_names
, UINT name_count
, LCID lcid
, DISPID
*rg_disp_id
)
613 struct Accessible
*This
= impl_from_Accessible2(iface
);
614 return IAccessible_GetIDsOfNames(&This
->IAccessible_iface
, riid
, rg_names
, name_count
,
618 static HRESULT WINAPI
Accessible2_Invoke(IAccessible2
*iface
, DISPID disp_id_member
,
619 REFIID riid
, LCID lcid
, WORD flags
, DISPPARAMS
*disp_params
,
620 VARIANT
*var_result
, EXCEPINFO
*excep_info
, UINT
*arg_err
)
622 struct Accessible
*This
= impl_from_Accessible2(iface
);
623 return IAccessible_Invoke(&This
->IAccessible_iface
, disp_id_member
, riid
, lcid
, flags
,
624 disp_params
, var_result
, excep_info
, arg_err
);
627 static HRESULT WINAPI
Accessible2_get_accParent(IAccessible2
*iface
, IDispatch
**out_parent
)
629 struct Accessible
*This
= impl_from_Accessible2(iface
);
630 return IAccessible_get_accParent(&This
->IAccessible_iface
, out_parent
);
633 static HRESULT WINAPI
Accessible2_get_accChildCount(IAccessible2
*iface
, LONG
*out_count
)
635 struct Accessible
*This
= impl_from_Accessible2(iface
);
636 return IAccessible_get_accChildCount(&This
->IAccessible_iface
, out_count
);
639 static HRESULT WINAPI
Accessible2_get_accChild(IAccessible2
*iface
, VARIANT child_id
,
640 IDispatch
**out_child
)
642 struct Accessible
*This
= impl_from_Accessible2(iface
);
643 return IAccessible_get_accChild(&This
->IAccessible_iface
, child_id
, out_child
);
646 static HRESULT WINAPI
Accessible2_get_accName(IAccessible2
*iface
, VARIANT child_id
,
649 struct Accessible
*This
= impl_from_Accessible2(iface
);
650 return IAccessible_get_accName(&This
->IAccessible_iface
, child_id
, out_name
);
653 static HRESULT WINAPI
Accessible2_get_accValue(IAccessible2
*iface
, VARIANT child_id
,
656 struct Accessible
*This
= impl_from_Accessible2(iface
);
657 return IAccessible_get_accValue(&This
->IAccessible_iface
, child_id
, out_value
);
660 static HRESULT WINAPI
Accessible2_get_accDescription(IAccessible2
*iface
, VARIANT child_id
,
661 BSTR
*out_description
)
663 struct Accessible
*This
= impl_from_Accessible2(iface
);
664 return IAccessible_get_accDescription(&This
->IAccessible_iface
, child_id
, out_description
);
667 static HRESULT WINAPI
Accessible2_get_accRole(IAccessible2
*iface
, VARIANT child_id
,
670 struct Accessible
*This
= impl_from_Accessible2(iface
);
671 return IAccessible_get_accRole(&This
->IAccessible_iface
, child_id
, out_role
);
674 static HRESULT WINAPI
Accessible2_get_accState(IAccessible2
*iface
, VARIANT child_id
,
677 struct Accessible
*This
= impl_from_Accessible2(iface
);
678 return IAccessible_get_accState(&This
->IAccessible_iface
, child_id
, out_state
);
681 static HRESULT WINAPI
Accessible2_get_accHelp(IAccessible2
*iface
, VARIANT child_id
,
684 struct Accessible
*This
= impl_from_Accessible2(iface
);
685 return IAccessible_get_accHelp(&This
->IAccessible_iface
, child_id
, out_help
);
688 static HRESULT WINAPI
Accessible2_get_accHelpTopic(IAccessible2
*iface
,
689 BSTR
*out_help_file
, VARIANT child_id
, LONG
*out_topic_id
)
691 struct Accessible
*This
= impl_from_Accessible2(iface
);
692 return IAccessible_get_accHelpTopic(&This
->IAccessible_iface
, out_help_file
, child_id
,
696 static HRESULT WINAPI
Accessible2_get_accKeyboardShortcut(IAccessible2
*iface
, VARIANT child_id
,
697 BSTR
*out_kbd_shortcut
)
699 struct Accessible
*This
= impl_from_Accessible2(iface
);
700 return IAccessible_get_accKeyboardShortcut(&This
->IAccessible_iface
, child_id
,
704 static HRESULT WINAPI
Accessible2_get_accFocus(IAccessible2
*iface
, VARIANT
*pchild_id
)
706 struct Accessible
*This
= impl_from_Accessible2(iface
);
707 return IAccessible_get_accFocus(&This
->IAccessible_iface
, pchild_id
);
710 static HRESULT WINAPI
Accessible2_get_accSelection(IAccessible2
*iface
, VARIANT
*out_selection
)
712 struct Accessible
*This
= impl_from_Accessible2(iface
);
713 return IAccessible_get_accSelection(&This
->IAccessible_iface
, out_selection
);
716 static HRESULT WINAPI
Accessible2_get_accDefaultAction(IAccessible2
*iface
, VARIANT child_id
,
717 BSTR
*out_default_action
)
719 struct Accessible
*This
= impl_from_Accessible2(iface
);
720 return IAccessible_get_accDefaultAction(&This
->IAccessible_iface
, child_id
,
724 static HRESULT WINAPI
Accessible2_accSelect(IAccessible2
*iface
, LONG select_flags
,
727 struct Accessible
*This
= impl_from_Accessible2(iface
);
728 return IAccessible_accSelect(&This
->IAccessible_iface
, select_flags
, child_id
);
731 static HRESULT WINAPI
Accessible2_accLocation(IAccessible2
*iface
, LONG
*out_left
,
732 LONG
*out_top
, LONG
*out_width
, LONG
*out_height
, VARIANT child_id
)
734 struct Accessible
*This
= impl_from_Accessible2(iface
);
735 return IAccessible_accLocation(&This
->IAccessible_iface
, out_left
, out_top
, out_width
,
736 out_height
, child_id
);
739 static HRESULT WINAPI
Accessible2_accNavigate(IAccessible2
*iface
, LONG nav_direction
,
740 VARIANT child_id_start
, VARIANT
*out_var
)
742 struct Accessible
*This
= impl_from_Accessible2(iface
);
743 return IAccessible_accNavigate(&This
->IAccessible_iface
, nav_direction
, child_id_start
,
747 static HRESULT WINAPI
Accessible2_accHitTest(IAccessible2
*iface
, LONG left
, LONG top
,
748 VARIANT
*out_child_id
)
750 struct Accessible
*This
= impl_from_Accessible2(iface
);
751 return IAccessible_accHitTest(&This
->IAccessible_iface
, left
, top
, out_child_id
);
754 static HRESULT WINAPI
Accessible2_accDoDefaultAction(IAccessible2
*iface
, VARIANT child_id
)
756 struct Accessible
*This
= impl_from_Accessible2(iface
);
757 return IAccessible_accDoDefaultAction(&This
->IAccessible_iface
, child_id
);
760 static HRESULT WINAPI
Accessible2_put_accName(IAccessible2
*iface
, VARIANT child_id
,
763 struct Accessible
*This
= impl_from_Accessible2(iface
);
764 return IAccessible_put_accName(&This
->IAccessible_iface
, child_id
, name
);
767 static HRESULT WINAPI
Accessible2_put_accValue(IAccessible2
*iface
, VARIANT child_id
,
770 struct Accessible
*This
= impl_from_Accessible2(iface
);
771 return IAccessible_put_accValue(&This
->IAccessible_iface
, child_id
, value
);
774 static HRESULT WINAPI
Accessible2_get_nRelations(IAccessible2
*iface
, LONG
*out_nRelations
)
776 ok(0, "unexpected call\n");
780 static HRESULT WINAPI
Accessible2_get_relation(IAccessible2
*iface
, LONG relation_idx
,
781 IAccessibleRelation
**out_relation
)
783 ok(0, "unexpected call\n");
787 static HRESULT WINAPI
Accessible2_get_relations(IAccessible2
*iface
, LONG count
,
788 IAccessibleRelation
**out_relations
, LONG
*out_relation_count
)
790 ok(0, "unexpected call\n");
794 static HRESULT WINAPI
Accessible2_role(IAccessible2
*iface
, LONG
*out_role
)
796 ok(0, "unexpected call\n");
800 static HRESULT WINAPI
Accessible2_scrollTo(IAccessible2
*iface
, enum IA2ScrollType scroll_type
)
802 ok(0, "unexpected call\n");
806 static HRESULT WINAPI
Accessible2_scrollToPoint(IAccessible2
*iface
,
807 enum IA2CoordinateType coordinate_type
, LONG x
, LONG y
)
809 ok(0, "unexpected call\n");
813 static HRESULT WINAPI
Accessible2_get_groupPosition(IAccessible2
*iface
, LONG
*out_group_level
,
814 LONG
*out_similar_items_in_group
, LONG
*out_position_in_group
)
816 ok(0, "unexpected call\n");
820 static HRESULT WINAPI
Accessible2_get_states(IAccessible2
*iface
, AccessibleStates
*out_states
)
822 ok(0, "unexpected call\n");
826 static HRESULT WINAPI
Accessible2_get_extendedRole(IAccessible2
*iface
, BSTR
*out_extended_role
)
828 ok(0, "unexpected call\n");
832 static HRESULT WINAPI
Accessible2_get_localizedExtendedRole(IAccessible2
*iface
,
833 BSTR
*out_localized_extended_role
)
835 ok(0, "unexpected call\n");
839 static HRESULT WINAPI
Accessible2_get_nExtendedStates(IAccessible2
*iface
, LONG
*out_nExtendedStates
)
841 ok(0, "unexpected call\n");
845 static HRESULT WINAPI
Accessible2_get_extendedStates(IAccessible2
*iface
, LONG count
,
846 BSTR
**out_extended_states
, LONG
*out_extended_states_count
)
848 ok(0, "unexpected call\n");
852 static HRESULT WINAPI
Accessible2_get_localizedExtendedStates(IAccessible2
*iface
, LONG count
,
853 BSTR
**out_localized_extended_states
, LONG
*out_localized_extended_states_count
)
855 ok(0, "unexpected call\n");
859 static HRESULT WINAPI
Accessible2_get_uniqueID(IAccessible2
*iface
, LONG
*out_unique_id
)
861 struct Accessible
*This
= impl_from_Accessible2(iface
);
863 if (This
== &Accessible2
)
864 CHECK_EXPECT(Accessible2_get_uniqueID
);
866 CHECK_EXPECT(Accessible_get_uniqueID
);
871 *out_unique_id
= This
->unique_id
;
878 static HRESULT WINAPI
Accessible2_get_windowHandle(IAccessible2
*iface
, HWND
*out_hwnd
)
880 ok(0, "unexpected call\n");
884 static HRESULT WINAPI
Accessible2_get_indexInParent(IAccessible2
*iface
, LONG
*out_idx_in_parent
)
886 ok(0, "unexpected call\n");
890 static HRESULT WINAPI
Accessible2_get_locale(IAccessible2
*iface
, IA2Locale
*out_locale
)
892 ok(0, "unexpected call\n");
896 static HRESULT WINAPI
Accessible2_get_attributes(IAccessible2
*iface
, BSTR
*out_attributes
)
898 ok(0, "unexpected call\n");
902 static const IAccessible2Vtbl Accessible2Vtbl
= {
903 Accessible2_QueryInterface
,
906 Accessible2_GetTypeInfoCount
,
907 Accessible2_GetTypeInfo
,
908 Accessible2_GetIDsOfNames
,
910 Accessible2_get_accParent
,
911 Accessible2_get_accChildCount
,
912 Accessible2_get_accChild
,
913 Accessible2_get_accName
,
914 Accessible2_get_accValue
,
915 Accessible2_get_accDescription
,
916 Accessible2_get_accRole
,
917 Accessible2_get_accState
,
918 Accessible2_get_accHelp
,
919 Accessible2_get_accHelpTopic
,
920 Accessible2_get_accKeyboardShortcut
,
921 Accessible2_get_accFocus
,
922 Accessible2_get_accSelection
,
923 Accessible2_get_accDefaultAction
,
924 Accessible2_accSelect
,
925 Accessible2_accLocation
,
926 Accessible2_accNavigate
,
927 Accessible2_accHitTest
,
928 Accessible2_accDoDefaultAction
,
929 Accessible2_put_accName
,
930 Accessible2_put_accValue
,
931 Accessible2_get_nRelations
,
932 Accessible2_get_relation
,
933 Accessible2_get_relations
,
935 Accessible2_scrollTo
,
936 Accessible2_scrollToPoint
,
937 Accessible2_get_groupPosition
,
938 Accessible2_get_states
,
939 Accessible2_get_extendedRole
,
940 Accessible2_get_localizedExtendedRole
,
941 Accessible2_get_nExtendedStates
,
942 Accessible2_get_extendedStates
,
943 Accessible2_get_localizedExtendedStates
,
944 Accessible2_get_uniqueID
,
945 Accessible2_get_windowHandle
,
946 Accessible2_get_indexInParent
,
947 Accessible2_get_locale
,
948 Accessible2_get_attributes
,
951 static inline struct Accessible
* impl_from_OleWindow(IOleWindow
*iface
)
953 return CONTAINING_RECORD(iface
, struct Accessible
, IOleWindow_iface
);
956 static HRESULT WINAPI
OleWindow_QueryInterface(IOleWindow
*iface
, REFIID riid
, void **obj
)
958 struct Accessible
*This
= impl_from_OleWindow(iface
);
959 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, obj
);
962 static ULONG WINAPI
OleWindow_AddRef(IOleWindow
*iface
)
964 struct Accessible
*This
= impl_from_OleWindow(iface
);
965 return IAccessible_AddRef(&This
->IAccessible_iface
);
968 static ULONG WINAPI
OleWindow_Release(IOleWindow
*iface
)
970 struct Accessible
*This
= impl_from_OleWindow(iface
);
971 return IAccessible_Release(&This
->IAccessible_iface
);
974 static HRESULT WINAPI
OleWindow_GetWindow(IOleWindow
*iface
, HWND
*hwnd
)
976 struct Accessible
*This
= impl_from_OleWindow(iface
);
978 *hwnd
= This
->ow_hwnd
;
979 return *hwnd
? S_OK
: E_FAIL
;
982 static HRESULT WINAPI
OleWindow_ContextSensitiveHelp(IOleWindow
*iface
, BOOL f_enter_mode
)
987 static const IOleWindowVtbl OleWindowVtbl
= {
988 OleWindow_QueryInterface
,
992 OleWindow_ContextSensitiveHelp
995 static inline struct Accessible
* impl_from_ServiceProvider(IServiceProvider
*iface
)
997 return CONTAINING_RECORD(iface
, struct Accessible
, IServiceProvider_iface
);
1000 static HRESULT WINAPI
ServiceProvider_QueryInterface(IServiceProvider
*iface
, REFIID riid
, void **obj
)
1002 struct Accessible
*This
= impl_from_ServiceProvider(iface
);
1003 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, obj
);
1006 static ULONG WINAPI
ServiceProvider_AddRef(IServiceProvider
*iface
)
1008 struct Accessible
*This
= impl_from_ServiceProvider(iface
);
1009 return IAccessible_AddRef(&This
->IAccessible_iface
);
1012 static ULONG WINAPI
ServiceProvider_Release(IServiceProvider
*iface
)
1014 struct Accessible
*This
= impl_from_ServiceProvider(iface
);
1015 return IAccessible_Release(&This
->IAccessible_iface
);
1018 static HRESULT WINAPI
ServiceProvider_QueryService(IServiceProvider
*iface
, REFGUID service_guid
,
1019 REFIID riid
, void **obj
)
1021 struct Accessible
*This
= impl_from_ServiceProvider(iface
);
1023 if (IsEqualIID(riid
, &IID_IAccessible2
) && IsEqualIID(service_guid
, &IID_IAccessible2
) &&
1025 return IAccessible_QueryInterface(&This
->IAccessible_iface
, riid
, obj
);
1030 static const IServiceProviderVtbl ServiceProviderVtbl
= {
1031 ServiceProvider_QueryInterface
,
1032 ServiceProvider_AddRef
,
1033 ServiceProvider_Release
,
1034 ServiceProvider_QueryService
,
1037 static struct Accessible Accessible
=
1039 { &AccessibleVtbl
},
1040 { &Accessible2Vtbl
},
1042 { &ServiceProviderVtbl
},
1051 static struct Accessible Accessible2
=
1053 { &AccessibleVtbl
},
1054 { &Accessible2Vtbl
},
1056 { &ServiceProviderVtbl
},
1065 static struct Accessible Accessible_child
=
1067 { &AccessibleVtbl
},
1068 { &Accessible2Vtbl
},
1070 { &ServiceProviderVtbl
},
1072 &Accessible
.IAccessible_iface
,
1079 static struct Accessible Accessible_child2
=
1081 { &AccessibleVtbl
},
1082 { &Accessible2Vtbl
},
1084 { &ServiceProviderVtbl
},
1086 &Accessible
.IAccessible_iface
,
1093 static struct Provider
1095 IRawElementProviderSimple IRawElementProviderSimple_iface
;
1096 IRawElementProviderFragment IRawElementProviderFragment_iface
;
1099 const char *prov_name
;
1100 IRawElementProviderFragment
*parent
;
1101 enum ProviderOptions prov_opts
;
1103 BOOL ret_invalid_prop_type
;
1105 } Provider
, Provider2
, Provider_child
, Provider_child2
;
1107 static const WCHAR
*uia_bstr_prop_str
= L
"uia-string";
1108 static const ULONG uia_i4_prop_val
= 0xdeadbeef;
1109 static const ULONG uia_i4_arr_prop_val
[] = { 0xfeedbeef, 0xdeadcafe, 0xfefedede };
1110 static const double uia_r8_prop_val
= 128.256f
;
1111 static const double uia_r8_arr_prop_val
[] = { 2.4, 8.16, 32.64 };
1112 static const IRawElementProviderSimple
*uia_unk_arr_prop_val
[] = { &Provider_child
.IRawElementProviderSimple_iface
,
1113 &Provider_child2
.IRawElementProviderSimple_iface
};
1114 static SAFEARRAY
*create_i4_safearray(void)
1119 if (!(sa
= SafeArrayCreateVector(VT_I4
, 0, ARRAY_SIZE(uia_i4_arr_prop_val
))))
1122 for (idx
= 0; idx
< ARRAY_SIZE(uia_i4_arr_prop_val
); idx
++)
1123 SafeArrayPutElement(sa
, &idx
, (void *)&uia_i4_arr_prop_val
[idx
]);
1128 static SAFEARRAY
*create_r8_safearray(void)
1133 if (!(sa
= SafeArrayCreateVector(VT_R8
, 0, ARRAY_SIZE(uia_r8_arr_prop_val
))))
1136 for (idx
= 0; idx
< ARRAY_SIZE(uia_r8_arr_prop_val
); idx
++)
1137 SafeArrayPutElement(sa
, &idx
, (void *)&uia_r8_arr_prop_val
[idx
]);
1142 static SAFEARRAY
*create_unk_safearray(void)
1147 if (!(sa
= SafeArrayCreateVector(VT_UNKNOWN
, 0, ARRAY_SIZE(uia_unk_arr_prop_val
))))
1150 for (idx
= 0; idx
< ARRAY_SIZE(uia_unk_arr_prop_val
); idx
++)
1151 SafeArrayPutElement(sa
, &idx
, (void *)uia_unk_arr_prop_val
[idx
]);
1157 PROV_GET_PROVIDER_OPTIONS
,
1158 PROV_GET_PROPERTY_VALUE
,
1159 PROV_GET_HOST_RAW_ELEMENT_PROVIDER
,
1163 static const char *prov_method_str
[] = {
1164 "get_ProviderOptions",
1166 "get_HostRawElementProvider",
1170 static const char *get_prov_method_str(int method
)
1172 if (method
>= ARRAY_SIZE(prov_method_str
))
1175 return prov_method_str
[method
];
1179 METHOD_OPTIONAL
= 0x01,
1183 struct prov_method_sequence
{
1184 struct Provider
*prov
;
1189 static int sequence_cnt
, sequence_size
;
1190 static struct prov_method_sequence
*sequence
;
1192 static void flush_method_sequence(void)
1194 HeapFree(GetProcessHeap(), 0, sequence
);
1196 sequence_cnt
= sequence_size
= 0;
1199 static void add_method_call(struct Provider
*prov
, int method
)
1201 struct prov_method_sequence prov_method
= {0};
1206 sequence
= HeapAlloc(GetProcessHeap(), 0, sequence_size
* sizeof(*sequence
));
1208 if (sequence_cnt
== sequence_size
)
1211 sequence
= HeapReAlloc(GetProcessHeap(), 0, sequence
, sequence_size
* sizeof(*sequence
));
1214 prov_method
.prov
= prov
;
1215 prov_method
.method
= method
;
1216 prov_method
.flags
= 0;
1217 sequence
[sequence_cnt
++] = prov_method
;
1220 #define ok_method_sequence( exp, context ) \
1221 ok_method_sequence_( (exp), (context), __FILE__, __LINE__)
1222 static void ok_method_sequence_(const struct prov_method_sequence
*expected_list
, const char *context
,
1223 const char *file
, int line
)
1225 const struct prov_method_sequence
*expected
= expected_list
;
1226 const struct prov_method_sequence
*actual
;
1227 unsigned int count
= 0;
1229 add_method_call(NULL
, 0);
1233 winetest_push_context("%s", context
);
1235 while (expected
->prov
&& actual
->prov
)
1237 if (expected
->prov
== actual
->prov
&& expected
->method
== actual
->method
)
1239 if (expected
->flags
& METHOD_TODO
)
1240 todo_wine
ok_(file
, line
)(1, "%d: expected %s_%s, got %s_%s\n", count
, expected
->prov
->prov_name
,
1241 get_prov_method_str(expected
->method
), actual
->prov
->prov_name
, get_prov_method_str(actual
->method
));
1245 else if (expected
->flags
& METHOD_TODO
)
1247 todo_wine
ok_(file
, line
)(0, "%d: expected %s_%s, got %s_%s\n", count
, expected
->prov
->prov_name
,
1248 get_prov_method_str(expected
->method
), actual
->prov
->prov_name
, get_prov_method_str(actual
->method
));
1251 else if (expected
->flags
& METHOD_OPTIONAL
)
1255 ok_(file
, line
)(0, "%d: expected %s_%s, got %s_%s\n", count
, expected
->prov
->prov_name
,
1256 get_prov_method_str(expected
->method
), actual
->prov
->prov_name
, get_prov_method_str(actual
->method
));
1263 /* Handle trailing optional/todo_wine methods. */
1264 while (expected
->prov
&& ((expected
->flags
& METHOD_OPTIONAL
) ||
1265 ((expected
->flags
& METHOD_TODO
) && !strcmp(winetest_platform
, "wine"))))
1267 if (expected
->flags
& METHOD_TODO
)
1268 todo_wine
ok_(file
, line
)(0, "%d: expected %s_%s\n", count
, expected
->prov
->prov_name
,
1269 get_prov_method_str(expected
->method
));
1274 if (expected
->prov
|| actual
->prov
)
1277 ok_( file
, line
)(0, "incomplete sequence: expected %s_%s, got nothing\n", expected
->prov
->prov_name
,
1278 get_prov_method_str(expected
->method
));
1280 ok_( file
, line
)(0, "incomplete sequence: expected nothing, got %s_%s\n", actual
->prov
->prov_name
,
1281 get_prov_method_str(actual
->method
));
1285 winetest_pop_context();
1287 flush_method_sequence();
1291 * Parsing the string returned by UIA_ProviderDescriptionPropertyId is
1292 * the only way to know what an HUIANODE represents internally. It
1293 * returns a formatted string which always starts with:
1294 * "[pid:<process-id>,providerId:0x<hwnd-ptr> "
1295 * On Windows versions 10v1507 and below, "providerId:" is "hwnd:"
1297 * This is followed by strings for each provider it represents. These are
1299 * "<prov-type>:<prov-desc> (<origin>)"
1300 * and are terminated with ";", the final provider has no ";" terminator,
1301 * instead it has "]".
1303 * If the given provider is the one used for navigation towards a parent, it has
1304 * "(parent link)" as a suffix on "<prov-type>".
1306 * <prov-type> is one of "Annotation", "Main", "Override", "Hwnd", or
1309 * <prov-desc> is the string returned from calling GetPropertyValue on the
1310 * IRawElementProviderSimple being represented with a property ID of
1311 * UIA_ProviderDescriptionPropertyId.
1313 * <origin> is the name of the module that the
1314 * IRawElementProviderSimple comes from. For unmanaged code, it's:
1315 * "unmanaged:<executable>"
1316 * and for managed code, it's:
1317 * "managed:<assembly-qualified-name>"
1320 * [pid:1500,providerId:0x2F054C Main:Provider (unmanaged:uiautomation_test.exe); Hwnd(parent link):HWND Proxy (unmanaged:uiautomationcore.dll)]
1322 static BOOL
get_provider_desc(BSTR prov_desc
, const WCHAR
*prov_type
, WCHAR
*out_name
)
1324 const WCHAR
*str
, *str2
;
1326 str
= wcsstr(prov_desc
, prov_type
);
1333 str
+= wcslen(prov_type
);
1334 str2
= wcschr(str
, L
'(');
1335 lstrcpynW(out_name
, str
, ((str2
- str
)));
1340 #define check_node_provider_desc( prov_desc, prov_type, prov_name, parent_link ) \
1341 check_node_provider_desc_( (prov_desc), (prov_type), (prov_name), (parent_link), __FILE__, __LINE__)
1342 static void check_node_provider_desc_(BSTR prov_desc
, const WCHAR
*prov_type
, const WCHAR
*prov_name
,
1343 BOOL parent_link
, const char *file
, int line
)
1348 wsprintfW(buf
, L
"%s(parent link):", prov_type
);
1350 wsprintfW(buf
, L
"%s:", prov_type
);
1352 if (!get_provider_desc(prov_desc
, buf
, buf
))
1355 wsprintfW(buf
, L
"%s:", prov_type
);
1357 wsprintfW(buf
, L
"%s(parent link):", prov_type
);
1359 if (!get_provider_desc(prov_desc
, buf
, buf
))
1361 ok_(file
, line
)(0, "failed to get provider string for %s\n", debugstr_w(prov_type
));
1367 ok_(file
, line
)(0, "expected parent link provider %s\n", debugstr_w(prov_type
));
1369 ok_(file
, line
)(0, "unexpected parent link provider %s\n", debugstr_w(prov_type
));
1374 ok_(file
, line
)(!wcscmp(prov_name
, buf
), "unexpected provider name %s\n", debugstr_w(buf
));
1377 #define check_node_provider_desc_prefix( prov_desc, pid, prov_id ) \
1378 check_node_provider_desc_prefix_( (prov_desc), (pid), (prov_id), __FILE__, __LINE__)
1379 static void check_node_provider_desc_prefix_(BSTR prov_desc
, DWORD pid
, HWND prov_id
, const char *file
, int line
)
1381 const WCHAR
*str
, *str2
;
1387 str
= wcsstr(prov_desc
, L
"pid:");
1388 str
+= wcslen(L
"pid:");
1389 str2
= wcschr(str
, L
',');
1390 lstrcpynW(buf
, str
, (str2
- str
) + 1);
1391 prov_pid
= wcstoul(buf
, &end
, 10);
1392 ok_(file
, line
)(prov_pid
== pid
, "Unexpected pid %lu\n", prov_pid
);
1394 str
= wcsstr(prov_desc
, L
"providerId:");
1396 str
+= wcslen(L
"providerId:");
1399 str
= wcsstr(prov_desc
, L
"hwnd:");
1400 str
+= wcslen(L
"hwnd:");
1402 str2
= wcschr(str
, L
' ');
1403 lstrcpynW(buf
, str
, (str2
- str
) + 1);
1404 prov_hwnd
= ULongToHandle(wcstoul(buf
, &end
, 16));
1405 ok_(file
, line
)(prov_hwnd
== prov_id
, "Unexpected hwnd %p\n", prov_hwnd
);
1408 static inline struct Provider
*impl_from_ProviderSimple(IRawElementProviderSimple
*iface
)
1410 return CONTAINING_RECORD(iface
, struct Provider
, IRawElementProviderSimple_iface
);
1413 HRESULT WINAPI
ProviderSimple_QueryInterface(IRawElementProviderSimple
*iface
, REFIID riid
, void **ppv
)
1415 struct Provider
*This
= impl_from_ProviderSimple(iface
);
1418 if (IsEqualIID(riid
, &IID_IRawElementProviderSimple
) || IsEqualIID(riid
, &IID_IUnknown
))
1420 else if (IsEqualIID(riid
, &IID_IRawElementProviderFragment
))
1421 *ppv
= &This
->IRawElementProviderFragment_iface
;
1423 return E_NOINTERFACE
;
1425 IRawElementProviderSimple_AddRef(iface
);
1429 ULONG WINAPI
ProviderSimple_AddRef(IRawElementProviderSimple
*iface
)
1431 struct Provider
*This
= impl_from_ProviderSimple(iface
);
1432 return InterlockedIncrement(&This
->ref
);
1435 ULONG WINAPI
ProviderSimple_Release(IRawElementProviderSimple
*iface
)
1437 struct Provider
*This
= impl_from_ProviderSimple(iface
);
1438 return InterlockedDecrement(&This
->ref
);
1441 HRESULT WINAPI
ProviderSimple_get_ProviderOptions(IRawElementProviderSimple
*iface
,
1442 enum ProviderOptions
*ret_val
)
1444 struct Provider
*This
= impl_from_ProviderSimple(iface
);
1446 add_method_call(This
, PROV_GET_PROVIDER_OPTIONS
);
1447 if (This
->expected_tid
)
1448 ok(This
->expected_tid
== GetCurrentThreadId(), "Unexpected tid %ld\n", GetCurrentThreadId());
1451 if (This
->prov_opts
)
1453 *ret_val
= This
->prov_opts
;
1460 HRESULT WINAPI
ProviderSimple_GetPatternProvider(IRawElementProviderSimple
*iface
,
1461 PATTERNID pattern_id
, IUnknown
**ret_val
)
1463 ok(0, "unexpected call\n");
1467 HRESULT WINAPI
ProviderSimple_GetPropertyValue(IRawElementProviderSimple
*iface
,
1468 PROPERTYID prop_id
, VARIANT
*ret_val
)
1470 struct Provider
*This
= impl_from_ProviderSimple(iface
);
1472 add_method_call(This
, PROV_GET_PROPERTY_VALUE
);
1473 if (This
->expected_tid
)
1474 ok(This
->expected_tid
== GetCurrentThreadId(), "Unexpected tid %ld\n", GetCurrentThreadId());
1476 VariantInit(ret_val
);
1479 case UIA_NativeWindowHandlePropertyId
:
1480 if (This
->ret_invalid_prop_type
)
1482 V_VT(ret_val
) = VT_R8
;
1483 V_R8(ret_val
) = uia_r8_prop_val
;
1487 V_VT(ret_val
) = VT_I4
;
1488 V_I4(ret_val
) = HandleToULong(This
->hwnd
);
1492 case UIA_ProcessIdPropertyId
:
1493 case UIA_ControlTypePropertyId
:
1494 case UIA_CulturePropertyId
:
1495 case UIA_OrientationPropertyId
:
1496 case UIA_LiveSettingPropertyId
:
1497 case UIA_PositionInSetPropertyId
:
1498 case UIA_SizeOfSetPropertyId
:
1499 case UIA_LevelPropertyId
:
1500 case UIA_LandmarkTypePropertyId
:
1501 case UIA_FillColorPropertyId
:
1502 case UIA_FillTypePropertyId
:
1503 case UIA_VisualEffectsPropertyId
:
1504 case UIA_HeadingLevelPropertyId
:
1505 if (This
->ret_invalid_prop_type
)
1507 V_VT(ret_val
) = VT_R8
;
1508 V_R8(ret_val
) = uia_r8_prop_val
;
1512 V_VT(ret_val
) = VT_I4
;
1513 V_I4(ret_val
) = uia_i4_prop_val
;
1517 case UIA_RotationPropertyId
:
1518 if (This
->ret_invalid_prop_type
)
1520 V_VT(ret_val
) = VT_I4
;
1521 V_I4(ret_val
) = uia_i4_prop_val
;
1525 V_VT(ret_val
) = VT_R8
;
1526 V_R8(ret_val
) = uia_r8_prop_val
;
1530 case UIA_LocalizedControlTypePropertyId
:
1531 case UIA_NamePropertyId
:
1532 case UIA_AcceleratorKeyPropertyId
:
1533 case UIA_AccessKeyPropertyId
:
1534 case UIA_AutomationIdPropertyId
:
1535 case UIA_ClassNamePropertyId
:
1536 case UIA_HelpTextPropertyId
:
1537 case UIA_ItemTypePropertyId
:
1538 case UIA_FrameworkIdPropertyId
:
1539 case UIA_ItemStatusPropertyId
:
1540 case UIA_AriaRolePropertyId
:
1541 case UIA_AriaPropertiesPropertyId
:
1542 case UIA_LocalizedLandmarkTypePropertyId
:
1543 case UIA_FullDescriptionPropertyId
:
1544 if (This
->ret_invalid_prop_type
)
1546 V_VT(ret_val
) = VT_I4
;
1547 V_I4(ret_val
) = uia_i4_prop_val
;
1551 V_VT(ret_val
) = VT_BSTR
;
1552 V_BSTR(ret_val
) = SysAllocString(uia_bstr_prop_str
);
1556 case UIA_HasKeyboardFocusPropertyId
:
1557 case UIA_IsKeyboardFocusablePropertyId
:
1558 case UIA_IsEnabledPropertyId
:
1559 case UIA_IsControlElementPropertyId
:
1560 case UIA_IsContentElementPropertyId
:
1561 case UIA_IsPasswordPropertyId
:
1562 case UIA_IsOffscreenPropertyId
:
1563 case UIA_IsRequiredForFormPropertyId
:
1564 case UIA_IsDataValidForFormPropertyId
:
1565 case UIA_OptimizeForVisualContentPropertyId
:
1566 case UIA_IsPeripheralPropertyId
:
1567 case UIA_IsDialogPropertyId
:
1568 if (This
->ret_invalid_prop_type
)
1570 V_VT(ret_val
) = VT_R8
;
1571 V_R8(ret_val
) = uia_r8_prop_val
;
1575 V_VT(ret_val
) = VT_BOOL
;
1576 V_BOOL(ret_val
) = VARIANT_TRUE
;
1580 case UIA_AnnotationTypesPropertyId
:
1581 case UIA_OutlineColorPropertyId
:
1582 if (This
->ret_invalid_prop_type
)
1584 V_VT(ret_val
) = VT_ARRAY
| VT_R8
;
1585 V_ARRAY(ret_val
) = create_r8_safearray();
1589 V_VT(ret_val
) = VT_ARRAY
| VT_I4
;
1590 V_ARRAY(ret_val
) = create_i4_safearray();
1594 case UIA_OutlineThicknessPropertyId
:
1595 case UIA_SizePropertyId
:
1596 if (This
->ret_invalid_prop_type
)
1598 V_VT(ret_val
) = VT_ARRAY
| VT_I4
;
1599 V_ARRAY(ret_val
) = create_i4_safearray();
1603 V_VT(ret_val
) = VT_ARRAY
| VT_R8
;
1604 V_ARRAY(ret_val
) = create_r8_safearray();
1608 case UIA_LabeledByPropertyId
:
1609 if (This
->ret_invalid_prop_type
)
1611 V_VT(ret_val
) = VT_I4
;
1612 V_I4(ret_val
) = uia_i4_prop_val
;
1616 V_VT(ret_val
) = VT_UNKNOWN
;
1617 V_UNKNOWN(ret_val
) = (IUnknown
*)&Provider_child
.IRawElementProviderSimple_iface
;
1618 IUnknown_AddRef(V_UNKNOWN(ret_val
));
1622 case UIA_AnnotationObjectsPropertyId
:
1623 case UIA_DescribedByPropertyId
:
1624 case UIA_FlowsFromPropertyId
:
1625 case UIA_FlowsToPropertyId
:
1626 case UIA_ControllerForPropertyId
:
1627 if (This
->ret_invalid_prop_type
)
1629 V_VT(ret_val
) = VT_ARRAY
| VT_I4
;
1630 V_ARRAY(ret_val
) = create_i4_safearray();
1634 V_VT(ret_val
) = VT_UNKNOWN
| VT_ARRAY
;
1635 V_ARRAY(ret_val
) = create_unk_safearray();
1639 case UIA_ProviderDescriptionPropertyId
:
1641 WCHAR buf
[1024] = {};
1643 mbstowcs(buf
, This
->prov_name
, strlen(This
->prov_name
));
1644 V_VT(ret_val
) = VT_BSTR
;
1645 V_BSTR(ret_val
) = SysAllocString(buf
);
1656 HRESULT WINAPI
ProviderSimple_get_HostRawElementProvider(IRawElementProviderSimple
*iface
,
1657 IRawElementProviderSimple
**ret_val
)
1659 struct Provider
*This
= impl_from_ProviderSimple(iface
);
1661 add_method_call(This
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
);
1662 if (This
->expected_tid
)
1663 ok(This
->expected_tid
== GetCurrentThreadId(), "Unexpected tid %ld\n", GetCurrentThreadId());
1667 return UiaHostProviderFromHwnd(This
->hwnd
, ret_val
);
1672 IRawElementProviderSimpleVtbl ProviderSimpleVtbl
= {
1673 ProviderSimple_QueryInterface
,
1674 ProviderSimple_AddRef
,
1675 ProviderSimple_Release
,
1676 ProviderSimple_get_ProviderOptions
,
1677 ProviderSimple_GetPatternProvider
,
1678 ProviderSimple_GetPropertyValue
,
1679 ProviderSimple_get_HostRawElementProvider
,
1682 static inline struct Provider
*impl_from_ProviderFragment(IRawElementProviderFragment
*iface
)
1684 return CONTAINING_RECORD(iface
, struct Provider
, IRawElementProviderFragment_iface
);
1687 static HRESULT WINAPI
ProviderFragment_QueryInterface(IRawElementProviderFragment
*iface
, REFIID riid
,
1690 struct Provider
*Provider
= impl_from_ProviderFragment(iface
);
1691 return IRawElementProviderSimple_QueryInterface(&Provider
->IRawElementProviderSimple_iface
, riid
, ppv
);
1694 static ULONG WINAPI
ProviderFragment_AddRef(IRawElementProviderFragment
*iface
)
1696 struct Provider
*Provider
= impl_from_ProviderFragment(iface
);
1697 return IRawElementProviderSimple_AddRef(&Provider
->IRawElementProviderSimple_iface
);
1700 static ULONG WINAPI
ProviderFragment_Release(IRawElementProviderFragment
*iface
)
1702 struct Provider
*Provider
= impl_from_ProviderFragment(iface
);
1703 return IRawElementProviderSimple_Release(&Provider
->IRawElementProviderSimple_iface
);
1706 static HRESULT WINAPI
ProviderFragment_Navigate(IRawElementProviderFragment
*iface
,
1707 enum NavigateDirection direction
, IRawElementProviderFragment
**ret_val
)
1709 struct Provider
*This
= impl_from_ProviderFragment(iface
);
1711 add_method_call(This
, FRAG_NAVIGATE
);
1712 if (This
->expected_tid
)
1713 ok(This
->expected_tid
== GetCurrentThreadId(), "Unexpected tid %ld\n", GetCurrentThreadId());
1716 if ((direction
== NavigateDirection_Parent
) && This
->parent
)
1718 *ret_val
= This
->parent
;
1719 IRawElementProviderFragment_AddRef(This
->parent
);
1724 static HRESULT WINAPI
ProviderFragment_GetRuntimeId(IRawElementProviderFragment
*iface
,
1725 SAFEARRAY
**ret_val
)
1727 ok(0, "unexpected call\n");
1732 static HRESULT WINAPI
ProviderFragment_get_BoundingRectangle(IRawElementProviderFragment
*iface
,
1733 struct UiaRect
*ret_val
)
1735 ok(0, "unexpected call\n");
1739 static HRESULT WINAPI
ProviderFragment_GetEmbeddedFragmentRoots(IRawElementProviderFragment
*iface
,
1740 SAFEARRAY
**ret_val
)
1742 ok(0, "unexpected call\n");
1747 static HRESULT WINAPI
ProviderFragment_SetFocus(IRawElementProviderFragment
*iface
)
1749 ok(0, "unexpected call\n");
1753 static HRESULT WINAPI
ProviderFragment_get_FragmentRoot(IRawElementProviderFragment
*iface
,
1754 IRawElementProviderFragmentRoot
**ret_val
)
1756 ok(0, "unexpected call\n");
1761 static const IRawElementProviderFragmentVtbl ProviderFragmentVtbl
= {
1762 ProviderFragment_QueryInterface
,
1763 ProviderFragment_AddRef
,
1764 ProviderFragment_Release
,
1765 ProviderFragment_Navigate
,
1766 ProviderFragment_GetRuntimeId
,
1767 ProviderFragment_get_BoundingRectangle
,
1768 ProviderFragment_GetEmbeddedFragmentRoots
,
1769 ProviderFragment_SetFocus
,
1770 ProviderFragment_get_FragmentRoot
,
1773 static struct Provider Provider
=
1775 { &ProviderSimpleVtbl
},
1776 { &ProviderFragmentVtbl
},
1783 static struct Provider Provider2
=
1785 { &ProviderSimpleVtbl
},
1786 { &ProviderFragmentVtbl
},
1793 static struct Provider Provider_child
=
1795 { &ProviderSimpleVtbl
},
1796 { &ProviderFragmentVtbl
},
1799 &Provider
.IRawElementProviderFragment_iface
,
1800 ProviderOptions_ServerSideProvider
, 0, 0,
1803 static struct Provider Provider_child2
=
1805 { &ProviderSimpleVtbl
},
1806 { &ProviderFragmentVtbl
},
1809 &Provider
.IRawElementProviderFragment_iface
,
1810 ProviderOptions_ServerSideProvider
, 0, 0,
1813 static IAccessible
*acc_client
;
1814 static IRawElementProviderSimple
*prov_root
;
1815 static LRESULT WINAPI
test_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1820 if (lParam
== (DWORD
)OBJID_CLIENT
)
1822 CHECK_EXPECT(winproc_GETOBJECT_CLIENT
);
1824 return LresultFromObject(&IID_IAccessible
, wParam
, (IUnknown
*)acc_client
);
1828 else if (lParam
== UiaRootObjectId
)
1830 CHECK_EXPECT(winproc_GETOBJECT_UiaRoot
);
1832 return UiaReturnRawElementProvider(hwnd
, wParam
, lParam
, prov_root
);
1843 return DefWindowProcA(hwnd
, message
, wParam
, lParam
);
1846 static void test_UiaHostProviderFromHwnd(void)
1848 IRawElementProviderSimple
*p
, *p2
;
1849 enum ProviderOptions prov_opt
;
1857 cls
.lpfnWndProc
= test_wnd_proc
;
1860 cls
.hInstance
= GetModuleHandleA(NULL
);
1863 cls
.hbrBackground
= NULL
;
1864 cls
.lpszMenuName
= NULL
;
1865 cls
.lpszClassName
= "HostProviderFromHwnd class";
1867 RegisterClassA(&cls
);
1869 hwnd
= CreateWindowExA(0, "HostProviderFromHwnd class", "Test window 1",
1870 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
| WS_MAXIMIZEBOX
| WS_VISIBLE
,
1871 0, 0, 100, 100, GetDesktopWindow(), NULL
, GetModuleHandleA(NULL
), NULL
);
1872 ok(hwnd
!= NULL
, "Failed to create a test window.\n");
1874 p
= (void *)0xdeadbeef;
1875 hr
= UiaHostProviderFromHwnd(NULL
, &p
);
1876 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1877 ok(p
== NULL
, "Unexpected instance.\n");
1879 hr
= UiaHostProviderFromHwnd(hwnd
, NULL
);
1880 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1883 hr
= UiaHostProviderFromHwnd(hwnd
, &p
);
1884 ok(hr
== S_OK
, "Failed to get host provider, hr %#lx.\n", hr
);
1887 hr
= UiaHostProviderFromHwnd(hwnd
, &p2
);
1888 ok(hr
== S_OK
, "Failed to get host provider, hr %#lx.\n", hr
);
1889 ok(p
!= p2
, "Unexpected instance.\n");
1890 IRawElementProviderSimple_Release(p2
);
1892 hr
= IRawElementProviderSimple_get_HostRawElementProvider(p
, &p2
);
1893 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1894 ok(p2
== NULL
, "Unexpected instance.\n");
1896 hr
= IRawElementProviderSimple_GetPropertyValue(p
, UIA_NativeWindowHandlePropertyId
, &v
);
1897 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1898 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
1899 ok(V_I4(&v
) == HandleToUlong(hwnd
), "V_I4(&v) = %#lx, expected %#lx\n", V_I4(&v
), HandleToUlong(hwnd
));
1901 hr
= IRawElementProviderSimple_GetPropertyValue(p
, UIA_ProviderDescriptionPropertyId
, &v
);
1902 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1903 ok(V_VT(&v
) == VT_BSTR
, "V_VT(&v) = %d\n", V_VT(&v
));
1906 /* No patterns are implemented on the HWND Host provider. */
1907 for (i
= UIA_InvokePatternId
; i
< (UIA_CustomNavigationPatternId
+ 1); i
++)
1911 unk
= (void *)0xdeadbeef;
1912 hr
= IRawElementProviderSimple_GetPatternProvider(p
, i
, &unk
);
1913 ok(hr
== S_OK
, "Unexpected hr %#lx, %d.\n", hr
, i
);
1914 ok(!unk
, "Pattern %d returned %p\n", i
, unk
);
1917 hr
= IRawElementProviderSimple_get_ProviderOptions(p
, &prov_opt
);
1918 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1919 ok((prov_opt
== ProviderOptions_ServerSideProvider
) ||
1920 broken(prov_opt
== ProviderOptions_ClientSideProvider
), /* Windows < 10 1507 */
1921 "Unexpected provider options %#x\n", prov_opt
);
1923 /* Test behavior post Window destruction. */
1924 DestroyWindow(hwnd
);
1926 hr
= IRawElementProviderSimple_GetPropertyValue(p
, UIA_NativeWindowHandlePropertyId
, &v
);
1927 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1928 ok(V_VT(&v
) == VT_I4
, "V_VT(&v) = %d\n", V_VT(&v
));
1929 ok(V_I4(&v
) == HandleToUlong(hwnd
), "V_I4(&v) = %#lx, expected %#lx\n", V_I4(&v
), HandleToUlong(hwnd
));
1931 hr
= IRawElementProviderSimple_GetPropertyValue(p
, UIA_ProviderDescriptionPropertyId
, &v
);
1932 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1933 ok(V_VT(&v
) == VT_BSTR
, "V_VT(&v) = %d\n", V_VT(&v
));
1936 hr
= IRawElementProviderSimple_get_ProviderOptions(p
, &prov_opt
);
1937 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1938 ok((prov_opt
== ProviderOptions_ServerSideProvider
) ||
1939 broken(prov_opt
== ProviderOptions_ClientSideProvider
), /* Windows < 10 1507 */
1940 "Unexpected provider options %#x\n", prov_opt
);
1942 IRawElementProviderSimple_Release(p
);
1944 UnregisterClassA("HostProviderFromHwnd class", NULL
);
1947 static DWORD WINAPI
uia_reserved_val_iface_marshal_thread(LPVOID param
)
1949 IStream
**stream
= param
;
1950 IUnknown
*unk_ns
, *unk_ns2
, *unk_ma
, *unk_ma2
;
1953 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
1955 hr
= CoGetInterfaceAndReleaseStream(stream
[0], &IID_IUnknown
, (void **)&unk_ns
);
1956 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1958 hr
= CoGetInterfaceAndReleaseStream(stream
[1], &IID_IUnknown
, (void **)&unk_ma
);
1959 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1961 hr
= UiaGetReservedNotSupportedValue(&unk_ns2
);
1962 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1964 hr
= UiaGetReservedMixedAttributeValue(&unk_ma2
);
1965 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1967 ok(unk_ns2
== unk_ns
, "UiaGetReservedNotSupported pointer mismatch, unk_ns2 %p, unk_ns %p\n", unk_ns2
, unk_ns
);
1968 ok(unk_ma2
== unk_ma
, "UiaGetReservedMixedAttribute pointer mismatch, unk_ma2 %p, unk_ma %p\n", unk_ma2
, unk_ma
);
1975 static void test_uia_reserved_value_ifaces(void)
1977 IUnknown
*unk_ns
, *unk_ns2
, *unk_ma
, *unk_ma2
;
1984 /* ReservedNotSupportedValue. */
1985 hr
= UiaGetReservedNotSupportedValue(NULL
);
1986 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1988 hr
= UiaGetReservedNotSupportedValue(&unk_ns
);
1989 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1990 ok(unk_ns
!= NULL
, "UiaGetReservedNotSupportedValue returned NULL interface.\n");
1992 refcnt
= IUnknown_AddRef(unk_ns
);
1993 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
1995 refcnt
= IUnknown_AddRef(unk_ns
);
1996 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
1998 refcnt
= IUnknown_Release(unk_ns
);
1999 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
2001 hr
= UiaGetReservedNotSupportedValue(&unk_ns2
);
2002 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2003 ok(unk_ns2
!= NULL
, "UiaGetReservedNotSupportedValue returned NULL interface.");
2004 ok(unk_ns2
== unk_ns
, "UiaGetReservedNotSupported pointer mismatch, unk_ns2 %p, unk_ns %p\n", unk_ns2
, unk_ns
);
2007 hr
= IUnknown_QueryInterface(unk_ns
, &IID_IMarshal
, (void **)&marshal
);
2008 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2009 ok(marshal
!= NULL
, "Failed to get IMarshal interface.\n");
2011 refcnt
= IMarshal_AddRef(marshal
);
2012 ok(refcnt
== 2, "Expected refcnt %d, got %ld\n", 2, refcnt
);
2014 refcnt
= IMarshal_Release(marshal
);
2015 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
2017 refcnt
= IMarshal_Release(marshal
);
2018 ok(refcnt
== 0, "Expected refcnt %d, got %ld\n", 0, refcnt
);
2020 /* ReservedMixedAttributeValue. */
2021 hr
= UiaGetReservedMixedAttributeValue(NULL
);
2022 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2024 hr
= UiaGetReservedMixedAttributeValue(&unk_ma
);
2025 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2026 ok(unk_ma
!= NULL
, "UiaGetReservedMixedAttributeValue returned NULL interface.");
2028 refcnt
= IUnknown_AddRef(unk_ma
);
2029 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
2031 refcnt
= IUnknown_AddRef(unk_ma
);
2032 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
2034 refcnt
= IUnknown_Release(unk_ma
);
2035 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
2037 hr
= UiaGetReservedMixedAttributeValue(&unk_ma2
);
2038 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2039 ok(unk_ma2
!= NULL
, "UiaGetReservedMixedAttributeValue returned NULL interface.");
2040 ok(unk_ma2
== unk_ma
, "UiaGetReservedMixedAttribute pointer mismatch, unk_ma2 %p, unk_ma %p\n", unk_ma2
, unk_ma
);
2043 hr
= IUnknown_QueryInterface(unk_ma
, &IID_IMarshal
, (void **)&marshal
);
2044 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2045 ok(marshal
!= NULL
, "Failed to get IMarshal interface.\n");
2047 refcnt
= IMarshal_AddRef(marshal
);
2048 ok(refcnt
== 2, "Expected refcnt %d, got %ld\n", 2, refcnt
);
2050 refcnt
= IMarshal_Release(marshal
);
2051 ok(refcnt
== 1, "Expected refcnt %d, got %ld\n", 1, refcnt
);
2053 refcnt
= IMarshal_Release(marshal
);
2054 ok(refcnt
== 0, "Expected refcnt %d, got %ld\n", 0, refcnt
);
2056 /* Test cross-thread marshaling behavior. */
2057 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
2059 hr
= CoMarshalInterThreadInterfaceInStream(&IID_IUnknown
, unk_ns
, &stream
[0]);
2060 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2061 hr
= CoMarshalInterThreadInterfaceInStream(&IID_IUnknown
, unk_ma
, &stream
[1]);
2062 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2064 thread
= CreateThread(NULL
, 0, uia_reserved_val_iface_marshal_thread
, (void *)stream
, 0, NULL
);
2065 while (MsgWaitForMultipleObjects(1, &thread
, FALSE
, INFINITE
, QS_ALLINPUT
) != WAIT_OBJECT_0
)
2068 while(PeekMessageW(&msg
, 0, 0, 0, PM_REMOVE
))
2070 TranslateMessage(&msg
);
2071 DispatchMessageW(&msg
);
2074 CloseHandle(thread
);
2079 struct msaa_role_uia_type
{
2081 INT uia_control_type
;
2084 static const struct msaa_role_uia_type msaa_role_uia_types
[] = {
2085 { ROLE_SYSTEM_TITLEBAR
, UIA_TitleBarControlTypeId
},
2086 { ROLE_SYSTEM_MENUBAR
, UIA_MenuBarControlTypeId
},
2087 { ROLE_SYSTEM_SCROLLBAR
, UIA_ScrollBarControlTypeId
},
2088 { ROLE_SYSTEM_GRIP
, UIA_ThumbControlTypeId
},
2089 { ROLE_SYSTEM_WINDOW
, UIA_WindowControlTypeId
},
2090 { ROLE_SYSTEM_MENUPOPUP
, UIA_MenuControlTypeId
},
2091 { ROLE_SYSTEM_MENUITEM
, UIA_MenuItemControlTypeId
},
2092 { ROLE_SYSTEM_TOOLTIP
, UIA_ToolTipControlTypeId
},
2093 { ROLE_SYSTEM_APPLICATION
, UIA_WindowControlTypeId
},
2094 { ROLE_SYSTEM_DOCUMENT
, UIA_DocumentControlTypeId
},
2095 { ROLE_SYSTEM_PANE
, UIA_PaneControlTypeId
},
2096 { ROLE_SYSTEM_GROUPING
, UIA_GroupControlTypeId
},
2097 { ROLE_SYSTEM_SEPARATOR
, UIA_SeparatorControlTypeId
},
2098 { ROLE_SYSTEM_TOOLBAR
, UIA_ToolBarControlTypeId
},
2099 { ROLE_SYSTEM_STATUSBAR
, UIA_StatusBarControlTypeId
},
2100 { ROLE_SYSTEM_TABLE
, UIA_TableControlTypeId
},
2101 { ROLE_SYSTEM_COLUMNHEADER
, UIA_HeaderControlTypeId
},
2102 { ROLE_SYSTEM_ROWHEADER
, UIA_HeaderControlTypeId
},
2103 { ROLE_SYSTEM_CELL
, UIA_DataItemControlTypeId
},
2104 { ROLE_SYSTEM_LINK
, UIA_HyperlinkControlTypeId
},
2105 { ROLE_SYSTEM_LIST
, UIA_ListControlTypeId
},
2106 { ROLE_SYSTEM_LISTITEM
, UIA_ListItemControlTypeId
},
2107 { ROLE_SYSTEM_OUTLINE
, UIA_TreeControlTypeId
},
2108 { ROLE_SYSTEM_OUTLINEITEM
, UIA_TreeItemControlTypeId
},
2109 { ROLE_SYSTEM_PAGETAB
, UIA_TabItemControlTypeId
},
2110 { ROLE_SYSTEM_INDICATOR
, UIA_ThumbControlTypeId
},
2111 { ROLE_SYSTEM_GRAPHIC
, UIA_ImageControlTypeId
},
2112 { ROLE_SYSTEM_STATICTEXT
, UIA_TextControlTypeId
},
2113 { ROLE_SYSTEM_TEXT
, UIA_EditControlTypeId
},
2114 { ROLE_SYSTEM_PUSHBUTTON
, UIA_ButtonControlTypeId
},
2115 { ROLE_SYSTEM_CHECKBUTTON
, UIA_CheckBoxControlTypeId
},
2116 { ROLE_SYSTEM_RADIOBUTTON
, UIA_RadioButtonControlTypeId
},
2117 { ROLE_SYSTEM_COMBOBOX
, UIA_ComboBoxControlTypeId
},
2118 { ROLE_SYSTEM_PROGRESSBAR
, UIA_ProgressBarControlTypeId
},
2119 { ROLE_SYSTEM_SLIDER
, UIA_SliderControlTypeId
},
2120 { ROLE_SYSTEM_SPINBUTTON
, UIA_SpinnerControlTypeId
},
2121 { ROLE_SYSTEM_BUTTONDROPDOWN
, UIA_SplitButtonControlTypeId
},
2122 { ROLE_SYSTEM_BUTTONMENU
, UIA_MenuItemControlTypeId
},
2123 { ROLE_SYSTEM_BUTTONDROPDOWNGRID
, UIA_ButtonControlTypeId
},
2124 { ROLE_SYSTEM_PAGETABLIST
, UIA_TabControlTypeId
},
2125 { ROLE_SYSTEM_SPLITBUTTON
, UIA_SplitButtonControlTypeId
},
2126 /* These accessible roles have no equivalent in UI Automation. */
2127 { ROLE_SYSTEM_SOUND
, 0 },
2128 { ROLE_SYSTEM_CURSOR
, 0 },
2129 { ROLE_SYSTEM_CARET
, 0 },
2130 { ROLE_SYSTEM_ALERT
, 0 },
2131 { ROLE_SYSTEM_CLIENT
, 0 },
2132 { ROLE_SYSTEM_CHART
, 0 },
2133 { ROLE_SYSTEM_DIALOG
, 0 },
2134 { ROLE_SYSTEM_BORDER
, 0 },
2135 { ROLE_SYSTEM_COLUMN
, 0 },
2136 { ROLE_SYSTEM_ROW
, 0 },
2137 { ROLE_SYSTEM_HELPBALLOON
, 0 },
2138 { ROLE_SYSTEM_CHARACTER
, 0 },
2139 { ROLE_SYSTEM_PROPERTYPAGE
, 0 },
2140 { ROLE_SYSTEM_DROPLIST
, 0 },
2141 { ROLE_SYSTEM_DIAL
, 0 },
2142 { ROLE_SYSTEM_HOTKEYFIELD
, 0 },
2143 { ROLE_SYSTEM_DIAGRAM
, 0 },
2144 { ROLE_SYSTEM_ANIMATION
, 0 },
2145 { ROLE_SYSTEM_EQUATION
, 0 },
2146 { ROLE_SYSTEM_WHITESPACE
, 0 },
2147 { ROLE_SYSTEM_IPADDRESS
, 0 },
2148 { ROLE_SYSTEM_OUTLINEBUTTON
, 0 },
2151 struct msaa_state_uia_prop
{
2156 static const struct msaa_state_uia_prop msaa_state_uia_props
[] = {
2157 { STATE_SYSTEM_FOCUSED
, UIA_HasKeyboardFocusPropertyId
},
2158 { STATE_SYSTEM_FOCUSABLE
, UIA_IsKeyboardFocusablePropertyId
},
2159 { ~STATE_SYSTEM_UNAVAILABLE
, UIA_IsEnabledPropertyId
},
2160 { STATE_SYSTEM_PROTECTED
, UIA_IsPasswordPropertyId
},
2163 static void set_accessible_props(struct Accessible
*acc
, INT role
, INT state
,
2164 LONG child_count
, LPCWSTR name
, LONG left
, LONG top
, LONG width
, LONG height
)
2169 acc
->child_count
= child_count
;
2174 acc
->height
= height
;
2177 static void set_accessible_ia2_props(struct Accessible
*acc
, BOOL enable_ia2
, LONG unique_id
)
2179 acc
->enable_ia2
= enable_ia2
;
2180 acc
->unique_id
= unique_id
;
2183 static void test_uia_prov_from_acc_ia2(void)
2185 IRawElementProviderSimple
*elprov
, *elprov2
;
2188 /* Only one exposes an IA2 interface, no match. */
2189 set_accessible_props(&Accessible
, 0, 0, 0, L
"acc_name", 0, 0, 0, 0);
2190 set_accessible_ia2_props(&Accessible
, TRUE
, 0);
2191 set_accessible_props(&Accessible2
, 0, 0, 0, L
"acc_name", 0, 0, 0, 0);
2192 set_accessible_ia2_props(&Accessible2
, FALSE
, 0);
2194 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2195 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2196 if (Accessible
.ref
!= 3)
2198 IRawElementProviderSimple_Release(elprov
);
2199 win_skip("UiaProviderFromIAccessible has no IAccessible2 support, skipping tests.\n");
2203 acc_client
= &Accessible2
.IAccessible_iface
;
2204 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2205 elprov2
= (void *)0xdeadbeef;
2206 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2207 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2208 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
2209 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
2210 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
2212 elprov2
= (void *)0xdeadbeef;
2214 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2215 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2216 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
2218 IRawElementProviderSimple_Release(elprov
);
2219 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2222 * If &Accessible returns a failure code on get_uniqueID, &Accessible2's
2223 * uniqueID is not checked.
2225 set_accessible_ia2_props(&Accessible
, TRUE
, 0);
2226 set_accessible_ia2_props(&Accessible2
, TRUE
, 0);
2227 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2228 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2229 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2231 acc_client
= &Accessible2
.IAccessible_iface
;
2232 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2233 SET_EXPECT(Accessible_get_accRole
);
2234 SET_EXPECT(Accessible_get_accState
);
2235 SET_EXPECT(Accessible_get_accChildCount
);
2236 SET_EXPECT(Accessible_accLocation
);
2237 SET_EXPECT(Accessible_get_accName
);
2238 SET_EXPECT(Accessible_get_uniqueID
);
2239 SET_EXPECT(Accessible2_get_accChildCount
);
2240 SET_EXPECT(Accessible2_get_accName
);
2241 SET_EXPECT(Accessible2_QI_IAccIdentity
);
2242 SET_EXPECT(Accessible2_get_accParent
);
2243 elprov2
= (void *)0xdeadbeef;
2244 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2245 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2246 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
2247 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
2248 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
2249 CHECK_CALLED(Accessible_get_accRole
);
2250 CHECK_CALLED(Accessible_get_accState
);
2251 CHECK_CALLED(Accessible_get_accChildCount
);
2252 CHECK_CALLED(Accessible_accLocation
);
2253 CHECK_CALLED(Accessible_get_accName
);
2254 CHECK_CALLED(Accessible_get_uniqueID
);
2255 CHECK_CALLED(Accessible2_get_accChildCount
);
2256 CHECK_CALLED(Accessible2_get_accName
);
2257 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
2258 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
2259 IRawElementProviderSimple_Release(elprov2
);
2261 elprov2
= (void *)0xdeadbeef;
2263 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2264 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2265 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
2266 IRawElementProviderSimple_Release(elprov2
);
2268 IRawElementProviderSimple_Release(elprov
);
2269 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2271 /* Unique ID matches. */
2272 set_accessible_ia2_props(&Accessible
, TRUE
, 1);
2273 set_accessible_ia2_props(&Accessible2
, TRUE
, 1);
2274 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2275 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2276 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2278 acc_client
= &Accessible2
.IAccessible_iface
;
2279 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2280 SET_EXPECT(Accessible_get_uniqueID
);
2281 SET_EXPECT(Accessible2_get_uniqueID
);
2282 elprov2
= (void *)0xdeadbeef;
2283 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2284 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2285 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
2286 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
2287 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
2288 CHECK_CALLED(Accessible_get_uniqueID
);
2289 CHECK_CALLED(Accessible2_get_uniqueID
);
2290 IRawElementProviderSimple_Release(elprov2
);
2292 elprov2
= (void *)0xdeadbeef;
2294 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2295 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2296 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
2297 IRawElementProviderSimple_Release(elprov2
);
2299 IRawElementProviderSimple_Release(elprov
);
2300 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2302 /* Unique ID mismatch. */
2303 set_accessible_ia2_props(&Accessible
, TRUE
, 1);
2304 set_accessible_ia2_props(&Accessible2
, TRUE
, 2);
2305 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2306 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2307 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2309 acc_client
= &Accessible2
.IAccessible_iface
;
2310 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2311 SET_EXPECT(Accessible_get_uniqueID
);
2312 SET_EXPECT(Accessible2_get_uniqueID
);
2313 elprov2
= (void *)0xdeadbeef;
2314 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2315 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2316 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
2317 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
2318 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
2319 CHECK_CALLED(Accessible_get_uniqueID
);
2320 CHECK_CALLED(Accessible2_get_uniqueID
);
2322 elprov2
= (void *)0xdeadbeef;
2324 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2325 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2326 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
2328 IRawElementProviderSimple_Release(elprov
);
2329 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2331 set_accessible_props(&Accessible
, 0, 0, 0, NULL
, 0, 0, 0, 0);
2332 set_accessible_ia2_props(&Accessible
, FALSE
, 0);
2333 set_accessible_props(&Accessible2
, 0, 0, 0, NULL
, 0, 0, 0, 0);
2334 set_accessible_ia2_props(&Accessible2
, FALSE
, 0);
2337 #define check_fragment_acc( fragment, acc, cid) \
2338 check_fragment_acc_( (fragment), (acc), (cid), __LINE__)
2339 static void check_fragment_acc_(IRawElementProviderFragment
*elfrag
, IAccessible
*acc
,
2342 ILegacyIAccessibleProvider
*accprov
;
2343 IAccessible
*accessible
;
2347 hr
= IRawElementProviderFragment_QueryInterface(elfrag
, &IID_ILegacyIAccessibleProvider
, (void **)&accprov
);
2348 ok_(__FILE__
, line
) (hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2349 ok_(__FILE__
, line
) (!!accprov
, "accprov == NULL\n");
2351 hr
= ILegacyIAccessibleProvider_GetIAccessible(accprov
, &accessible
);
2352 ok_(__FILE__
, line
) (hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2353 ok_(__FILE__
, line
) (accessible
== acc
, "accessible != acc\n");
2354 IAccessible_Release(accessible
);
2356 hr
= ILegacyIAccessibleProvider_get_ChildId(accprov
, &child_id
);
2357 ok_(__FILE__
, line
) (hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2358 ok_(__FILE__
, line
) (child_id
== cid
, "child_id != cid\n");
2360 ILegacyIAccessibleProvider_Release(accprov
);
2363 static void test_uia_prov_from_acc_navigation(void)
2365 IRawElementProviderFragment
*elfrag
, *elfrag2
, *elfrag3
;
2366 IRawElementProviderSimple
*elprov
, *elprov2
;
2370 * Full IAccessible parent, with 4 children:
2371 * childid 1 is a simple element, with STATE_SYSTEM_INVISIBLE.
2372 * childid 2 is Accessible_child.
2373 * childid 3 is a simple element with STATE_SYSTEM_NORMAL.
2374 * childid 4 is Accessible_child2.
2376 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2377 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2378 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2380 hr
= IRawElementProviderSimple_QueryInterface(elprov
, &IID_IRawElementProviderFragment
, (void **)&elfrag
);
2381 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2382 ok(!!elfrag
, "elfrag == NULL\n");
2385 * First time doing NavigateDirection_Parent will result in the same root
2386 * accessible check as get_HostRawElementProvider. If this IAccessible is
2387 * the root for its associated HWND, NavigateDirection_Parent and
2388 * NavigateDirection_Next/PreviousSibling will do nothing, as UI Automation
2389 * provides non-client area providers for the root IAccessible's parent
2392 set_accessible_props(&Accessible
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 4,
2393 L
"acc_name", 0, 0, 50, 50);
2394 set_accessible_props(&Accessible2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 4,
2395 L
"acc_name", 0, 0, 50, 50);
2396 acc_client
= &Accessible2
.IAccessible_iface
;
2397 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2398 SET_EXPECT(Accessible_get_accRole
);
2399 SET_EXPECT(Accessible_get_accState
);
2400 SET_EXPECT(Accessible_get_accChildCount
);
2401 SET_EXPECT(Accessible_accLocation
);
2402 SET_EXPECT(Accessible_get_accName
);
2403 SET_EXPECT(Accessible2_get_accRole
);
2404 SET_EXPECT(Accessible2_get_accState
);
2405 SET_EXPECT(Accessible2_get_accChildCount
);
2406 SET_EXPECT(Accessible2_accLocation
);
2407 SET_EXPECT(Accessible2_get_accName
);
2408 SET_EXPECT(Accessible2_QI_IAccIdentity
);
2409 SET_EXPECT(Accessible2_get_accParent
);
2410 elfrag2
= (void *)0xdeadbeef;
2411 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_Parent
, &elfrag2
);
2412 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2413 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2414 ok(!elfrag2
, "elfrag2 != NULL\n");
2415 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
2416 CHECK_CALLED(Accessible_get_accRole
);
2417 CHECK_CALLED(Accessible_get_accState
);
2418 CHECK_CALLED(Accessible_get_accChildCount
);
2419 CHECK_CALLED(Accessible_accLocation
);
2420 CHECK_CALLED(Accessible_get_accName
);
2421 CHECK_CALLED(Accessible2_get_accRole
);
2422 CHECK_CALLED(Accessible2_get_accState
);
2423 CHECK_CALLED(Accessible2_get_accChildCount
);
2424 CHECK_CALLED(Accessible2_accLocation
);
2425 CHECK_CALLED(Accessible2_get_accName
);
2426 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
2427 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
2430 /* No check against root IAccessible, since it was done previously. */
2431 elprov2
= (void *)0xdeadbeef;
2432 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
2433 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2434 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
2435 IRawElementProviderSimple_Release(elprov2
);
2438 elfrag2
= (void *)0xdeadbeef;
2439 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_Parent
, &elfrag2
);
2440 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2441 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2442 ok(!elfrag2
, "elfrag2 != NULL\n");
2444 elfrag2
= (void *)0xdeadbeef;
2445 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_NextSibling
, &elfrag2
);
2446 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2447 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2448 ok(!elfrag2
, "elfrag2 != NULL\n");
2450 elfrag2
= (void *)0xdeadbeef;
2451 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_PreviousSibling
, &elfrag2
);
2452 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2453 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2454 ok(!elfrag2
, "elfrag2 != NULL\n");
2457 * Retrieve childid 2 (Accessible_child) as first child. childid 1 is skipped due to
2458 * having a state of STATE_SYSTEM_INVISIBLE.
2460 set_accessible_props(&Accessible_child
, 0, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
2461 set_accessible_props(&Accessible_child2
, 0, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
2462 SET_EXPECT_MULTI(Accessible_get_accChildCount
, 3);
2463 SET_EXPECT_MULTI(Accessible_get_accChild
, 2);
2464 SET_EXPECT(Accessible_get_accState
);
2465 SET_EXPECT(Accessible_child_get_accState
);
2466 SET_EXPECT(Accessible_child_accNavigate
);
2467 SET_EXPECT(Accessible_child_get_accParent
);
2468 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_FirstChild
, &elfrag2
);
2469 ok(Accessible_child
.ref
== 2, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2470 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2471 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2472 ok(!!elfrag2
, "elfrag2 == NULL\n");
2473 CHECK_CALLED_MULTI(Accessible_get_accChildCount
, 3);
2474 CHECK_CALLED_MULTI(Accessible_get_accChild
, 2);
2475 CHECK_CALLED(Accessible_child_get_accState
);
2476 CHECK_CALLED(Accessible_child_accNavigate
);
2477 CHECK_CALLED(Accessible_child_get_accParent
);
2479 check_fragment_acc(elfrag2
, &Accessible_child
.IAccessible_iface
, CHILDID_SELF
);
2480 SET_EXPECT(Accessible_get_accChildCount
);
2481 SET_EXPECT(Accessible_get_accChild
);
2482 SET_EXPECT(Accessible_get_accState
);
2483 hr
= IRawElementProviderFragment_Navigate(elfrag2
, NavigateDirection_NextSibling
, &elfrag3
);
2484 ok(Accessible
.ref
== 5, "Unexpected refcnt %ld\n", Accessible
.ref
);
2485 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2486 ok(!!elfrag3
, "elfrag2 == NULL\n");
2487 CHECK_CALLED(Accessible_get_accChildCount
);
2488 CHECK_CALLED(Accessible_get_accChild
);
2489 CHECK_CALLED(Accessible_get_accState
);
2490 check_fragment_acc(elfrag3
, &Accessible
.IAccessible_iface
, 3);
2492 IRawElementProviderFragment_Release(elfrag3
);
2493 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2494 IRawElementProviderFragment_Release(elfrag2
);
2495 ok(Accessible_child
.ref
== 1, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2496 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2498 /* Retrieve childid 3 as first child now that Accessible_child is invisible. */
2499 set_accessible_props(&Accessible_child
, 0, STATE_SYSTEM_INVISIBLE
, 0, NULL
, 0, 0, 0, 0);
2500 SET_EXPECT_MULTI(Accessible_get_accChildCount
, 4);
2501 SET_EXPECT_MULTI(Accessible_get_accChild
, 3);
2502 SET_EXPECT_MULTI(Accessible_get_accState
, 2);
2503 SET_EXPECT(Accessible_child_get_accState
);
2504 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_FirstChild
, &elfrag2
);
2505 ok(Accessible
.ref
== 4, "Unexpected refcnt %ld\n", Accessible
.ref
);
2506 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2507 ok(!!elfrag2
, "elfrag2 == NULL\n");
2508 CHECK_CALLED_MULTI(Accessible_get_accChildCount
, 4);
2509 CHECK_CALLED_MULTI(Accessible_get_accChild
, 3);
2510 CHECK_CALLED_MULTI(Accessible_get_accState
, 2);
2511 CHECK_CALLED(Accessible_child_get_accState
);
2512 check_fragment_acc(elfrag2
, &Accessible
.IAccessible_iface
, 3);
2513 IRawElementProviderFragment_Release(elfrag2
);
2514 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2516 /* Retrieve childid 4 (Accessible_child2) as last child. */
2517 set_accessible_props(&Accessible_child2
, 0, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
2518 SET_EXPECT_MULTI(Accessible_get_accChildCount
, 2);
2519 SET_EXPECT(Accessible_get_accChild
);
2520 SET_EXPECT(Accessible_child2_get_accState
);
2521 SET_EXPECT(Accessible_child2_accNavigate
);
2522 SET_EXPECT(Accessible_child2_get_accParent
);
2523 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_LastChild
, &elfrag2
);
2524 ok(Accessible_child2
.ref
== 2, "Unexpected refcnt %ld\n", Accessible_child2
.ref
);
2525 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2526 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2527 ok(!!elfrag2
, "elfrag2 == NULL\n");
2528 CHECK_CALLED_MULTI(Accessible_get_accChildCount
, 2);
2529 CHECK_CALLED(Accessible_get_accChild
);
2530 CHECK_CALLED(Accessible_child2_get_accState
);
2531 CHECK_CALLED(Accessible_child2_accNavigate
);
2532 CHECK_CALLED(Accessible_child2_get_accParent
);
2534 check_fragment_acc(elfrag2
, &Accessible_child2
.IAccessible_iface
, CHILDID_SELF
);
2535 SET_EXPECT(Accessible_get_accChildCount
);
2536 SET_EXPECT(Accessible_get_accChild
);
2537 SET_EXPECT(Accessible_get_accState
);
2538 hr
= IRawElementProviderFragment_Navigate(elfrag2
, NavigateDirection_PreviousSibling
, &elfrag3
);
2539 ok(Accessible
.ref
== 5, "Unexpected refcnt %ld\n", Accessible
.ref
);
2540 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2541 ok(!!elfrag3
, "elfrag2 == NULL\n");
2542 CHECK_CALLED(Accessible_get_accChildCount
);
2543 CHECK_CALLED(Accessible_get_accChild
);
2544 CHECK_CALLED(Accessible_get_accState
);
2545 check_fragment_acc(elfrag3
, &Accessible
.IAccessible_iface
, 3);
2547 IRawElementProviderFragment_Release(elfrag3
);
2548 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2549 IRawElementProviderFragment_Release(elfrag2
);
2550 ok(Accessible_child2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible_child2
.ref
);
2551 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2553 /* Retrieve childid 3 as last child, now that Accessible_child2 is STATE_SYSTEM_INVISIBLE. */
2554 set_accessible_props(&Accessible_child2
, 0, STATE_SYSTEM_INVISIBLE
, 0, NULL
, 0, 0, 0, 0);
2555 SET_EXPECT_MULTI(Accessible_get_accChildCount
, 3);
2556 SET_EXPECT_MULTI(Accessible_get_accChild
, 2);
2557 SET_EXPECT(Accessible_get_accState
);
2558 SET_EXPECT(Accessible_child2_get_accState
);
2559 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_LastChild
, &elfrag2
);
2560 ok(Accessible
.ref
== 4, "Unexpected refcnt %ld\n", Accessible
.ref
);
2561 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2562 ok(!!elfrag2
, "elfrag2 == NULL\n");
2563 CHECK_CALLED_MULTI(Accessible_get_accChildCount
, 3);
2564 CHECK_CALLED_MULTI(Accessible_get_accChild
, 2);
2565 CHECK_CALLED(Accessible_get_accState
);
2566 CHECK_CALLED(Accessible_child2_get_accState
);
2567 check_fragment_acc(elfrag2
, &Accessible
.IAccessible_iface
, 3);
2568 IRawElementProviderFragment_Release(elfrag2
);
2569 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2571 IRawElementProviderFragment_Release(elfrag
);
2572 IRawElementProviderSimple_Release(elprov
);
2573 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2576 * Full IAccessible child tests.
2578 SET_EXPECT(Accessible_child_accNavigate
);
2579 SET_EXPECT(Accessible_child_get_accParent
);
2580 hr
= pUiaProviderFromIAccessible(&Accessible_child
.IAccessible_iface
, 0, UIA_PFIA_DEFAULT
, &elprov
);
2581 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2582 CHECK_CALLED(Accessible_child_accNavigate
);
2583 CHECK_CALLED(Accessible_child_get_accParent
);
2584 ok(Accessible_child
.ref
== 2, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2586 hr
= IRawElementProviderSimple_QueryInterface(elprov
, &IID_IRawElementProviderFragment
, (void **)&elfrag
);
2587 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2588 ok(!!elfrag
, "elfrag == NULL\n");
2591 * After determining this isn't the root IAccessible, get_accParent will
2592 * be used to get the parent.
2594 set_accessible_props(&Accessible2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
2595 set_accessible_props(&Accessible_child
, ROLE_SYSTEM_CLIENT
, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
2596 acc_client
= &Accessible2
.IAccessible_iface
;
2597 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2598 SET_EXPECT(Accessible_child_get_accRole
);
2599 SET_EXPECT(Accessible_child_get_accParent
);
2600 SET_EXPECT(Accessible2_get_accRole
);
2601 SET_EXPECT(Accessible2_QI_IAccIdentity
);
2602 SET_EXPECT(Accessible2_get_accParent
);
2603 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_Parent
, &elfrag2
);
2604 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2605 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2606 ok(!!elfrag2
, "elfrag2 == NULL\n");
2607 CHECK_CALLED(Accessible_child_get_accParent
);
2608 CHECK_CALLED(Accessible_child_get_accRole
);
2609 CHECK_CALLED(Accessible2_get_accRole
);
2610 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
2611 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
2612 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
2613 check_fragment_acc(elfrag2
, &Accessible
.IAccessible_iface
, CHILDID_SELF
);
2614 IRawElementProviderFragment_Release(elfrag2
);
2615 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2618 /* Second call only does get_accParent, no root check. */
2619 SET_EXPECT(Accessible_child_get_accParent
);
2620 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_Parent
, &elfrag2
);
2621 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2622 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2623 ok(!!elfrag2
, "elfrag2 == NULL\n");
2624 CHECK_CALLED(Accessible_child_get_accParent
);
2625 check_fragment_acc(elfrag2
, &Accessible
.IAccessible_iface
, CHILDID_SELF
);
2626 IRawElementProviderFragment_Release(elfrag2
);
2627 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2629 /* ChildCount of 0, do nothing for First/Last child.*/
2630 SET_EXPECT(Accessible_child_get_accChildCount
);
2631 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_FirstChild
, &elfrag2
);
2632 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2633 ok(!elfrag2
, "elfrag2 != NULL\n");
2634 CHECK_CALLED(Accessible_child_get_accChildCount
);
2636 SET_EXPECT(Accessible_child_get_accChildCount
);
2637 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_LastChild
, &elfrag2
);
2638 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2639 ok(!elfrag2
, "elfrag2 != NULL\n");
2640 CHECK_CALLED(Accessible_child_get_accChildCount
);
2643 * In the case of sibling navigation on an IAccessible that wasn't
2644 * received through previous navigation from a parent (i.e, from
2645 * NavigateDirection_First/LastChild), we have to figure out which
2646 * IAccessible child we represent by comparing against all children of our
2647 * IAccessible parent. If we find more than one IAccessible that matches,
2648 * or none at all that do, navigation will fail.
2650 set_accessible_props(&Accessible_child
, ROLE_SYSTEM_CLIENT
, STATE_SYSTEM_FOCUSABLE
, 1,
2651 L
"acc_child", 0, 0, 50, 50);
2652 set_accessible_props(&Accessible_child2
, ROLE_SYSTEM_CLIENT
, STATE_SYSTEM_FOCUSABLE
, 1,
2653 L
"acc_child", 0, 0, 50, 50);
2654 SET_EXPECT_MULTI(Accessible_get_accChildCount
, 5);
2655 SET_EXPECT_MULTI(Accessible_get_accChild
, 4);
2656 SET_EXPECT(Accessible_child_get_accParent
);
2657 SET_EXPECT(Accessible_child_get_accRole
);
2658 SET_EXPECT(Accessible_child_get_accState
);
2659 SET_EXPECT(Accessible_child_get_accChildCount
);
2660 SET_EXPECT(Accessible_child_accLocation
);
2661 SET_EXPECT(Accessible_child_get_accName
);
2662 SET_EXPECT(Accessible_child2_get_accRole
);
2663 SET_EXPECT(Accessible_child2_get_accState
);
2664 SET_EXPECT(Accessible_child2_get_accChildCount
);
2665 SET_EXPECT(Accessible_child2_accLocation
);
2666 SET_EXPECT(Accessible_child2_get_accName
);
2667 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_NextSibling
, &elfrag2
);
2668 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2669 ok(!elfrag2
, "elfrag2 != NULL\n");
2670 CHECK_CALLED_MULTI(Accessible_get_accChildCount
, 5);
2671 CHECK_CALLED_MULTI(Accessible_get_accChild
, 4);
2672 CHECK_CALLED(Accessible_child_get_accParent
);
2673 CHECK_CALLED(Accessible_child_get_accRole
);
2674 CHECK_CALLED(Accessible_child_get_accState
);
2675 CHECK_CALLED(Accessible_child_get_accChildCount
);
2676 CHECK_CALLED(Accessible_child_accLocation
);
2677 CHECK_CALLED(Accessible_child_get_accName
);
2678 CHECK_CALLED(Accessible_child2_get_accRole
);
2679 CHECK_CALLED(Accessible_child2_get_accState
);
2680 CHECK_CALLED(Accessible_child2_get_accChildCount
);
2681 CHECK_CALLED(Accessible_child2_accLocation
);
2682 CHECK_CALLED(Accessible_child2_get_accName
);
2684 /* Now they have a role mismatch, we can determine our position. */
2685 set_accessible_props(&Accessible_child2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1,
2686 L
"acc_child", 0, 0, 50, 50);
2687 SET_EXPECT_MULTI(Accessible_get_accChildCount
, 6);
2688 SET_EXPECT_MULTI(Accessible_get_accChild
, 5);
2689 /* Check ChildID 1 for STATE_SYSTEM_INVISIBLE. */
2690 SET_EXPECT(Accessible_get_accState
);
2691 SET_EXPECT(Accessible_child_get_accParent
);
2692 SET_EXPECT(Accessible_child_get_accRole
);
2693 SET_EXPECT(Accessible_child2_get_accRole
);
2694 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_PreviousSibling
, &elfrag2
);
2696 * Even though we didn't get a new fragment, now that we know our
2697 * position, a reference is added to the parent IAccessible.
2699 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2700 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2701 ok(!elfrag2
, "elfrag2 != NULL\n");
2702 CHECK_CALLED_MULTI(Accessible_get_accChildCount
, 6);
2703 CHECK_CALLED_MULTI(Accessible_get_accChild
, 5);
2704 CHECK_CALLED(Accessible_get_accState
);
2705 CHECK_CALLED(Accessible_child_get_accParent
);
2706 CHECK_CALLED(Accessible_child_get_accRole
);
2707 CHECK_CALLED(Accessible_child2_get_accRole
);
2709 /* Now that we know our position, no extra nav work. */
2710 SET_EXPECT(Accessible_get_accChildCount
);
2711 SET_EXPECT(Accessible_get_accChild
);
2712 SET_EXPECT(Accessible_get_accState
);
2713 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_NextSibling
, &elfrag2
);
2714 ok(Accessible
.ref
== 4, "Unexpected refcnt %ld\n", Accessible
.ref
);
2715 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2716 ok(!!elfrag2
, "elfrag2 == NULL\n");
2717 CHECK_CALLED(Accessible_get_accChildCount
);
2718 CHECK_CALLED(Accessible_get_accChild
);
2719 CHECK_CALLED(Accessible_get_accState
);
2722 check_fragment_acc(elfrag2
, &Accessible
.IAccessible_iface
, 3);
2723 IRawElementProviderFragment_Release(elfrag2
);
2724 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2727 IRawElementProviderFragment_Release(elfrag
);
2728 IRawElementProviderSimple_Release(elprov
);
2729 ok(Accessible_child
.ref
== 1, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2730 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2733 * Simple element child tests.
2735 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, 1, UIA_PFIA_DEFAULT
, &elprov
);
2736 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2737 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2739 hr
= IRawElementProviderSimple_QueryInterface(elprov
, &IID_IRawElementProviderFragment
, (void **)&elfrag
);
2740 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2741 ok(!!elfrag
, "elfrag == NULL\n");
2744 * Simple child elements don't check the root IAccessible, because they
2745 * can't be the root IAccessible.
2747 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_Parent
, &elfrag2
);
2748 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2749 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2750 ok(!!elfrag2
, "elfrag2 == NULL\n");
2751 check_fragment_acc(elfrag2
, &Accessible
.IAccessible_iface
, CHILDID_SELF
);
2752 IRawElementProviderFragment_Release(elfrag2
);
2753 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2756 * Test NavigateDirection_First/LastChild on simple child element. Does
2757 * nothing, as simple children cannot have children.
2759 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_FirstChild
, &elfrag2
);
2760 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2761 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2762 ok(!elfrag2
, "elfrag2 != NULL\n");
2764 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_LastChild
, &elfrag2
);
2765 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2766 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2767 ok(!elfrag2
, "elfrag2 != NULL\n");
2770 * NavigateDirection_Next/PreviousSibling behaves normally, no IAccessible
2773 SET_EXPECT(Accessible_get_accChildCount
);
2774 SET_EXPECT(Accessible_get_accChild
);
2775 SET_EXPECT(Accessible_child_get_accState
);
2776 SET_EXPECT(Accessible_child_accNavigate
);
2777 SET_EXPECT(Accessible_child_get_accParent
);
2778 hr
= IRawElementProviderFragment_Navigate(elfrag
, NavigateDirection_NextSibling
, &elfrag2
);
2779 ok(Accessible_child
.ref
== 2, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2780 ok(Accessible
.ref
== 4, "Unexpected refcnt %ld\n", Accessible
.ref
);
2781 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2782 ok(!!elfrag2
, "elfrag2 == NULL\n");
2783 CHECK_CALLED(Accessible_get_accChildCount
);
2784 CHECK_CALLED(Accessible_get_accChild
);
2785 CHECK_CALLED(Accessible_child_get_accState
);
2786 CHECK_CALLED(Accessible_child_accNavigate
);
2787 CHECK_CALLED(Accessible_child_get_accParent
);
2788 check_fragment_acc(elfrag2
, &Accessible_child
.IAccessible_iface
, CHILDID_SELF
);
2790 IRawElementProviderFragment_Release(elfrag2
);
2791 ok(Accessible_child
.ref
== 1, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2792 ok(Accessible
.ref
== 3, "Unexpected refcnt %ld\n", Accessible
.ref
);
2793 IRawElementProviderFragment_Release(elfrag
);
2794 IRawElementProviderSimple_Release(elprov
);
2795 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2797 set_accessible_props(&Accessible
, 0, 0, 0, NULL
, 0, 0, 0, 0);
2798 set_accessible_props(&Accessible2
, 0, 0, 0, NULL
, 0, 0, 0, 0);
2799 set_accessible_props(&Accessible_child
, 0, 0, 0, NULL
, 0, 0, 0, 0);
2800 set_accessible_props(&Accessible_child2
, 0, 0, 0, NULL
, 0, 0, 0, 0);
2803 static void test_uia_prov_from_acc_properties(void)
2805 IRawElementProviderSimple
*elprov
;
2810 /* MSAA role to UIA control type test. */
2812 for (i
= 0; i
< ARRAY_SIZE(msaa_role_uia_types
); i
++)
2814 const struct msaa_role_uia_type
*role
= &msaa_role_uia_types
[i
];
2817 * Roles get cached once a valid one is mapped, so create a new
2818 * element for each role.
2820 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2821 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2822 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2824 Accessible
.role
= role
->acc_role
;
2825 SET_EXPECT(Accessible_get_accRole
);
2827 hr
= IRawElementProviderSimple_GetPropertyValue(elprov
, UIA_ControlTypePropertyId
, &v
);
2828 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2829 if (role
->uia_control_type
)
2830 ok(check_variant_i4(&v
, role
->uia_control_type
), "MSAA role %d: V_I4(&v) = %ld\n", role
->acc_role
, V_I4(&v
));
2832 ok(V_VT(&v
) == VT_EMPTY
, "MSAA role %d: V_VT(&v) = %d\n", role
->acc_role
, V_VT(&v
));
2833 CHECK_CALLED(Accessible_get_accRole
);
2835 if (!role
->uia_control_type
)
2836 SET_EXPECT(Accessible_get_accRole
);
2838 hr
= IRawElementProviderSimple_GetPropertyValue(elprov
, UIA_ControlTypePropertyId
, &v
);
2839 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2840 if (role
->uia_control_type
)
2841 ok(check_variant_i4(&v
, role
->uia_control_type
), "MSAA role %d: V_I4(&v) = %ld\n", role
->acc_role
, V_I4(&v
));
2843 ok(V_VT(&v
) == VT_EMPTY
, "MSAA role %d: V_VT(&v) = %d\n", role
->acc_role
, V_VT(&v
));
2844 if (!role
->uia_control_type
)
2845 CHECK_CALLED(Accessible_get_accRole
);
2847 IRawElementProviderSimple_Release(elprov
);
2848 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2851 /* ROLE_SYSTEM_CLOCK has no mapping in Windows < 10 1809. */
2852 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2853 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2854 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2856 Accessible
.role
= ROLE_SYSTEM_CLOCK
;
2857 SET_EXPECT(Accessible_get_accRole
);
2859 hr
= IRawElementProviderSimple_GetPropertyValue(elprov
, UIA_ControlTypePropertyId
, &v
);
2860 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2861 ok(check_variant_i4(&v
, UIA_ButtonControlTypeId
) || broken(V_VT(&v
) == VT_EMPTY
), /* Windows < 10 1809 */
2862 "MSAA role %d: V_I4(&v) = %ld\n", Accessible
.role
, V_I4(&v
));
2863 CHECK_CALLED(Accessible_get_accRole
);
2865 if (V_VT(&v
) == VT_EMPTY
)
2866 SET_EXPECT(Accessible_get_accRole
);
2868 hr
= IRawElementProviderSimple_GetPropertyValue(elprov
, UIA_ControlTypePropertyId
, &v
);
2869 ok(check_variant_i4(&v
, UIA_ButtonControlTypeId
) || broken(V_VT(&v
) == VT_EMPTY
), /* Windows < 10 1809 */
2870 "MSAA role %d: V_I4(&v) = %ld\n", Accessible
.role
, V_I4(&v
));
2871 if (V_VT(&v
) == VT_EMPTY
)
2872 CHECK_CALLED(Accessible_get_accRole
);
2874 Accessible
.role
= 0;
2875 IRawElementProviderSimple_Release(elprov
);
2876 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2878 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2879 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2880 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2882 /* UIA PropertyId's that correspond directly to individual MSAA state flags. */
2883 for (i
= 0; i
< ARRAY_SIZE(msaa_state_uia_props
); i
++)
2885 const struct msaa_state_uia_prop
*state
= &msaa_state_uia_props
[i
];
2887 for (x
= 0; x
< 2; x
++)
2889 Accessible
.state
= x
? state
->acc_state
: ~state
->acc_state
;
2890 SET_EXPECT(Accessible_get_accState
);
2891 hr
= IRawElementProviderSimple_GetPropertyValue(elprov
, state
->prop_id
, &v
);
2892 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2893 ok(check_variant_bool(&v
, x
), "V_BOOL(&v) = %#x\n", V_BOOL(&v
));
2894 CHECK_CALLED(Accessible_get_accState
);
2897 Accessible
.state
= 0;
2899 IRawElementProviderSimple_Release(elprov
);
2900 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2903 static void test_UiaProviderFromIAccessible(void)
2905 ILegacyIAccessibleProvider
*accprov
;
2906 IRawElementProviderSimple
*elprov
, *elprov2
;
2907 enum ProviderOptions prov_opt
;
2916 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
2918 cls
.lpfnWndProc
= test_wnd_proc
;
2921 cls
.hInstance
= GetModuleHandleA(NULL
);
2924 cls
.hbrBackground
= NULL
;
2925 cls
.lpszMenuName
= NULL
;
2926 cls
.lpszClassName
= "UiaProviderFromIAccessible class";
2928 RegisterClassA(&cls
);
2930 hwnd
= CreateWindowA("UiaProviderFromIAccessible class", "Test window", WS_OVERLAPPEDWINDOW
,
2931 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
2933 hr
= pUiaProviderFromIAccessible(NULL
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2934 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2936 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, NULL
);
2937 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2940 * UiaProviderFromIAccessible will not wrap an MSAA proxy, this is
2941 * detected by checking for the 'IIS_IsOleaccProxy' service from the
2942 * IServiceProvider interface.
2944 hr
= CreateStdAccessibleObject(hwnd
, OBJID_CLIENT
, &IID_IAccessible
, (void**)&acc
);
2945 ok(hr
== S_OK
, "got %#lx\n", hr
);
2946 ok(!!acc
, "acc == NULL\n");
2948 hr
= pUiaProviderFromIAccessible(acc
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2949 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2950 IAccessible_Release(acc
);
2952 /* Don't return an HWND from accNavigate or OleWindow. */
2953 SET_EXPECT(Accessible_accNavigate
);
2954 SET_EXPECT(Accessible_get_accParent
);
2955 Accessible
.acc_hwnd
= NULL
;
2956 Accessible
.ow_hwnd
= NULL
;
2957 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2958 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
2959 CHECK_CALLED(Accessible_accNavigate
);
2960 CHECK_CALLED(Accessible_get_accParent
);
2962 /* Return an HWND from accNavigate, not OleWindow. */
2963 SET_EXPECT(Accessible_accNavigate
);
2964 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
2965 acc_client
= &Accessible
.IAccessible_iface
;
2966 Accessible
.acc_hwnd
= hwnd
;
2967 Accessible
.ow_hwnd
= NULL
;
2968 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2969 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2970 CHECK_CALLED(Accessible_accNavigate
);
2971 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
2972 IRawElementProviderSimple_Release(elprov
);
2973 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
2976 /* Skip tests on Win10v1507. */
2977 if (called_winproc_GETOBJECT_CLIENT
)
2979 win_skip("UiaProviderFromIAccessible behaves inconsistently on Win10 1507, skipping tests.\n");
2982 expect_winproc_GETOBJECT_CLIENT
= FALSE
;
2984 /* Return an HWND from parent IAccessible's IOleWindow interface. */
2985 SET_EXPECT(Accessible_child_accNavigate
);
2986 SET_EXPECT(Accessible_child_get_accParent
);
2987 Accessible
.acc_hwnd
= NULL
;
2988 Accessible
.ow_hwnd
= hwnd
;
2989 hr
= pUiaProviderFromIAccessible(&Accessible_child
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
2990 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2991 CHECK_CALLED(Accessible_child_accNavigate
);
2992 CHECK_CALLED(Accessible_child_get_accParent
);
2993 ok(Accessible_child
.ref
== 2, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2994 IRawElementProviderSimple_Release(elprov
);
2995 ok(Accessible_child
.ref
== 1, "Unexpected refcnt %ld\n", Accessible_child
.ref
);
2997 /* Return an HWND from OleWindow, not accNavigate. */
2998 Accessible
.acc_hwnd
= NULL
;
2999 Accessible
.ow_hwnd
= hwnd
;
3000 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3001 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3002 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3004 hr
= IRawElementProviderSimple_get_ProviderOptions(elprov
, &prov_opt
);
3005 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3006 ok((prov_opt
== (ProviderOptions_ServerSideProvider
| ProviderOptions_UseComThreading
)) ||
3007 broken(prov_opt
== ProviderOptions_ClientSideProvider
), /* Windows < 10 1507 */
3008 "Unexpected provider options %#x\n", prov_opt
);
3010 hr
= IRawElementProviderSimple_GetPropertyValue(elprov
, UIA_ProviderDescriptionPropertyId
, &v
);
3011 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3012 ok(V_VT(&v
) == VT_BSTR
, "V_VT(&v) = %d\n", V_VT(&v
));
3015 hr
= IRawElementProviderSimple_GetPatternProvider(elprov
, UIA_LegacyIAccessiblePatternId
, &unk
);
3016 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3017 ok(!!unk
, "unk == NULL\n");
3018 ok(iface_cmp((IUnknown
*)elprov
, unk
), "unk != elprov\n");
3020 hr
= IUnknown_QueryInterface(unk
, &IID_ILegacyIAccessibleProvider
, (void **)&accprov
);
3021 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3022 ok(!!accprov
, "accprov == NULL\n");
3024 hr
= ILegacyIAccessibleProvider_get_ChildId(accprov
, &cid
);
3025 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3026 ok(cid
== CHILDID_SELF
, "cid != CHILDID_SELF\n");
3028 hr
= ILegacyIAccessibleProvider_GetIAccessible(accprov
, &acc
);
3029 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3030 ok(acc
== &Accessible
.IAccessible_iface
, "acc != &Accessible.IAccessible_iface\n");
3031 IAccessible_Release(acc
);
3032 IUnknown_Release(unk
);
3033 ILegacyIAccessibleProvider_Release(accprov
);
3035 IRawElementProviderSimple_Release(elprov
);
3036 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3038 /* ChildID other than CHILDID_SELF. */
3039 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, 1, UIA_PFIA_DEFAULT
, &elprov
);
3040 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3041 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3044 * Simple child element (IAccessible without CHILDID_SELF) cannot be root
3045 * IAccessible. No checks against the root HWND IAccessible will be done.
3047 elprov2
= (void *)0xdeadbeef;
3048 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3049 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3050 ok(!elprov2
, "elprov != NULL\n");
3052 hr
= IRawElementProviderSimple_GetPatternProvider(elprov
, UIA_LegacyIAccessiblePatternId
, &unk
);
3053 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3054 ok(!!unk
, "unk == NULL\n");
3055 ok(iface_cmp((IUnknown
*)elprov
, unk
), "unk != elprov\n");
3057 hr
= IUnknown_QueryInterface(unk
, &IID_ILegacyIAccessibleProvider
, (void **)&accprov
);
3058 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3059 ok(!!accprov
, "accprov == NULL\n");
3061 hr
= ILegacyIAccessibleProvider_get_ChildId(accprov
, &cid
);
3062 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3063 ok(cid
== 1, "cid != CHILDID_SELF\n");
3065 hr
= ILegacyIAccessibleProvider_GetIAccessible(accprov
, &acc
);
3066 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3067 ok(acc
== &Accessible
.IAccessible_iface
, "acc != &Accessible.IAccessible_iface\n");
3068 IAccessible_Release(acc
);
3069 IUnknown_Release(unk
);
3070 ILegacyIAccessibleProvider_Release(accprov
);
3072 IRawElementProviderSimple_Release(elprov
);
3073 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3076 * &Accessible.IAccessible_iface will be compared against the default
3077 * client accessible object. Since we have all properties set to 0,
3078 * we return failure HRESULTs and all properties will get queried but not
3081 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3082 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3083 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3085 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3086 SET_EXPECT(Accessible_get_accRole
);
3087 SET_EXPECT(Accessible_get_accState
);
3088 SET_EXPECT(Accessible_get_accChildCount
);
3089 SET_EXPECT(Accessible_accLocation
);
3090 SET_EXPECT(Accessible_get_accName
);
3091 elprov2
= (void *)0xdeadbeef;
3092 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3093 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3094 ok(!elprov2
, "elprov != NULL\n");
3095 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3096 CHECK_CALLED(Accessible_get_accRole
);
3097 CHECK_CALLED(Accessible_get_accState
);
3098 CHECK_CALLED(Accessible_get_accChildCount
);
3099 CHECK_CALLED(Accessible_accLocation
);
3100 CHECK_CALLED(Accessible_get_accName
);
3102 /* Second call won't send WM_GETOBJECT. */
3103 elprov2
= (void *)0xdeadbeef;
3104 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3105 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3106 ok(!elprov2
, "elprov != NULL\n");
3108 IRawElementProviderSimple_Release(elprov
);
3109 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3112 * Return &Accessible.IAccessible_iface in response to OBJID_CLIENT,
3113 * interface pointers will be compared, no method calls to check property
3116 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3117 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3118 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3120 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3121 elprov2
= (void *)0xdeadbeef;
3122 acc_client
= &Accessible
.IAccessible_iface
;
3123 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3124 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3125 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3126 IRawElementProviderSimple_Release(elprov2
);
3127 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3129 /* Second call, no checks. */
3130 elprov2
= (void *)0xdeadbeef;
3132 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3133 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3134 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3135 IRawElementProviderSimple_Release(elprov2
);
3137 IRawElementProviderSimple_Release(elprov
);
3138 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3141 * Return &Accessible2.IAccessible_iface in response to OBJID_CLIENT,
3142 * interface pointers won't match, so properties will be compared.
3144 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3145 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3146 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3148 set_accessible_props(&Accessible
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1,
3149 L
"acc_name", 0, 0, 50, 50);
3150 set_accessible_props(&Accessible2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1,
3151 L
"acc_name", 0, 0, 50, 50);
3153 acc_client
= &Accessible2
.IAccessible_iface
;
3154 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3155 SET_EXPECT(Accessible_get_accRole
);
3156 SET_EXPECT(Accessible_get_accState
);
3157 SET_EXPECT(Accessible_get_accChildCount
);
3158 SET_EXPECT(Accessible_accLocation
);
3159 SET_EXPECT(Accessible_get_accName
);
3160 SET_EXPECT(Accessible2_get_accRole
);
3161 SET_EXPECT(Accessible2_get_accState
);
3162 SET_EXPECT(Accessible2_get_accChildCount
);
3163 SET_EXPECT(Accessible2_accLocation
);
3164 SET_EXPECT(Accessible2_get_accName
);
3166 * The IAccessible returned by WM_GETOBJECT will be checked for an
3167 * IAccIdentity interface to see if Dynamic Annotation properties should
3168 * be queried. If not present on the current IAccessible, it will check
3169 * the parent IAccessible for one.
3171 SET_EXPECT(Accessible2_QI_IAccIdentity
);
3172 SET_EXPECT(Accessible2_get_accParent
);
3173 elprov2
= (void *)0xdeadbeef;
3174 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3175 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3176 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3177 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
3178 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3179 CHECK_CALLED(Accessible_get_accRole
);
3180 CHECK_CALLED(Accessible_get_accState
);
3181 CHECK_CALLED(Accessible_get_accChildCount
);
3182 CHECK_CALLED(Accessible_accLocation
);
3183 CHECK_CALLED(Accessible_get_accName
);
3184 CHECK_CALLED(Accessible2_get_accRole
);
3185 CHECK_CALLED(Accessible2_get_accState
);
3186 CHECK_CALLED(Accessible2_get_accChildCount
);
3187 CHECK_CALLED(Accessible2_accLocation
);
3188 CHECK_CALLED(Accessible2_get_accName
);
3189 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
3190 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
3191 IRawElementProviderSimple_Release(elprov2
);
3193 elprov2
= (void *)0xdeadbeef;
3195 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3196 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3197 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3198 IRawElementProviderSimple_Release(elprov2
);
3200 IRawElementProviderSimple_Release(elprov
);
3201 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3204 * If a failure HRESULT is returned from the IRawElementProviderSimple
3205 * IAccessible, the corresponding AOFW IAccessible method isn't called.
3206 * An exception is get_accChildCount, which is always called, but only
3207 * checked if the HRESULT return value is not a failure. If Role/State/Name
3208 * are not queried, no IAccIdentity check is done.
3210 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3211 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3212 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3214 set_accessible_props(&Accessible
, 0, 0, 0, NULL
, 0, 0, 0, 0);
3215 set_accessible_props(&Accessible2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1,
3216 L
"acc_name", 0, 0, 50, 50);
3218 acc_client
= &Accessible2
.IAccessible_iface
;
3219 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3220 SET_EXPECT(Accessible_get_accRole
);
3221 SET_EXPECT(Accessible_get_accState
);
3222 SET_EXPECT(Accessible_get_accChildCount
);
3223 SET_EXPECT(Accessible2_get_accChildCount
);
3224 SET_EXPECT(Accessible_accLocation
);
3225 SET_EXPECT(Accessible_get_accName
);
3226 elprov2
= (void *)0xdeadbeef;
3227 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3228 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3229 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
3230 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3231 CHECK_CALLED(Accessible_get_accRole
);
3232 CHECK_CALLED(Accessible_get_accState
);
3233 CHECK_CALLED(Accessible_get_accChildCount
);
3234 CHECK_CALLED(Accessible2_get_accChildCount
);
3235 CHECK_CALLED(Accessible_accLocation
);
3236 CHECK_CALLED(Accessible_get_accName
);
3239 elprov2
= (void *)0xdeadbeef;
3240 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3241 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3242 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
3244 IRawElementProviderSimple_Release(elprov
);
3245 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3248 * Properties are checked in a sequence of accRole, accState,
3249 * accChildCount, accLocation, and finally accName. If a mismatch is found
3250 * early in the sequence, the rest aren't checked.
3252 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3253 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3254 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3256 set_accessible_props(&Accessible
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
3257 set_accessible_props(&Accessible2
, ROLE_SYSTEM_CLIENT
, STATE_SYSTEM_FOCUSABLE
, 0, NULL
, 0, 0, 0, 0);
3259 acc_client
= &Accessible2
.IAccessible_iface
;
3260 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3261 SET_EXPECT(Accessible_get_accRole
);
3262 SET_EXPECT(Accessible2_get_accRole
);
3263 SET_EXPECT(Accessible2_QI_IAccIdentity
);
3264 SET_EXPECT(Accessible2_get_accParent
);
3265 elprov2
= (void *)0xdeadbeef;
3266 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3267 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3268 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
3269 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3270 CHECK_CALLED(Accessible_get_accRole
);
3271 CHECK_CALLED(Accessible2_get_accRole
);
3272 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
3273 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
3275 elprov2
= (void *)0xdeadbeef;
3277 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3278 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3279 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
3281 IRawElementProviderSimple_Release(elprov
);
3282 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3284 /* 4/5 properties match, considered a match. */
3285 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3286 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3287 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3289 set_accessible_props(&Accessible
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1, NULL
, 0, 0, 50, 50);
3290 set_accessible_props(&Accessible2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1, NULL
, 0, 0, 50, 50);
3292 acc_client
= &Accessible2
.IAccessible_iface
;
3293 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3294 SET_EXPECT(Accessible_get_accRole
);
3295 SET_EXPECT(Accessible_get_accState
);
3296 SET_EXPECT(Accessible_get_accChildCount
);
3297 SET_EXPECT(Accessible_accLocation
);
3298 SET_EXPECT(Accessible_get_accName
);
3299 SET_EXPECT(Accessible2_get_accRole
);
3300 SET_EXPECT(Accessible2_get_accState
);
3301 SET_EXPECT(Accessible2_get_accChildCount
);
3302 SET_EXPECT(Accessible2_accLocation
);
3303 SET_EXPECT(Accessible2_QI_IAccIdentity
);
3304 SET_EXPECT(Accessible2_get_accParent
);
3305 elprov2
= (void *)0xdeadbeef;
3306 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3307 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3308 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3309 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
3310 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3311 CHECK_CALLED(Accessible_get_accRole
);
3312 CHECK_CALLED(Accessible_get_accState
);
3313 CHECK_CALLED(Accessible_get_accChildCount
);
3314 CHECK_CALLED(Accessible_accLocation
);
3315 CHECK_CALLED(Accessible_get_accName
);
3316 CHECK_CALLED(Accessible2_get_accRole
);
3317 CHECK_CALLED(Accessible2_get_accState
);
3318 CHECK_CALLED(Accessible2_get_accChildCount
);
3319 CHECK_CALLED(Accessible2_accLocation
);
3320 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
3321 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
3322 IRawElementProviderSimple_Release(elprov2
);
3324 elprov2
= (void *)0xdeadbeef;
3326 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3327 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3328 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3329 IRawElementProviderSimple_Release(elprov2
);
3331 IRawElementProviderSimple_Release(elprov
);
3332 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3334 /* 3/5 properties match, not considered a match. */
3335 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3336 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3337 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3339 set_accessible_props(&Accessible
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1, NULL
, 0, 0, 0, 0);
3340 set_accessible_props(&Accessible2
, ROLE_SYSTEM_DOCUMENT
, STATE_SYSTEM_FOCUSABLE
, 1, NULL
, 0, 0, 0, 0);
3342 acc_client
= &Accessible2
.IAccessible_iface
;
3343 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3344 SET_EXPECT(Accessible_get_accRole
);
3345 SET_EXPECT(Accessible_get_accState
);
3346 SET_EXPECT(Accessible_get_accChildCount
);
3347 SET_EXPECT(Accessible_accLocation
);
3348 SET_EXPECT(Accessible_get_accName
);
3349 SET_EXPECT(Accessible2_get_accRole
);
3350 SET_EXPECT(Accessible2_get_accState
);
3351 SET_EXPECT(Accessible2_get_accChildCount
);
3352 SET_EXPECT(Accessible2_QI_IAccIdentity
);
3353 SET_EXPECT(Accessible2_get_accParent
);
3354 elprov2
= (void *)0xdeadbeef;
3355 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3356 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3357 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
3358 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3359 CHECK_CALLED(Accessible_get_accRole
);
3360 CHECK_CALLED(Accessible_get_accState
);
3361 CHECK_CALLED(Accessible_get_accChildCount
);
3362 CHECK_CALLED(Accessible_accLocation
);
3363 CHECK_CALLED(Accessible_get_accName
);
3364 CHECK_CALLED(Accessible2_get_accRole
);
3365 CHECK_CALLED(Accessible2_get_accState
);
3366 CHECK_CALLED(Accessible2_get_accChildCount
);
3367 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
3368 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
3370 elprov2
= (void *)0xdeadbeef;
3372 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3373 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3374 ok(!elprov2
, "elprov != NULL, elprov %p\n", elprov2
);
3376 IRawElementProviderSimple_Release(elprov
);
3377 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3379 /* Only name matches, considered a match. */
3380 hr
= pUiaProviderFromIAccessible(&Accessible
.IAccessible_iface
, CHILDID_SELF
, UIA_PFIA_DEFAULT
, &elprov
);
3381 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3382 ok(Accessible
.ref
== 2, "Unexpected refcnt %ld\n", Accessible
.ref
);
3384 set_accessible_props(&Accessible
, 0, 0, 0, L
"acc_name", 0, 0, 0, 0);
3385 set_accessible_props(&Accessible2
, 0, 0, 0, L
"acc_name", 0, 0, 0, 0);
3387 acc_client
= &Accessible2
.IAccessible_iface
;
3388 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
3389 SET_EXPECT(Accessible_get_accRole
);
3390 SET_EXPECT(Accessible_get_accState
);
3391 SET_EXPECT(Accessible_get_accChildCount
);
3392 SET_EXPECT(Accessible_accLocation
);
3393 SET_EXPECT(Accessible_get_accName
);
3394 SET_EXPECT(Accessible2_get_accChildCount
);
3395 SET_EXPECT(Accessible2_get_accName
);
3396 SET_EXPECT(Accessible2_QI_IAccIdentity
);
3397 SET_EXPECT(Accessible2_get_accParent
);
3398 elprov2
= (void *)0xdeadbeef;
3399 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3400 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3401 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3402 ok(Accessible2
.ref
== 1, "Unexpected refcnt %ld\n", Accessible2
.ref
);
3403 CHECK_CALLED(winproc_GETOBJECT_CLIENT
);
3404 CHECK_CALLED(Accessible_get_accRole
);
3405 CHECK_CALLED(Accessible_get_accState
);
3406 CHECK_CALLED(Accessible_get_accChildCount
);
3407 CHECK_CALLED(Accessible_accLocation
);
3408 CHECK_CALLED(Accessible_get_accName
);
3409 CHECK_CALLED(Accessible2_get_accChildCount
);
3410 CHECK_CALLED(Accessible2_get_accName
);
3411 todo_wine
CHECK_CALLED(Accessible2_QI_IAccIdentity
);
3412 todo_wine
CHECK_CALLED(Accessible2_get_accParent
);
3413 IRawElementProviderSimple_Release(elprov2
);
3415 elprov2
= (void *)0xdeadbeef;
3417 hr
= IRawElementProviderSimple_get_HostRawElementProvider(elprov
, &elprov2
);
3418 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3419 ok(!!elprov2
, "elprov == NULL, elprov %p\n", elprov2
);
3420 IRawElementProviderSimple_Release(elprov2
);
3422 IRawElementProviderSimple_Release(elprov
);
3423 ok(Accessible
.ref
== 1, "Unexpected refcnt %ld\n", Accessible
.ref
);
3425 test_uia_prov_from_acc_properties();
3426 test_uia_prov_from_acc_navigation();
3427 test_uia_prov_from_acc_ia2();
3430 DestroyWindow(hwnd
);
3431 UnregisterClassA("pUiaProviderFromIAccessible class", NULL
);
3432 Accessible
.acc_hwnd
= NULL
;
3433 Accessible
.ow_hwnd
= NULL
;
3436 struct uia_lookup_id
{
3441 static const struct uia_lookup_id uia_property_lookup_ids
[] = {
3442 { &RuntimeId_Property_GUID
, UIA_RuntimeIdPropertyId
},
3443 { &BoundingRectangle_Property_GUID
, UIA_BoundingRectanglePropertyId
},
3444 { &ProcessId_Property_GUID
, UIA_ProcessIdPropertyId
},
3445 { &ControlType_Property_GUID
, UIA_ControlTypePropertyId
},
3446 { &LocalizedControlType_Property_GUID
, UIA_LocalizedControlTypePropertyId
},
3447 { &Name_Property_GUID
, UIA_NamePropertyId
},
3448 { &AcceleratorKey_Property_GUID
, UIA_AcceleratorKeyPropertyId
},
3449 { &AccessKey_Property_GUID
, UIA_AccessKeyPropertyId
},
3450 { &HasKeyboardFocus_Property_GUID
, UIA_HasKeyboardFocusPropertyId
},
3451 { &IsKeyboardFocusable_Property_GUID
, UIA_IsKeyboardFocusablePropertyId
},
3452 { &IsEnabled_Property_GUID
, UIA_IsEnabledPropertyId
},
3453 { &AutomationId_Property_GUID
, UIA_AutomationIdPropertyId
},
3454 { &ClassName_Property_GUID
, UIA_ClassNamePropertyId
},
3455 { &HelpText_Property_GUID
, UIA_HelpTextPropertyId
},
3456 { &ClickablePoint_Property_GUID
, UIA_ClickablePointPropertyId
},
3457 { &Culture_Property_GUID
, UIA_CulturePropertyId
},
3458 { &IsControlElement_Property_GUID
, UIA_IsControlElementPropertyId
},
3459 { &IsContentElement_Property_GUID
, UIA_IsContentElementPropertyId
},
3460 { &LabeledBy_Property_GUID
, UIA_LabeledByPropertyId
},
3461 { &IsPassword_Property_GUID
, UIA_IsPasswordPropertyId
},
3462 { &NewNativeWindowHandle_Property_GUID
, UIA_NativeWindowHandlePropertyId
},
3463 { &ItemType_Property_GUID
, UIA_ItemTypePropertyId
},
3464 { &IsOffscreen_Property_GUID
, UIA_IsOffscreenPropertyId
},
3465 { &Orientation_Property_GUID
, UIA_OrientationPropertyId
},
3466 { &FrameworkId_Property_GUID
, UIA_FrameworkIdPropertyId
},
3467 { &IsRequiredForForm_Property_GUID
, UIA_IsRequiredForFormPropertyId
},
3468 { &ItemStatus_Property_GUID
, UIA_ItemStatusPropertyId
},
3469 { &IsDockPatternAvailable_Property_GUID
, UIA_IsDockPatternAvailablePropertyId
},
3470 { &IsExpandCollapsePatternAvailable_Property_GUID
, UIA_IsExpandCollapsePatternAvailablePropertyId
},
3471 { &IsGridItemPatternAvailable_Property_GUID
, UIA_IsGridItemPatternAvailablePropertyId
},
3472 { &IsGridPatternAvailable_Property_GUID
, UIA_IsGridPatternAvailablePropertyId
},
3473 { &IsInvokePatternAvailable_Property_GUID
, UIA_IsInvokePatternAvailablePropertyId
},
3474 { &IsMultipleViewPatternAvailable_Property_GUID
, UIA_IsMultipleViewPatternAvailablePropertyId
},
3475 { &IsRangeValuePatternAvailable_Property_GUID
, UIA_IsRangeValuePatternAvailablePropertyId
},
3476 { &IsScrollPatternAvailable_Property_GUID
, UIA_IsScrollPatternAvailablePropertyId
},
3477 { &IsScrollItemPatternAvailable_Property_GUID
, UIA_IsScrollItemPatternAvailablePropertyId
},
3478 { &IsSelectionItemPatternAvailable_Property_GUID
, UIA_IsSelectionItemPatternAvailablePropertyId
},
3479 { &IsSelectionPatternAvailable_Property_GUID
, UIA_IsSelectionPatternAvailablePropertyId
},
3480 { &IsTablePatternAvailable_Property_GUID
, UIA_IsTablePatternAvailablePropertyId
},
3481 { &IsTableItemPatternAvailable_Property_GUID
, UIA_IsTableItemPatternAvailablePropertyId
},
3482 { &IsTextPatternAvailable_Property_GUID
, UIA_IsTextPatternAvailablePropertyId
},
3483 { &IsTogglePatternAvailable_Property_GUID
, UIA_IsTogglePatternAvailablePropertyId
},
3484 { &IsTransformPatternAvailable_Property_GUID
, UIA_IsTransformPatternAvailablePropertyId
},
3485 { &IsValuePatternAvailable_Property_GUID
, UIA_IsValuePatternAvailablePropertyId
},
3486 { &IsWindowPatternAvailable_Property_GUID
, UIA_IsWindowPatternAvailablePropertyId
},
3487 { &Value_Value_Property_GUID
, UIA_ValueValuePropertyId
},
3488 { &Value_IsReadOnly_Property_GUID
, UIA_ValueIsReadOnlyPropertyId
},
3489 { &RangeValue_Value_Property_GUID
, UIA_RangeValueValuePropertyId
},
3490 { &RangeValue_IsReadOnly_Property_GUID
, UIA_RangeValueIsReadOnlyPropertyId
},
3491 { &RangeValue_Minimum_Property_GUID
, UIA_RangeValueMinimumPropertyId
},
3492 { &RangeValue_Maximum_Property_GUID
, UIA_RangeValueMaximumPropertyId
},
3493 { &RangeValue_LargeChange_Property_GUID
, UIA_RangeValueLargeChangePropertyId
},
3494 { &RangeValue_SmallChange_Property_GUID
, UIA_RangeValueSmallChangePropertyId
},
3495 { &Scroll_HorizontalScrollPercent_Property_GUID
, UIA_ScrollHorizontalScrollPercentPropertyId
},
3496 { &Scroll_HorizontalViewSize_Property_GUID
, UIA_ScrollHorizontalViewSizePropertyId
},
3497 { &Scroll_VerticalScrollPercent_Property_GUID
, UIA_ScrollVerticalScrollPercentPropertyId
},
3498 { &Scroll_VerticalViewSize_Property_GUID
, UIA_ScrollVerticalViewSizePropertyId
},
3499 { &Scroll_HorizontallyScrollable_Property_GUID
, UIA_ScrollHorizontallyScrollablePropertyId
},
3500 { &Scroll_VerticallyScrollable_Property_GUID
, UIA_ScrollVerticallyScrollablePropertyId
},
3501 { &Selection_Selection_Property_GUID
, UIA_SelectionSelectionPropertyId
},
3502 { &Selection_CanSelectMultiple_Property_GUID
, UIA_SelectionCanSelectMultiplePropertyId
},
3503 { &Selection_IsSelectionRequired_Property_GUID
, UIA_SelectionIsSelectionRequiredPropertyId
},
3504 { &Grid_RowCount_Property_GUID
, UIA_GridRowCountPropertyId
},
3505 { &Grid_ColumnCount_Property_GUID
, UIA_GridColumnCountPropertyId
},
3506 { &GridItem_Row_Property_GUID
, UIA_GridItemRowPropertyId
},
3507 { &GridItem_Column_Property_GUID
, UIA_GridItemColumnPropertyId
},
3508 { &GridItem_RowSpan_Property_GUID
, UIA_GridItemRowSpanPropertyId
},
3509 { &GridItem_ColumnSpan_Property_GUID
, UIA_GridItemColumnSpanPropertyId
},
3510 { &GridItem_Parent_Property_GUID
, UIA_GridItemContainingGridPropertyId
},
3511 { &Dock_DockPosition_Property_GUID
, UIA_DockDockPositionPropertyId
},
3512 { &ExpandCollapse_ExpandCollapseState_Property_GUID
, UIA_ExpandCollapseExpandCollapseStatePropertyId
},
3513 { &MultipleView_CurrentView_Property_GUID
, UIA_MultipleViewCurrentViewPropertyId
},
3514 { &MultipleView_SupportedViews_Property_GUID
, UIA_MultipleViewSupportedViewsPropertyId
},
3515 { &Window_CanMaximize_Property_GUID
, UIA_WindowCanMaximizePropertyId
},
3516 { &Window_CanMinimize_Property_GUID
, UIA_WindowCanMinimizePropertyId
},
3517 { &Window_WindowVisualState_Property_GUID
, UIA_WindowWindowVisualStatePropertyId
},
3518 { &Window_WindowInteractionState_Property_GUID
, UIA_WindowWindowInteractionStatePropertyId
},
3519 { &Window_IsModal_Property_GUID
, UIA_WindowIsModalPropertyId
},
3520 { &Window_IsTopmost_Property_GUID
, UIA_WindowIsTopmostPropertyId
},
3521 { &SelectionItem_IsSelected_Property_GUID
, UIA_SelectionItemIsSelectedPropertyId
},
3522 { &SelectionItem_SelectionContainer_Property_GUID
, UIA_SelectionItemSelectionContainerPropertyId
},
3523 { &Table_RowHeaders_Property_GUID
, UIA_TableRowHeadersPropertyId
},
3524 { &Table_ColumnHeaders_Property_GUID
, UIA_TableColumnHeadersPropertyId
},
3525 { &Table_RowOrColumnMajor_Property_GUID
, UIA_TableRowOrColumnMajorPropertyId
},
3526 { &TableItem_RowHeaderItems_Property_GUID
, UIA_TableItemRowHeaderItemsPropertyId
},
3527 { &TableItem_ColumnHeaderItems_Property_GUID
, UIA_TableItemColumnHeaderItemsPropertyId
},
3528 { &Toggle_ToggleState_Property_GUID
, UIA_ToggleToggleStatePropertyId
},
3529 { &Transform_CanMove_Property_GUID
, UIA_TransformCanMovePropertyId
},
3530 { &Transform_CanResize_Property_GUID
, UIA_TransformCanResizePropertyId
},
3531 { &Transform_CanRotate_Property_GUID
, UIA_TransformCanRotatePropertyId
},
3532 { &IsLegacyIAccessiblePatternAvailable_Property_GUID
, UIA_IsLegacyIAccessiblePatternAvailablePropertyId
},
3533 { &LegacyIAccessible_ChildId_Property_GUID
, UIA_LegacyIAccessibleChildIdPropertyId
},
3534 { &LegacyIAccessible_Name_Property_GUID
, UIA_LegacyIAccessibleNamePropertyId
},
3535 { &LegacyIAccessible_Value_Property_GUID
, UIA_LegacyIAccessibleValuePropertyId
},
3536 { &LegacyIAccessible_Description_Property_GUID
, UIA_LegacyIAccessibleDescriptionPropertyId
},
3537 { &LegacyIAccessible_Role_Property_GUID
, UIA_LegacyIAccessibleRolePropertyId
},
3538 { &LegacyIAccessible_State_Property_GUID
, UIA_LegacyIAccessibleStatePropertyId
},
3539 { &LegacyIAccessible_Help_Property_GUID
, UIA_LegacyIAccessibleHelpPropertyId
},
3540 { &LegacyIAccessible_KeyboardShortcut_Property_GUID
, UIA_LegacyIAccessibleKeyboardShortcutPropertyId
},
3541 { &LegacyIAccessible_Selection_Property_GUID
, UIA_LegacyIAccessibleSelectionPropertyId
},
3542 { &LegacyIAccessible_DefaultAction_Property_GUID
, UIA_LegacyIAccessibleDefaultActionPropertyId
},
3543 { &AriaRole_Property_GUID
, UIA_AriaRolePropertyId
},
3544 { &AriaProperties_Property_GUID
, UIA_AriaPropertiesPropertyId
},
3545 { &IsDataValidForForm_Property_GUID
, UIA_IsDataValidForFormPropertyId
},
3546 { &ControllerFor_Property_GUID
, UIA_ControllerForPropertyId
},
3547 { &DescribedBy_Property_GUID
, UIA_DescribedByPropertyId
},
3548 { &FlowsTo_Property_GUID
, UIA_FlowsToPropertyId
},
3549 { &ProviderDescription_Property_GUID
, UIA_ProviderDescriptionPropertyId
},
3550 { &IsItemContainerPatternAvailable_Property_GUID
, UIA_IsItemContainerPatternAvailablePropertyId
},
3551 { &IsVirtualizedItemPatternAvailable_Property_GUID
, UIA_IsVirtualizedItemPatternAvailablePropertyId
},
3552 { &IsSynchronizedInputPatternAvailable_Property_GUID
, UIA_IsSynchronizedInputPatternAvailablePropertyId
},
3553 /* Implemented on Win8+ */
3554 { &OptimizeForVisualContent_Property_GUID
, UIA_OptimizeForVisualContentPropertyId
},
3555 { &IsObjectModelPatternAvailable_Property_GUID
, UIA_IsObjectModelPatternAvailablePropertyId
},
3556 { &Annotation_AnnotationTypeId_Property_GUID
, UIA_AnnotationAnnotationTypeIdPropertyId
},
3557 { &Annotation_AnnotationTypeName_Property_GUID
, UIA_AnnotationAnnotationTypeNamePropertyId
},
3558 { &Annotation_Author_Property_GUID
, UIA_AnnotationAuthorPropertyId
},
3559 { &Annotation_DateTime_Property_GUID
, UIA_AnnotationDateTimePropertyId
},
3560 { &Annotation_Target_Property_GUID
, UIA_AnnotationTargetPropertyId
},
3561 { &IsAnnotationPatternAvailable_Property_GUID
, UIA_IsAnnotationPatternAvailablePropertyId
},
3562 { &IsTextPattern2Available_Property_GUID
, UIA_IsTextPattern2AvailablePropertyId
},
3563 { &Styles_StyleId_Property_GUID
, UIA_StylesStyleIdPropertyId
},
3564 { &Styles_StyleName_Property_GUID
, UIA_StylesStyleNamePropertyId
},
3565 { &Styles_FillColor_Property_GUID
, UIA_StylesFillColorPropertyId
},
3566 { &Styles_FillPatternStyle_Property_GUID
, UIA_StylesFillPatternStylePropertyId
},
3567 { &Styles_Shape_Property_GUID
, UIA_StylesShapePropertyId
},
3568 { &Styles_FillPatternColor_Property_GUID
, UIA_StylesFillPatternColorPropertyId
},
3569 { &Styles_ExtendedProperties_Property_GUID
, UIA_StylesExtendedPropertiesPropertyId
},
3570 { &IsStylesPatternAvailable_Property_GUID
, UIA_IsStylesPatternAvailablePropertyId
},
3571 { &IsSpreadsheetPatternAvailable_Property_GUID
, UIA_IsSpreadsheetPatternAvailablePropertyId
},
3572 { &SpreadsheetItem_Formula_Property_GUID
, UIA_SpreadsheetItemFormulaPropertyId
},
3573 { &SpreadsheetItem_AnnotationObjects_Property_GUID
, UIA_SpreadsheetItemAnnotationObjectsPropertyId
},
3574 { &SpreadsheetItem_AnnotationTypes_Property_GUID
, UIA_SpreadsheetItemAnnotationTypesPropertyId
},
3575 { &IsSpreadsheetItemPatternAvailable_Property_GUID
, UIA_IsSpreadsheetItemPatternAvailablePropertyId
},
3576 { &Transform2_CanZoom_Property_GUID
, UIA_Transform2CanZoomPropertyId
},
3577 { &IsTransformPattern2Available_Property_GUID
, UIA_IsTransformPattern2AvailablePropertyId
},
3578 { &LiveSetting_Property_GUID
, UIA_LiveSettingPropertyId
},
3579 { &IsTextChildPatternAvailable_Property_GUID
, UIA_IsTextChildPatternAvailablePropertyId
},
3580 { &IsDragPatternAvailable_Property_GUID
, UIA_IsDragPatternAvailablePropertyId
},
3581 { &Drag_IsGrabbed_Property_GUID
, UIA_DragIsGrabbedPropertyId
},
3582 { &Drag_DropEffect_Property_GUID
, UIA_DragDropEffectPropertyId
},
3583 { &Drag_DropEffects_Property_GUID
, UIA_DragDropEffectsPropertyId
},
3584 { &IsDropTargetPatternAvailable_Property_GUID
, UIA_IsDropTargetPatternAvailablePropertyId
},
3585 { &DropTarget_DropTargetEffect_Property_GUID
, UIA_DropTargetDropTargetEffectPropertyId
},
3586 { &DropTarget_DropTargetEffects_Property_GUID
, UIA_DropTargetDropTargetEffectsPropertyId
},
3587 { &Drag_GrabbedItems_Property_GUID
, UIA_DragGrabbedItemsPropertyId
},
3588 { &Transform2_ZoomLevel_Property_GUID
, UIA_Transform2ZoomLevelPropertyId
},
3589 { &Transform2_ZoomMinimum_Property_GUID
, UIA_Transform2ZoomMinimumPropertyId
},
3590 { &Transform2_ZoomMaximum_Property_GUID
, UIA_Transform2ZoomMaximumPropertyId
},
3591 { &FlowsFrom_Property_GUID
, UIA_FlowsFromPropertyId
},
3592 { &IsTextEditPatternAvailable_Property_GUID
, UIA_IsTextEditPatternAvailablePropertyId
},
3593 { &IsPeripheral_Property_GUID
, UIA_IsPeripheralPropertyId
},
3594 /* Implemented on Win10v1507+. */
3595 { &IsCustomNavigationPatternAvailable_Property_GUID
, UIA_IsCustomNavigationPatternAvailablePropertyId
},
3596 { &PositionInSet_Property_GUID
, UIA_PositionInSetPropertyId
},
3597 { &SizeOfSet_Property_GUID
, UIA_SizeOfSetPropertyId
},
3598 { &Level_Property_GUID
, UIA_LevelPropertyId
},
3599 { &AnnotationTypes_Property_GUID
, UIA_AnnotationTypesPropertyId
},
3600 { &AnnotationObjects_Property_GUID
, UIA_AnnotationObjectsPropertyId
},
3601 /* Implemented on Win10v1809+. */
3602 { &LandmarkType_Property_GUID
, UIA_LandmarkTypePropertyId
},
3603 { &LocalizedLandmarkType_Property_GUID
, UIA_LocalizedLandmarkTypePropertyId
},
3604 { &FullDescription_Property_GUID
, UIA_FullDescriptionPropertyId
},
3605 { &FillColor_Property_GUID
, UIA_FillColorPropertyId
},
3606 { &OutlineColor_Property_GUID
, UIA_OutlineColorPropertyId
},
3607 { &FillType_Property_GUID
, UIA_FillTypePropertyId
},
3608 { &VisualEffects_Property_GUID
, UIA_VisualEffectsPropertyId
},
3609 { &OutlineThickness_Property_GUID
, UIA_OutlineThicknessPropertyId
},
3610 { &CenterPoint_Property_GUID
, UIA_CenterPointPropertyId
},
3611 { &Rotation_Property_GUID
, UIA_RotationPropertyId
},
3612 { &Size_Property_GUID
, UIA_SizePropertyId
},
3613 { &IsSelectionPattern2Available_Property_GUID
, UIA_IsSelectionPattern2AvailablePropertyId
},
3614 { &Selection2_FirstSelectedItem_Property_GUID
, UIA_Selection2FirstSelectedItemPropertyId
},
3615 { &Selection2_LastSelectedItem_Property_GUID
, UIA_Selection2LastSelectedItemPropertyId
},
3616 { &Selection2_CurrentSelectedItem_Property_GUID
, UIA_Selection2CurrentSelectedItemPropertyId
},
3617 { &Selection2_ItemCount_Property_GUID
, UIA_Selection2ItemCountPropertyId
},
3618 { &HeadingLevel_Property_GUID
, UIA_HeadingLevelPropertyId
},
3619 { &IsDialog_Property_GUID
, UIA_IsDialogPropertyId
},
3622 static void test_UiaLookupId(void)
3626 for (i
= 0; i
< ARRAY_SIZE(uia_property_lookup_ids
); i
++)
3628 int prop_id
= UiaLookupId(AutomationIdentifierType_Property
, uia_property_lookup_ids
[i
].guid
);
3632 win_skip("No propertyId for GUID %s, skipping further tests.\n", debugstr_guid(uia_property_lookup_ids
[i
].guid
));
3636 ok(prop_id
== uia_property_lookup_ids
[i
].id
, "Unexpected Property id, expected %d, got %d\n",
3637 uia_property_lookup_ids
[i
].id
, prop_id
);
3641 static const struct prov_method_sequence node_from_prov1
[] = {
3642 { &Provider
, PROV_GET_PROVIDER_OPTIONS
},
3646 static const struct prov_method_sequence node_from_prov2
[] = {
3647 { &Provider
, PROV_GET_PROVIDER_OPTIONS
},
3648 /* Win10v1507 and below call this. */
3649 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3650 { &Provider
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3651 { &Provider
, PROV_GET_PROPERTY_VALUE
}, /* UIA_NativeWindowHandlePropertyId */
3652 { &Provider
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3653 /* Only called on Windows versions past Win10v1507. */
3654 { &Provider
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3655 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3659 static const struct prov_method_sequence node_from_prov3
[] = {
3660 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
},
3661 /* Win10v1507 and below call this. */
3662 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3663 { &Provider_child
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3664 { &Provider_child
, PROV_GET_PROPERTY_VALUE
}, /* UIA_NativeWindowHandlePropertyId */
3665 { &Provider_child
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3666 /* Only called on Windows versions past Win10v1507. */
3667 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3668 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3672 static const struct prov_method_sequence node_from_prov4
[] = {
3673 { &Provider
, PROV_GET_PROVIDER_OPTIONS
},
3674 /* Win10v1507 and below call this. */
3675 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3676 { &Provider
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3677 { &Provider
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3678 /* Only called on Windows versions past Win10v1507. */
3679 { &Provider
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3680 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3684 static const struct prov_method_sequence node_from_prov5
[] = {
3685 { &Provider
, PROV_GET_PROVIDER_OPTIONS
},
3686 /* Win10v1507 and below call this. */
3687 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3688 { &Provider
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3689 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3690 /* Win10v1507 and below call this. */
3691 { &Provider2
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3692 { &Provider2
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
, METHOD_TODO
},
3693 { &Provider2
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3694 /* These three are only done on Win10v1507 and below. */
3695 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3696 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3697 { &Provider2
, FRAG_NAVIGATE
, METHOD_OPTIONAL
}, /* NavigateDirection_Parent */
3698 { &Provider
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3699 /* This is only done on Win10v1507. */
3700 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3701 /* Only called on Windows versions past Win10v1507. */
3702 { &Provider
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3703 /* Win10v1507 and below call this. */
3704 { &Provider2
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_ProviderDescriptionPropertyId */
3705 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3709 static const struct prov_method_sequence node_from_prov6
[] = {
3710 { &Provider
, PROV_GET_PROVIDER_OPTIONS
},
3711 /* Win10v1507 and below call this. */
3712 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3713 { &Provider
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3714 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3715 /* Win10v1507 and below call this. */
3716 { &Provider2
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3717 { &Provider2
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
, METHOD_TODO
},
3718 { &Provider2
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3719 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3720 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3721 /* Only called on Windows versions past Win10v1507. */
3722 { &Provider
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
, METHOD_OPTIONAL
},
3723 { &Provider2
, FRAG_NAVIGATE
, METHOD_OPTIONAL
}, /* NavigateDirection_Parent */
3724 { &Provider
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3725 /* This is only done on Win10v1507. */
3726 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3727 /* Only called on Windows versions past Win10v1507. */
3728 { &Provider
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3729 { &Provider2
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3730 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3734 static const struct prov_method_sequence node_from_prov7
[] = {
3735 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
},
3736 /* Win10v1507 and below call this. */
3737 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3738 { &Provider_child
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3739 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3740 /* Win10v1507 and below call this. */
3741 { &Provider2
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3742 { &Provider2
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
, METHOD_TODO
},
3743 { &Provider2
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3744 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3745 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
3746 /* Only called on Windows versions past Win10v1507. */
3747 { &Provider_child
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
, METHOD_OPTIONAL
},
3748 { &Provider2
, FRAG_NAVIGATE
, METHOD_OPTIONAL
}, /* NavigateDirection_Parent */
3749 { &Provider_child
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3750 /* This is only done on Win10v1507. */
3751 { &Provider2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3752 /* Only called on Windows versions past Win10v1507. */
3753 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3754 { &Provider2
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3755 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_TODO
}, /* UIA_ProviderDescriptionPropertyId */
3759 static const struct prov_method_sequence node_from_prov8
[] = {
3760 { &Provider
, PROV_GET_PROVIDER_OPTIONS
},
3761 /* Win10v1507 and below call this. */
3762 { &Provider
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
3763 { &Provider
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
3764 { &Provider
, PROV_GET_PROPERTY_VALUE
}, /* UIA_NativeWindowHandlePropertyId */
3765 { &Provider
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
3766 /* Only called on Windows versions past Win10v1507. */
3767 { &Provider
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
3771 static void check_uia_prop_val(PROPERTYID prop_id
, enum UIAutomationType type
, VARIANT
*v
);
3772 static DWORD WINAPI
uia_node_from_provider_test_com_thread(LPVOID param
)
3774 HUIANODE node
= param
;
3779 * Since this is a node representing an IRawElementProviderSimple with
3780 * ProviderOptions_UseComThreading set, it is only usable in threads that
3781 * have initialized COM.
3783 hr
= UiaGetPropertyValue(node
, UIA_ProcessIdPropertyId
, &v
);
3784 ok(hr
== CO_E_NOTINITIALIZED
, "Unexpected hr %#lx\n", hr
);
3786 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
3788 hr
= UiaGetPropertyValue(node
, UIA_ProcessIdPropertyId
, &v
);
3789 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
3790 check_uia_prop_val(UIA_ProcessIdPropertyId
, UIAutomationType_Int
, &v
);
3793 * When retrieving a UIAutomationType_Element property, if UseComThreading
3794 * is set, we'll get an HUIANODE that will make calls inside of the
3795 * apartment of the node it is retrieved from. I.e, if we received a node
3796 * with UseComThreading set from another node with UseComThreading set
3797 * inside of an STA, the returned node will have all of its methods called
3798 * from the STA thread.
3800 Provider_child
.prov_opts
= ProviderOptions_UseComThreading
| ProviderOptions_ServerSideProvider
;
3801 Provider_child
.expected_tid
= Provider
.expected_tid
;
3802 hr
= UiaGetPropertyValue(node
, UIA_LabeledByPropertyId
, &v
);
3803 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
3804 check_uia_prop_val(UIA_LabeledByPropertyId
, UIAutomationType_Element
, &v
);
3806 /* Unset ProviderOptions_UseComThreading. */
3807 Provider_child
.prov_opts
= ProviderOptions_ServerSideProvider
;
3808 hr
= UiaGetPropertyValue(node
, UIA_LabeledByPropertyId
, &v
);
3809 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
3812 * ProviderOptions_UseComThreading not set, GetPropertyValue will be
3813 * called on the current thread.
3815 Provider_child
.expected_tid
= GetCurrentThreadId();
3816 check_uia_prop_val(UIA_LabeledByPropertyId
, UIAutomationType_Element
, &v
);
3823 static void test_uia_node_from_prov_com_threading(void)
3829 /* Test ProviderOptions_UseComThreading. */
3830 Provider
.hwnd
= NULL
;
3832 Provider
.prov_opts
= ProviderOptions_ServerSideProvider
| ProviderOptions_UseComThreading
;
3833 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
3834 ok_method_sequence(node_from_prov8
, "node_from_prov8");
3837 * On Windows versions prior to Windows 10, UiaNodeFromProvider ignores the
3838 * ProviderOptions_UseComThreading flag.
3842 win_skip("Skipping ProviderOptions_UseComThreading tests for UiaNodeFromProvider.\n");
3843 UiaNodeRelease(node
);
3846 ok(hr
== CO_E_NOTINITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3848 CoInitializeEx(NULL
, COINIT_APARTMENTTHREADED
);
3849 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
3850 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3851 ok(Provider
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
3852 ok_method_sequence(node_from_prov8
, "node_from_prov8");
3854 Provider
.expected_tid
= GetCurrentThreadId();
3855 thread
= CreateThread(NULL
, 0, uia_node_from_provider_test_com_thread
, (void *)node
, 0, NULL
);
3856 while (MsgWaitForMultipleObjects(1, &thread
, FALSE
, INFINITE
, QS_ALLINPUT
) != WAIT_OBJECT_0
)
3859 while(PeekMessageW(&msg
, 0, 0, 0, PM_REMOVE
))
3861 TranslateMessage(&msg
);
3862 DispatchMessageW(&msg
);
3865 CloseHandle(thread
);
3867 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
3868 ok(Provider
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
3869 Provider_child
.expected_tid
= Provider
.expected_tid
= 0;
3873 static void test_UiaNodeFromProvider(void)
3883 cls
.lpfnWndProc
= test_wnd_proc
;
3886 cls
.hInstance
= GetModuleHandleA(NULL
);
3889 cls
.hbrBackground
= NULL
;
3890 cls
.lpszMenuName
= NULL
;
3891 cls
.lpszClassName
= "UiaNodeFromProvider class";
3893 RegisterClassA(&cls
);
3895 hwnd
= CreateWindowA("UiaNodeFromProvider class", "Test window", WS_OVERLAPPEDWINDOW
,
3896 0, 0, 100, 100, NULL
, NULL
, NULL
, NULL
);
3898 /* Run these tests early, we end up in an implicit MTA later. */
3899 test_uia_node_from_prov_com_threading();
3901 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
3903 hr
= UiaNodeFromProvider(NULL
, &node
);
3904 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
3906 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, NULL
);
3907 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
3909 /* Must have a successful call to get_ProviderOptions. */
3910 Provider
.prov_opts
= 0;
3911 node
= (void *)0xdeadbeef;
3912 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
3913 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3914 ok(!node
, "node != NULL\n");
3915 ok_method_sequence(node_from_prov1
, "node_from_prov1");
3917 /* No HWND exposed through Provider. */
3918 Provider
.prov_opts
= ProviderOptions_ServerSideProvider
;
3919 node
= (void *)0xdeadbeef;
3920 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
3921 ok(Provider
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
3923 hr
= UiaGetPropertyValue(node
, UIA_ProviderDescriptionPropertyId
, &v
);
3924 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
3927 check_node_provider_desc_prefix(V_BSTR(&v
), GetCurrentProcessId(), NULL
);
3928 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider", TRUE
);
3932 ok_method_sequence(node_from_prov2
, "node_from_prov2");
3934 /* HUIANODE represents a COM interface. */
3935 ref
= IUnknown_AddRef((IUnknown
*)node
);
3936 ok(ref
== 2, "Unexpected refcnt %ld\n", ref
);
3938 ref
= IUnknown_AddRef((IUnknown
*)node
);
3939 ok(ref
== 3, "Unexpected refcnt %ld\n", ref
);
3941 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
3943 ref
= IUnknown_Release((IUnknown
*)node
);
3944 ok(ref
== 1, "Unexpected refcnt %ld\n", ref
);
3946 ref
= IUnknown_Release((IUnknown
*)node
);
3947 ok(ref
== 0, "Unexpected refcnt %ld\n", ref
);
3948 ok(Provider
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
3951 * No HWND exposed through Provider_child, but it returns a parent from
3952 * NavigateDirection_Parent. Behavior doesn't change.
3954 Provider_child
.prov_opts
= ProviderOptions_ServerSideProvider
;
3955 node
= (void *)0xdeadbeef;
3956 hr
= UiaNodeFromProvider(&Provider_child
.IRawElementProviderSimple_iface
, &node
);
3957 ok(Provider_child
.ref
== 2, "Unexpected refcnt %ld\n", Provider_child
.ref
);
3959 hr
= UiaGetPropertyValue(node
, UIA_ProviderDescriptionPropertyId
, &v
);
3960 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
3963 check_node_provider_desc_prefix(V_BSTR(&v
), GetCurrentProcessId(), NULL
);
3964 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider_child", TRUE
);
3968 ok_method_sequence(node_from_prov3
, "node_from_prov3");
3969 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
3970 ok(Provider_child
.ref
== 1, "Unexpected refcnt %ld\n", Provider_child
.ref
);
3972 /* HWND exposed, but Provider2 not returned from WM_GETOBJECT. */
3973 Provider
.hwnd
= hwnd
;
3975 node
= (void *)0xdeadbeef;
3976 SET_EXPECT(winproc_GETOBJECT_UiaRoot
);
3977 /* Win10v1507 and below send this, Windows 7 sends it twice. */
3978 SET_EXPECT_MULTI(winproc_GETOBJECT_CLIENT
, 2);
3979 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
3980 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3981 ok(Provider
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
3982 todo_wine
CHECK_CALLED(winproc_GETOBJECT_UiaRoot
);
3983 called_winproc_GETOBJECT_CLIENT
= expect_winproc_GETOBJECT_CLIENT
= 0;
3985 hr
= UiaGetPropertyValue(node
, UIA_ProviderDescriptionPropertyId
, &v
);
3986 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
3989 check_node_provider_desc_prefix(V_BSTR(&v
), GetCurrentProcessId(), hwnd
);
3991 /* Newer versions of Windows have "Hwnd(parent link):" */
3992 if (get_provider_desc(V_BSTR(&v
), L
"Hwnd(parent link):", NULL
))
3994 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider", FALSE
);
3995 check_node_provider_desc(V_BSTR(&v
), L
"Nonclient", NULL
, FALSE
);
3996 check_node_provider_desc(V_BSTR(&v
), L
"Hwnd", NULL
, TRUE
);
4000 check_node_provider_desc(V_BSTR(&v
), L
"Annotation", NULL
, TRUE
);
4001 check_node_provider_desc(V_BSTR(&v
), L
"Main", NULL
, FALSE
);
4002 check_node_provider_desc(V_BSTR(&v
), L
"Nonclient", NULL
, FALSE
);
4003 check_node_provider_desc(V_BSTR(&v
), L
"Hwnd", L
"Provider", FALSE
);
4008 ok_method_sequence(node_from_prov4
, "node_from_prov4");
4010 ok(!!node
, "node == NULL\n");
4011 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
4012 ok(Provider
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
4014 /* Return Provider2 in response to WM_GETOBJECT. */
4015 Provider
.hwnd
= Provider2
.hwnd
= hwnd
;
4016 Provider
.prov_opts
= Provider2
.prov_opts
= ProviderOptions_ServerSideProvider
;
4017 prov_root
= &Provider2
.IRawElementProviderSimple_iface
;
4018 node
= (void *)0xdeadbeef;
4019 SET_EXPECT(winproc_GETOBJECT_UiaRoot
);
4020 /* Windows 7 sends this. */
4021 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
4022 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
4023 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4024 todo_wine
CHECK_CALLED(winproc_GETOBJECT_UiaRoot
);
4025 called_winproc_GETOBJECT_CLIENT
= expect_winproc_GETOBJECT_CLIENT
= 0;
4027 /* Win10v1507 and below hold a reference to the root provider for the HWND */
4028 ok(broken(Provider2
.ref
== 2) || Provider2
.ref
== 1, "Unexpected refcnt %ld\n", Provider2
.ref
);
4029 ok(Provider
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
4030 ok(!!node
, "node == NULL\n");
4032 hr
= UiaGetPropertyValue(node
, UIA_ProviderDescriptionPropertyId
, &v
);
4033 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4036 check_node_provider_desc_prefix(V_BSTR(&v
), GetCurrentProcessId(), hwnd
);
4038 /* Newer versions of Windows have "Hwnd(parent link):" */
4039 if (get_provider_desc(V_BSTR(&v
), L
"Hwnd(parent link):", NULL
))
4041 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider", FALSE
);
4042 check_node_provider_desc(V_BSTR(&v
), L
"Nonclient", NULL
, FALSE
);
4043 check_node_provider_desc(V_BSTR(&v
), L
"Hwnd", NULL
, TRUE
);
4047 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider2", TRUE
);
4048 check_node_provider_desc(V_BSTR(&v
), L
"Nonclient", NULL
, FALSE
);
4049 check_node_provider_desc(V_BSTR(&v
), L
"Hwnd", L
"Provider", FALSE
);
4054 ok_method_sequence(node_from_prov5
, "node_from_prov5");
4056 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
4057 ok(Provider
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
4058 ok(Provider2
.ref
== 1, "Unexpected refcnt %ld\n", Provider2
.ref
);
4061 * Windows 10 newer than v1507 only matches older behavior if
4062 * Provider is a ClientSideProvider.
4064 Provider
.prov_opts
= ProviderOptions_ClientSideProvider
;
4065 Provider2
.prov_opts
= ProviderOptions_ServerSideProvider
;
4066 prov_root
= &Provider2
.IRawElementProviderSimple_iface
;
4067 node
= (void *)0xdeadbeef;
4068 SET_EXPECT(winproc_GETOBJECT_UiaRoot
);
4069 /* Windows 7 sends this. */
4070 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
4071 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
4072 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4073 todo_wine
CHECK_CALLED(winproc_GETOBJECT_UiaRoot
);
4074 called_winproc_GETOBJECT_CLIENT
= expect_winproc_GETOBJECT_CLIENT
= 0;
4076 hr
= UiaGetPropertyValue(node
, UIA_ProviderDescriptionPropertyId
, &v
);
4077 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4080 check_node_provider_desc_prefix(V_BSTR(&v
), GetCurrentProcessId(), hwnd
);
4081 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider2", TRUE
);
4082 check_node_provider_desc(V_BSTR(&v
), L
"Nonclient", NULL
, FALSE
);
4083 check_node_provider_desc(V_BSTR(&v
), L
"Hwnd", L
"Provider", FALSE
);
4086 ok_method_sequence(node_from_prov6
, "node_from_prov6");
4088 todo_wine
ok(Provider2
.ref
== 2, "Unexpected refcnt %ld\n", Provider2
.ref
);
4089 ok(Provider
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
4091 ok(!!node
, "node == NULL\n");
4092 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
4093 ok(Provider
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
4094 ok(Provider2
.ref
== 1, "Unexpected refcnt %ld\n", Provider2
.ref
);
4096 /* Provider_child has a parent, so it will be "(parent link)". */
4097 Provider_child
.prov_opts
= ProviderOptions_ClientSideProvider
;
4098 Provider_child
.hwnd
= hwnd
;
4099 Provider2
.prov_opts
= ProviderOptions_ServerSideProvider
;
4100 prov_root
= &Provider2
.IRawElementProviderSimple_iface
;
4101 node
= (void *)0xdeadbeef;
4102 SET_EXPECT(winproc_GETOBJECT_UiaRoot
);
4103 /* Windows 7 sends this. */
4104 SET_EXPECT(winproc_GETOBJECT_CLIENT
);
4105 hr
= UiaNodeFromProvider(&Provider_child
.IRawElementProviderSimple_iface
, &node
);
4106 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4107 todo_wine
CHECK_CALLED(winproc_GETOBJECT_UiaRoot
);
4108 called_winproc_GETOBJECT_CLIENT
= expect_winproc_GETOBJECT_CLIENT
= 0;
4110 hr
= UiaGetPropertyValue(node
, UIA_ProviderDescriptionPropertyId
, &v
);
4111 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4114 check_node_provider_desc_prefix(V_BSTR(&v
), GetCurrentProcessId(), hwnd
);
4115 check_node_provider_desc(V_BSTR(&v
), L
"Main", L
"Provider2", FALSE
);
4116 check_node_provider_desc(V_BSTR(&v
), L
"Nonclient", NULL
, FALSE
);
4117 check_node_provider_desc(V_BSTR(&v
), L
"Hwnd", L
"Provider_child", TRUE
);
4120 ok_method_sequence(node_from_prov7
, "node_from_prov7");
4122 todo_wine
ok(Provider2
.ref
== 2, "Unexpected refcnt %ld\n", Provider2
.ref
);
4123 ok(Provider_child
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
4125 ok(!!node
, "node == NULL\n");
4126 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
4127 ok(Provider_child
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
4128 ok(Provider2
.ref
== 1, "Unexpected refcnt %ld\n", Provider2
.ref
);
4131 DestroyWindow(hwnd
);
4132 UnregisterClassA("UiaNodeFromProvider class", NULL
);
4136 /* Sequence for types other than UIAutomationType_Element. */
4137 static const struct prov_method_sequence get_prop_seq
[] = {
4138 { &Provider
, PROV_GET_PROPERTY_VALUE
},
4142 /* Sequence for getting a property that returns an invalid type. */
4143 static const struct prov_method_sequence get_prop_invalid_type_seq
[] = {
4144 { &Provider
, PROV_GET_PROPERTY_VALUE
},
4145 /* Windows 7 calls this. */
4146 { &Provider
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
4150 /* UIAutomationType_Element sequence. */
4151 static const struct prov_method_sequence get_elem_prop_seq
[] = {
4152 { &Provider
, PROV_GET_PROPERTY_VALUE
},
4153 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
},
4154 /* Win10v1507 and below call this. */
4155 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
4156 { &Provider_child
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
4157 { &Provider_child
, PROV_GET_PROPERTY_VALUE
}, /* UIA_NativeWindowHandlePropertyId */
4158 { &Provider_child
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
4159 /* Only called on Windows versions past Win10v1507. */
4160 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
, METHOD_OPTIONAL
},
4161 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
},
4165 /* UIAutomationType_ElementArray sequence. */
4166 static const struct prov_method_sequence get_elem_arr_prop_seq
[] = {
4167 { &Provider
, PROV_GET_PROPERTY_VALUE
},
4168 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
},
4169 /* Win10v1507 and below call this. */
4170 { &Provider_child
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
4171 { &Provider_child
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
4172 { &Provider_child
, PROV_GET_PROPERTY_VALUE
}, /* UIA_NativeWindowHandlePropertyId */
4173 { &Provider_child
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
4174 { &Provider_child
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
4175 { &Provider_child2
, PROV_GET_PROVIDER_OPTIONS
},
4176 /* Win10v1507 and below call this. */
4177 { &Provider_child2
, PROV_GET_PROPERTY_VALUE
, METHOD_OPTIONAL
}, /* UIA_NativeWindowHandlePropertyId */
4178 { &Provider_child2
, PROV_GET_HOST_RAW_ELEMENT_PROVIDER
},
4179 { &Provider_child2
, PROV_GET_PROPERTY_VALUE
}, /* UIA_NativeWindowHandlePropertyId */
4180 { &Provider_child2
, FRAG_NAVIGATE
, METHOD_TODO
}, /* NavigateDirection_Parent */
4181 { &Provider_child2
, PROV_GET_PROVIDER_OPTIONS
, METHOD_TODO
},
4182 { &Provider_child
, PROV_GET_PROPERTY_VALUE
},
4183 { &Provider_child2
, PROV_GET_PROPERTY_VALUE
},
4187 static void check_uia_prop_val(PROPERTYID prop_id
, enum UIAutomationType type
, VARIANT
*v
)
4193 case UIAutomationType_String
:
4194 ok(V_VT(v
) == VT_BSTR
, "Unexpected VT %d\n", V_VT(v
));
4195 ok(!lstrcmpW(V_BSTR(v
), uia_bstr_prop_str
), "Unexpected BSTR %s\n", wine_dbgstr_w(V_BSTR(v
)));
4196 ok_method_sequence(get_prop_seq
, NULL
);
4199 case UIAutomationType_Bool
:
4200 ok(V_VT(v
) == VT_BOOL
, "Unexpected VT %d\n", V_VT(v
));
4202 /* UIA_IsKeyboardFocusablePropertyId is broken on Win8 and Win10v1507. */
4203 if (prop_id
== UIA_IsKeyboardFocusablePropertyId
)
4204 ok(check_variant_bool(v
, TRUE
) || broken(check_variant_bool(v
, FALSE
)),
4205 "Unexpected BOOL %#x\n", V_BOOL(v
));
4207 ok(check_variant_bool(v
, TRUE
), "Unexpected BOOL %#x\n", V_BOOL(v
));
4208 ok_method_sequence(get_prop_seq
, NULL
);
4211 case UIAutomationType_Int
:
4212 ok(V_VT(v
) == VT_I4
, "Unexpected VT %d\n", V_VT(v
));
4214 if (prop_id
== UIA_NativeWindowHandlePropertyId
)
4215 ok(ULongToHandle(V_I4(v
)) == Provider
.hwnd
, "Unexpected I4 %#lx\n", V_I4(v
));
4217 ok(V_I4(v
) == uia_i4_prop_val
, "Unexpected I4 %#lx\n", V_I4(v
));
4218 ok_method_sequence(get_prop_seq
, NULL
);
4221 case UIAutomationType_IntArray
:
4222 ok(V_VT(v
) == (VT_ARRAY
| VT_I4
), "Unexpected VT %d\n", V_VT(v
));
4224 for (idx
= 0; idx
< ARRAY_SIZE(uia_i4_arr_prop_val
); idx
++)
4228 SafeArrayGetElement(V_ARRAY(v
), &idx
, &val
);
4229 ok(val
== uia_i4_arr_prop_val
[idx
], "Unexpected I4 %#lx at idx %ld\n", val
, idx
);
4231 ok_method_sequence(get_prop_seq
, NULL
);
4234 case UIAutomationType_Double
:
4235 ok(V_VT(v
) == VT_R8
, "Unexpected VT %d\n", V_VT(v
));
4236 ok(V_R8(v
) == uia_r8_prop_val
, "Unexpected R8 %lf\n", V_R8(v
));
4237 ok_method_sequence(get_prop_seq
, NULL
);
4240 case UIAutomationType_DoubleArray
:
4241 ok(V_VT(v
) == (VT_ARRAY
| VT_R8
), "Unexpected VT %d\n", V_VT(v
));
4242 for (idx
= 0; idx
< ARRAY_SIZE(uia_r8_arr_prop_val
); idx
++)
4246 SafeArrayGetElement(V_ARRAY(v
), &idx
, &val
);
4247 ok(val
== uia_r8_arr_prop_val
[idx
], "Unexpected R8 %lf at idx %ld\n", val
, idx
);
4249 ok_method_sequence(get_prop_seq
, NULL
);
4252 case UIAutomationType_Element
:
4259 ok(V_VT(v
) == VT_I8
, "Unexpected VT %d\n", V_VT(v
));
4260 tmp_node
= (HUIANODE
)V_I8(v
);
4262 ok(V_VT(v
) == VT_I4
, "Unexpected VT %d\n", V_VT(v
));
4263 tmp_node
= (HUIANODE
)V_I4(v
);
4265 ok(Provider_child
.ref
== 2, "Unexpected refcnt %ld\n", Provider_child
.ref
);
4267 hr
= UiaGetPropertyValue(tmp_node
, UIA_ControlTypePropertyId
, &v1
);
4268 ok(hr
== S_OK
, "Unexpected hr %#lx\n", hr
);
4269 ok(V_VT(&v1
) == VT_I4
, "Unexpected VT %d\n", V_VT(&v1
));
4270 ok(V_I4(&v1
) == uia_i4_prop_val
, "Unexpected I4 %#lx\n", V_I4(&v1
));
4272 ok(UiaNodeRelease(tmp_node
), "Failed to release node\n");
4273 ok(Provider_child
.ref
== 1, "Unexpected refcnt %ld\n", Provider_child
.ref
);
4274 ok_method_sequence(get_elem_prop_seq
, NULL
);
4278 case UIAutomationType_ElementArray
:
4279 ok(V_VT(v
) == (VT_ARRAY
| VT_UNKNOWN
), "Unexpected VT %d\n", V_VT(v
));
4280 if (V_VT(v
) != (VT_ARRAY
| VT_UNKNOWN
))
4283 ok(Provider_child
.ref
== 2, "Unexpected refcnt %ld\n", Provider_child
.ref
);
4284 ok(Provider_child2
.ref
== 2, "Unexpected refcnt %ld\n", Provider_child2
.ref
);
4285 for (idx
= 0; idx
< ARRAY_SIZE(uia_unk_arr_prop_val
); idx
++)
4291 SafeArrayGetElement(V_ARRAY(v
), &idx
, &tmp_node
);
4293 hr
= UiaGetPropertyValue(tmp_node
, UIA_ControlTypePropertyId
, &v1
);
4294 ok(hr
== S_OK
, "node[%ld] Unexpected hr %#lx\n", idx
, hr
);
4295 ok(V_VT(&v1
) == VT_I4
, "node[%ld] Unexpected VT %d\n", idx
, V_VT(&v1
));
4296 ok(V_I4(&v1
) == uia_i4_prop_val
, "node[%ld] Unexpected I4 %#lx\n", idx
, V_I4(&v1
));
4298 ok(UiaNodeRelease(tmp_node
), "Failed to release node[%ld]\n", idx
);
4303 ok(Provider_child
.ref
== 1, "Unexpected refcnt %ld\n", Provider_child
.ref
);
4304 ok(Provider_child2
.ref
== 1, "Unexpected refcnt %ld\n", Provider_child2
.ref
);
4305 ok_method_sequence(get_elem_arr_prop_seq
, NULL
);
4316 struct uia_element_property
{
4317 const GUID
*prop_guid
;
4318 enum UIAutomationType type
;
4322 static const struct uia_element_property element_properties
[] = {
4323 { &ProcessId_Property_GUID
, UIAutomationType_Int
, TRUE
},
4324 { &ControlType_Property_GUID
, UIAutomationType_Int
},
4325 { &LocalizedControlType_Property_GUID
, UIAutomationType_String
, TRUE
},
4326 { &Name_Property_GUID
, UIAutomationType_String
},
4327 { &AcceleratorKey_Property_GUID
, UIAutomationType_String
},
4328 { &AccessKey_Property_GUID
, UIAutomationType_String
},
4329 { &HasKeyboardFocus_Property_GUID
, UIAutomationType_Bool
},
4330 { &IsKeyboardFocusable_Property_GUID
, UIAutomationType_Bool
},
4331 { &IsEnabled_Property_GUID
, UIAutomationType_Bool
},
4332 { &AutomationId_Property_GUID
, UIAutomationType_String
},
4333 { &ClassName_Property_GUID
, UIAutomationType_String
},
4334 { &HelpText_Property_GUID
, UIAutomationType_String
},
4335 { &Culture_Property_GUID
, UIAutomationType_Int
},
4336 { &IsControlElement_Property_GUID
, UIAutomationType_Bool
},
4337 { &IsContentElement_Property_GUID
, UIAutomationType_Bool
},
4338 { &LabeledBy_Property_GUID
, UIAutomationType_Element
},
4339 { &IsPassword_Property_GUID
, UIAutomationType_Bool
},
4340 { &NewNativeWindowHandle_Property_GUID
, UIAutomationType_Int
},
4341 { &ItemType_Property_GUID
, UIAutomationType_String
},
4342 { &IsOffscreen_Property_GUID
, UIAutomationType_Bool
},
4343 { &Orientation_Property_GUID
, UIAutomationType_Int
},
4344 { &FrameworkId_Property_GUID
, UIAutomationType_String
},
4345 { &IsRequiredForForm_Property_GUID
, UIAutomationType_Bool
},
4346 { &ItemStatus_Property_GUID
, UIAutomationType_String
},
4347 { &AriaRole_Property_GUID
, UIAutomationType_String
},
4348 { &AriaProperties_Property_GUID
, UIAutomationType_String
},
4349 { &IsDataValidForForm_Property_GUID
, UIAutomationType_Bool
},
4350 { &ControllerFor_Property_GUID
, UIAutomationType_ElementArray
},
4351 { &DescribedBy_Property_GUID
, UIAutomationType_ElementArray
},
4352 { &FlowsTo_Property_GUID
, UIAutomationType_ElementArray
},
4353 /* Implemented on Win8+ */
4354 { &OptimizeForVisualContent_Property_GUID
, UIAutomationType_Bool
},
4355 { &LiveSetting_Property_GUID
, UIAutomationType_Int
},
4356 { &FlowsFrom_Property_GUID
, UIAutomationType_ElementArray
},
4357 { &IsPeripheral_Property_GUID
, UIAutomationType_Bool
},
4358 /* Implemented on Win10v1507+. */
4359 { &PositionInSet_Property_GUID
, UIAutomationType_Int
},
4360 { &SizeOfSet_Property_GUID
, UIAutomationType_Int
},
4361 { &Level_Property_GUID
, UIAutomationType_Int
},
4362 { &AnnotationTypes_Property_GUID
, UIAutomationType_IntArray
},
4363 { &AnnotationObjects_Property_GUID
, UIAutomationType_ElementArray
},
4364 /* Implemented on Win10v1809+. */
4365 { &LandmarkType_Property_GUID
, UIAutomationType_Int
},
4366 { &LocalizedLandmarkType_Property_GUID
, UIAutomationType_String
, TRUE
},
4367 { &FullDescription_Property_GUID
, UIAutomationType_String
},
4368 { &FillColor_Property_GUID
, UIAutomationType_Int
},
4369 { &OutlineColor_Property_GUID
, UIAutomationType_IntArray
},
4370 { &FillType_Property_GUID
, UIAutomationType_Int
},
4371 { &VisualEffects_Property_GUID
, UIAutomationType_Int
},
4372 { &OutlineThickness_Property_GUID
, UIAutomationType_DoubleArray
},
4373 { &Rotation_Property_GUID
, UIAutomationType_Double
},
4374 { &Size_Property_GUID
, UIAutomationType_DoubleArray
},
4375 { &HeadingLevel_Property_GUID
, UIAutomationType_Int
},
4376 { &IsDialog_Property_GUID
, UIAutomationType_Bool
},
4379 static void test_UiaGetPropertyValue(void)
4381 const struct uia_element_property
*elem_prop
;
4389 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
4391 Provider
.prov_opts
= ProviderOptions_ServerSideProvider
;
4392 Provider_child
.prov_opts
= Provider_child2
.prov_opts
= ProviderOptions_ServerSideProvider
;
4393 Provider
.hwnd
= Provider_child
.hwnd
= Provider_child2
.hwnd
= NULL
;
4394 node
= (void *)0xdeadbeef;
4395 hr
= UiaNodeFromProvider(&Provider
.IRawElementProviderSimple_iface
, &node
);
4396 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4397 ok(Provider
.ref
== 2, "Unexpected refcnt %ld\n", Provider
.ref
);
4398 ok_method_sequence(node_from_prov8
, NULL
);
4400 hr
= UiaGetReservedNotSupportedValue(&unk_ns
);
4401 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4403 for (i
= 0; i
< ARRAY_SIZE(element_properties
); i
++)
4405 elem_prop
= &element_properties
[i
];
4407 Provider
.ret_invalid_prop_type
= FALSE
;
4409 prop_id
= UiaLookupId(AutomationIdentifierType_Property
, elem_prop
->prop_guid
);
4412 win_skip("No propertyId for GUID %s, skipping further tests.\n", debugstr_guid(elem_prop
->prop_guid
));
4415 winetest_push_context("prop_id %d", prop_id
);
4416 hr
= UiaGetPropertyValue(node
, prop_id
, &v
);
4417 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4418 check_uia_prop_val(prop_id
, elem_prop
->type
, &v
);
4421 * Some properties have special behavior if an invalid value is
4422 * returned, skip them here.
4424 if (!elem_prop
->skip_invalid
)
4426 Provider
.ret_invalid_prop_type
= TRUE
;
4427 hr
= UiaGetPropertyValue(node
, prop_id
, &v
);
4428 if (hr
== E_NOTIMPL
)
4429 todo_wine
ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4431 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4434 ok_method_sequence(get_prop_invalid_type_seq
, NULL
);
4435 ok(V_VT(&v
) == VT_UNKNOWN
, "Unexpected vt %d\n", V_VT(&v
));
4436 ok(V_UNKNOWN(&v
) == unk_ns
, "unexpected IUnknown %p\n", V_UNKNOWN(&v
));
4441 winetest_pop_context();
4444 Provider
.ret_invalid_prop_type
= FALSE
;
4445 ok(UiaNodeRelease(node
), "UiaNodeRelease returned FALSE\n");
4446 ok(Provider
.ref
== 1, "Unexpected refcnt %ld\n", Provider
.ref
);
4448 IUnknown_Release(unk_ns
);
4452 START_TEST(uiautomation
)
4454 HMODULE uia_dll
= LoadLibraryA("uiautomationcore.dll");
4455 BOOL (WINAPI
*pImmDisableIME
)(DWORD
);
4456 HMODULE hModuleImm32
;
4458 /* Make sure COM isn't initialized by imm32. */
4459 hModuleImm32
= LoadLibraryA("imm32.dll");
4461 pImmDisableIME
= (void *)GetProcAddress(hModuleImm32
, "ImmDisableIME");
4465 pImmDisableIME
= NULL
;
4466 FreeLibrary(hModuleImm32
);
4468 test_UiaHostProviderFromHwnd();
4469 test_uia_reserved_value_ifaces();
4471 test_UiaNodeFromProvider();
4472 test_UiaGetPropertyValue();
4475 pUiaProviderFromIAccessible
= (void *)GetProcAddress(uia_dll
, "UiaProviderFromIAccessible");
4476 if (pUiaProviderFromIAccessible
)
4477 test_UiaProviderFromIAccessible();
4479 win_skip("UiaProviderFromIAccessible not exported by uiautomationcore.dll\n");
4481 FreeLibrary(uia_dll
);