uiautomationcore: Retrieve HWND from HUIANODE provider.
[wine.git] / dlls / uiautomationcore / tests / uiautomation.c
blob948198faea0121a627d0ffc839e1eb807efc6c30
1 /*
2 * UI Automation tests
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
21 #define COBJMACROS
23 #include "windows.h"
24 #include "initguid.h"
25 #include "uiautomation.h"
26 #include "ocidl.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) \
43 do { \
44 ok(expect_ ##func, "unexpected call " #func "\n"); \
45 called_ ## func++; \
46 }while(0)
48 #define CHECK_EXPECT(func) \
49 do { \
50 CHECK_EXPECT2(func); \
51 expect_ ## func--; \
52 }while(0)
54 #define CHECK_CALLED(func) \
55 do { \
56 ok(called_ ## func, "expected " #func "\n"); \
57 expect_ ## func = called_ ## func = 0; \
58 }while(0)
60 #define CHECK_CALLED_MULTI(func, num) \
61 do { \
62 ok(called_ ## func == num, "expected " #func " %d times (got %d)\n", num, called_ ## func); \
63 expect_ ## func = called_ ## func = 0; \
64 }while(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)
105 return TRUE;
107 return FALSE;
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))
113 return TRUE;
115 return FALSE;
118 static BOOL iface_cmp(IUnknown *iface1, IUnknown *iface2)
120 IUnknown *unk1, *unk2;
121 BOOL cmp;
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);
129 return cmp;
132 static struct Accessible
134 IAccessible IAccessible_iface;
135 IAccessible2 IAccessible2_iface;
136 IOleWindow IOleWindow_iface;
137 IServiceProvider IServiceProvider_iface;
138 LONG ref;
140 IAccessible *parent;
141 HWND acc_hwnd;
142 HWND ow_hwnd;
143 INT role;
144 INT state;
145 LONG child_count;
146 LPCWSTR name;
147 LONG left, top, width, height;
148 BOOL enable_ia2;
149 LONG unique_id;
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);
161 *obj = NULL;
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))
172 *obj = iface;
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;
179 else
180 return E_NOINTERFACE;
182 IAccessible_AddRef(iface);
183 return S_OK;
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");
201 return E_NOTIMPL;
204 static HRESULT WINAPI Accessible_GetTypeInfo(IAccessible *iface, UINT iTInfo,
205 LCID lcid, ITypeInfo **out_tinfo)
207 ok(0, "unexpected call\n");
208 return E_NOTIMPL;
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");
215 return E_NOTIMPL;
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");
223 return E_NOTIMPL;
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);
236 else
237 CHECK_EXPECT(Accessible_get_accParent);
239 if (This->parent)
240 return IAccessible_QueryInterface(This->parent, &IID_IDispatch, (void **)out_parent);
242 *out_parent = NULL;
243 return S_FALSE;
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);
256 else
257 CHECK_EXPECT(Accessible_get_accChildCount);
259 if (This->child_count)
261 *out_count = This->child_count;
262 return S_OK;
265 return E_NOTIMPL;
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");
276 *out_child = NULL;
277 if (V_VT(&child_id) != VT_I4)
278 return E_INVALIDARG;
280 if (This == &Accessible)
282 switch (V_I4(&child_id))
284 case CHILDID_SELF:
285 return IAccessible_QueryInterface(&This->IAccessible_iface, &IID_IDispatch, (void **)out_child);
287 /* Simple element children. */
288 case 1:
289 case 3:
290 return S_FALSE;
292 case 2:
293 return IAccessible_QueryInterface(&Accessible_child.IAccessible_iface, &IID_IDispatch, (void **)out_child);
295 case 4:
296 return IAccessible_QueryInterface(&Accessible_child2.IAccessible_iface, &IID_IDispatch, (void **)out_child);
298 default:
299 break;
303 return E_NOTIMPL;
306 static HRESULT WINAPI Accessible_get_accName(IAccessible *iface, VARIANT child_id,
307 BSTR *out_name)
309 struct Accessible *This = impl_from_Accessible(iface);
311 *out_name = NULL;
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);
318 else
319 CHECK_EXPECT(Accessible_get_accName);
321 if (This->name)
323 *out_name = SysAllocString(This->name);
324 return S_OK;
327 return E_NOTIMPL;
330 static HRESULT WINAPI Accessible_get_accValue(IAccessible *iface, VARIANT child_id,
331 BSTR *out_value)
333 ok(0, "unexpected call\n");
334 return E_NOTIMPL;
337 static HRESULT WINAPI Accessible_get_accDescription(IAccessible *iface, VARIANT child_id,
338 BSTR *out_description)
340 ok(0, "unexpected call\n");
341 return E_NOTIMPL;
344 static HRESULT WINAPI Accessible_get_accRole(IAccessible *iface, VARIANT child_id,
345 VARIANT *out_role)
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);
355 else
356 CHECK_EXPECT(Accessible_get_accRole);
358 if (This->role)
360 V_VT(out_role) = VT_I4;
361 V_I4(out_role) = This->role;
362 return S_OK;
365 return E_NOTIMPL;
368 static HRESULT WINAPI Accessible_get_accState(IAccessible *iface, VARIANT child_id,
369 VARIANT *out_state)
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);
379 else
380 CHECK_EXPECT(Accessible_get_accState);
382 if (V_VT(&child_id) != VT_I4)
383 return E_INVALIDARG;
385 if (This == &Accessible && V_I4(&child_id) != CHILDID_SELF)
387 switch (V_I4(&child_id))
389 case 1:
390 V_VT(out_state) = VT_I4;
391 V_I4(out_state) = STATE_SYSTEM_INVISIBLE;
392 break;
394 case 3:
395 V_VT(out_state) = VT_I4;
396 V_I4(out_state) = STATE_SYSTEM_FOCUSABLE;
397 break;
399 default:
400 return E_INVALIDARG;
403 return S_OK;
406 if (This->state)
408 V_VT(out_state) = VT_I4;
409 V_I4(out_state) = This->state;
410 return S_OK;
413 return E_NOTIMPL;
416 static HRESULT WINAPI Accessible_get_accHelp(IAccessible *iface, VARIANT child_id,
417 BSTR *out_help)
419 ok(0, "unexpected call\n");
420 return E_NOTIMPL;
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");
427 return E_NOTIMPL;
430 static HRESULT WINAPI Accessible_get_accKeyboardShortcut(IAccessible *iface, VARIANT child_id,
431 BSTR *out_kbd_shortcut)
433 ok(0, "unexpected call\n");
434 return E_NOTIMPL;
437 static HRESULT WINAPI Accessible_get_accFocus(IAccessible *iface, VARIANT *pchild_id)
439 ok(0, "unexpected call\n");
440 return E_NOTIMPL;
443 static HRESULT WINAPI Accessible_get_accSelection(IAccessible *iface, VARIANT *out_selection)
445 ok(0, "unexpected call\n");
446 return E_NOTIMPL;
449 static HRESULT WINAPI Accessible_get_accDefaultAction(IAccessible *iface, VARIANT child_id,
450 BSTR *out_default_action)
452 ok(0, "unexpected call\n");
453 return E_NOTIMPL;
456 static HRESULT WINAPI Accessible_accSelect(IAccessible *iface, LONG select_flags,
457 VARIANT child_id)
459 ok(0, "unexpected call\n");
460 return E_NOTIMPL;
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);
474 else
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;
483 return S_OK;
486 return E_NOTIMPL;
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);
498 else
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) &&
507 This->acc_hwnd)
509 V_VT(out_var) = VT_I4;
510 V_I4(out_var) = HandleToUlong(This->acc_hwnd);
511 return S_OK;
513 return S_FALSE;
516 static HRESULT WINAPI Accessible_accHitTest(IAccessible *iface, LONG left, LONG top,
517 VARIANT *out_child_id)
519 ok(0, "unexpected call\n");
520 return E_NOTIMPL;
523 static HRESULT WINAPI Accessible_accDoDefaultAction(IAccessible *iface, VARIANT child_id)
525 ok(0, "unexpected call\n");
526 return E_NOTIMPL;
529 static HRESULT WINAPI Accessible_put_accName(IAccessible *iface, VARIANT child_id,
530 BSTR name)
532 ok(0, "unexpected call\n");
533 return E_NOTIMPL;
536 static HRESULT WINAPI Accessible_put_accValue(IAccessible *iface, VARIANT child_id,
537 BSTR value)
539 ok(0, "unexpected call\n");
540 return E_NOTIMPL;
543 static IAccessibleVtbl AccessibleVtbl = {
544 Accessible_QueryInterface,
545 Accessible_AddRef,
546 Accessible_Release,
547 Accessible_GetTypeInfoCount,
548 Accessible_GetTypeInfo,
549 Accessible_GetIDsOfNames,
550 Accessible_Invoke,
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,
615 lcid, rg_disp_id);
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,
647 BSTR *out_name)
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,
654 BSTR *out_value)
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,
668 VARIANT *out_role)
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,
675 VARIANT *out_state)
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,
682 BSTR *out_help)
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,
693 out_topic_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,
701 out_kbd_shortcut);
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,
721 out_default_action);
724 static HRESULT WINAPI Accessible2_accSelect(IAccessible2 *iface, LONG select_flags,
725 VARIANT child_id)
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,
744 out_var);
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,
761 BSTR name)
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,
768 BSTR value)
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");
777 return E_NOTIMPL;
780 static HRESULT WINAPI Accessible2_get_relation(IAccessible2 *iface, LONG relation_idx,
781 IAccessibleRelation **out_relation)
783 ok(0, "unexpected call\n");
784 return E_NOTIMPL;
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");
791 return E_NOTIMPL;
794 static HRESULT WINAPI Accessible2_role(IAccessible2 *iface, LONG *out_role)
796 ok(0, "unexpected call\n");
797 return E_NOTIMPL;
800 static HRESULT WINAPI Accessible2_scrollTo(IAccessible2 *iface, enum IA2ScrollType scroll_type)
802 ok(0, "unexpected call\n");
803 return E_NOTIMPL;
806 static HRESULT WINAPI Accessible2_scrollToPoint(IAccessible2 *iface,
807 enum IA2CoordinateType coordinate_type, LONG x, LONG y)
809 ok(0, "unexpected call\n");
810 return E_NOTIMPL;
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");
817 return E_NOTIMPL;
820 static HRESULT WINAPI Accessible2_get_states(IAccessible2 *iface, AccessibleStates *out_states)
822 ok(0, "unexpected call\n");
823 return E_NOTIMPL;
826 static HRESULT WINAPI Accessible2_get_extendedRole(IAccessible2 *iface, BSTR *out_extended_role)
828 ok(0, "unexpected call\n");
829 return E_NOTIMPL;
832 static HRESULT WINAPI Accessible2_get_localizedExtendedRole(IAccessible2 *iface,
833 BSTR *out_localized_extended_role)
835 ok(0, "unexpected call\n");
836 return E_NOTIMPL;
839 static HRESULT WINAPI Accessible2_get_nExtendedStates(IAccessible2 *iface, LONG *out_nExtendedStates)
841 ok(0, "unexpected call\n");
842 return E_NOTIMPL;
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");
849 return E_NOTIMPL;
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");
856 return E_NOTIMPL;
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);
865 else
866 CHECK_EXPECT(Accessible_get_uniqueID);
868 *out_unique_id = 0;
869 if (This->unique_id)
871 *out_unique_id = This->unique_id;
872 return S_OK;
875 return E_NOTIMPL;
878 static HRESULT WINAPI Accessible2_get_windowHandle(IAccessible2 *iface, HWND *out_hwnd)
880 ok(0, "unexpected call\n");
881 return E_NOTIMPL;
884 static HRESULT WINAPI Accessible2_get_indexInParent(IAccessible2 *iface, LONG *out_idx_in_parent)
886 ok(0, "unexpected call\n");
887 return E_NOTIMPL;
890 static HRESULT WINAPI Accessible2_get_locale(IAccessible2 *iface, IA2Locale *out_locale)
892 ok(0, "unexpected call\n");
893 return E_NOTIMPL;
896 static HRESULT WINAPI Accessible2_get_attributes(IAccessible2 *iface, BSTR *out_attributes)
898 ok(0, "unexpected call\n");
899 return E_NOTIMPL;
902 static const IAccessible2Vtbl Accessible2Vtbl = {
903 Accessible2_QueryInterface,
904 Accessible2_AddRef,
905 Accessible2_Release,
906 Accessible2_GetTypeInfoCount,
907 Accessible2_GetTypeInfo,
908 Accessible2_GetIDsOfNames,
909 Accessible2_Invoke,
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,
934 Accessible2_role,
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)
984 return E_NOTIMPL;
987 static const IOleWindowVtbl OleWindowVtbl = {
988 OleWindow_QueryInterface,
989 OleWindow_AddRef,
990 OleWindow_Release,
991 OleWindow_GetWindow,
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) &&
1024 This->enable_ia2)
1025 return IAccessible_QueryInterface(&This->IAccessible_iface, riid, obj);
1027 return E_NOTIMPL;
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 },
1041 { &OleWindowVtbl },
1042 { &ServiceProviderVtbl },
1044 NULL,
1045 0, 0,
1046 0, 0, 0, NULL,
1047 0, 0, 0, 0,
1048 FALSE, 0,
1051 static struct Accessible Accessible2 =
1053 { &AccessibleVtbl },
1054 { &Accessible2Vtbl },
1055 { &OleWindowVtbl },
1056 { &ServiceProviderVtbl },
1058 NULL,
1059 0, 0,
1060 0, 0, 0, NULL,
1061 0, 0, 0, 0,
1062 FALSE, 0,
1065 static struct Accessible Accessible_child =
1067 { &AccessibleVtbl },
1068 { &Accessible2Vtbl },
1069 { &OleWindowVtbl },
1070 { &ServiceProviderVtbl },
1072 &Accessible.IAccessible_iface,
1073 0, 0,
1074 0, 0, 0, NULL,
1075 0, 0, 0, 0,
1076 FALSE, 0,
1079 static struct Accessible Accessible_child2 =
1081 { &AccessibleVtbl },
1082 { &Accessible2Vtbl },
1083 { &OleWindowVtbl },
1084 { &ServiceProviderVtbl },
1086 &Accessible.IAccessible_iface,
1087 0, 0,
1088 0, 0, 0, NULL,
1089 0, 0, 0, 0,
1090 FALSE, 0,
1093 static struct Provider
1095 IRawElementProviderSimple IRawElementProviderSimple_iface;
1096 IRawElementProviderFragment IRawElementProviderFragment_iface;
1097 LONG ref;
1099 const char *prov_name;
1100 IRawElementProviderFragment *parent;
1101 enum ProviderOptions prov_opts;
1102 HWND hwnd;
1103 BOOL ret_invalid_prop_type;
1104 DWORD expected_tid;
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)
1116 SAFEARRAY *sa;
1117 LONG idx;
1119 if (!(sa = SafeArrayCreateVector(VT_I4, 0, ARRAY_SIZE(uia_i4_arr_prop_val))))
1120 return NULL;
1122 for (idx = 0; idx < ARRAY_SIZE(uia_i4_arr_prop_val); idx++)
1123 SafeArrayPutElement(sa, &idx, (void *)&uia_i4_arr_prop_val[idx]);
1125 return sa;
1128 static SAFEARRAY *create_r8_safearray(void)
1130 SAFEARRAY *sa;
1131 LONG idx;
1133 if (!(sa = SafeArrayCreateVector(VT_R8, 0, ARRAY_SIZE(uia_r8_arr_prop_val))))
1134 return NULL;
1136 for (idx = 0; idx < ARRAY_SIZE(uia_r8_arr_prop_val); idx++)
1137 SafeArrayPutElement(sa, &idx, (void *)&uia_r8_arr_prop_val[idx]);
1139 return sa;
1142 static SAFEARRAY *create_unk_safearray(void)
1144 SAFEARRAY *sa;
1145 LONG idx;
1147 if (!(sa = SafeArrayCreateVector(VT_UNKNOWN, 0, ARRAY_SIZE(uia_unk_arr_prop_val))))
1148 return NULL;
1150 for (idx = 0; idx < ARRAY_SIZE(uia_unk_arr_prop_val); idx++)
1151 SafeArrayPutElement(sa, &idx, (void *)uia_unk_arr_prop_val[idx]);
1153 return sa;
1156 enum {
1157 PROV_GET_PROVIDER_OPTIONS,
1158 PROV_GET_PROPERTY_VALUE,
1159 PROV_GET_HOST_RAW_ELEMENT_PROVIDER,
1160 FRAG_NAVIGATE,
1163 static const char *prov_method_str[] = {
1164 "get_ProviderOptions",
1165 "GetPropertyValue",
1166 "get_HostRawElementProvider",
1167 "Navigate",
1170 static const char *get_prov_method_str(int method)
1172 if (method >= ARRAY_SIZE(prov_method_str))
1173 return NULL;
1174 else
1175 return prov_method_str[method];
1178 enum {
1179 METHOD_OPTIONAL = 0x01,
1180 METHOD_TODO = 0x02,
1183 struct prov_method_sequence {
1184 struct Provider *prov;
1185 int method;
1186 int flags;
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);
1195 sequence = NULL;
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};
1203 if (!sequence)
1205 sequence_size = 10;
1206 sequence = HeapAlloc(GetProcessHeap(), 0, sequence_size * sizeof(*sequence));
1208 if (sequence_cnt == sequence_size)
1210 sequence_size *= 2;
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);
1230 actual = sequence;
1232 if (context)
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));
1242 expected++;
1243 actual++;
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));
1249 expected++;
1251 else if (expected->flags & METHOD_OPTIONAL)
1252 expected++;
1253 else
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));
1257 expected++;
1258 actual++;
1260 count++;
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));
1270 count++;
1271 expected++;
1274 if (expected->prov || actual->prov)
1276 if (expected->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));
1279 else
1280 ok_( file, line)(0, "incomplete sequence: expected nothing, got %s_%s\n", actual->prov->prov_name,
1281 get_prov_method_str(actual->method));
1284 if (context)
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
1298 * formatted as:
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
1307 * "Nonclient".
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>"
1319 * An example:
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);
1327 if (!str)
1328 return FALSE;
1330 if (!out_name)
1331 return TRUE;
1333 str += wcslen(prov_type);
1334 str2 = wcschr(str, L'(');
1335 lstrcpynW(out_name, str, ((str2 - str)));
1337 return TRUE;
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)
1345 WCHAR buf[2048];
1347 if (parent_link)
1348 wsprintfW(buf, L"%s(parent link):", prov_type);
1349 else
1350 wsprintfW(buf, L"%s:", prov_type);
1352 if (!get_provider_desc(prov_desc, buf, buf))
1354 if (parent_link)
1355 wsprintfW(buf, L"%s:", prov_type);
1356 else
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));
1362 return;
1364 else
1366 if (parent_link)
1367 ok_(file, line)(0, "expected parent link provider %s\n", debugstr_w(prov_type));
1368 else
1369 ok_(file, line)(0, "unexpected parent link provider %s\n", debugstr_w(prov_type));
1373 if (prov_name)
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;
1382 WCHAR buf[128];
1383 DWORD prov_pid;
1384 HWND prov_hwnd;
1385 WCHAR *end;
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:");
1395 if (str)
1396 str += wcslen(L"providerId:");
1397 else
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);
1417 *ppv = NULL;
1418 if (IsEqualIID(riid, &IID_IRawElementProviderSimple) || IsEqualIID(riid, &IID_IUnknown))
1419 *ppv = iface;
1420 else if (IsEqualIID(riid, &IID_IRawElementProviderFragment))
1421 *ppv = &This->IRawElementProviderFragment_iface;
1422 else
1423 return E_NOINTERFACE;
1425 IRawElementProviderSimple_AddRef(iface);
1426 return S_OK;
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());
1450 *ret_val = 0;
1451 if (This->prov_opts)
1453 *ret_val = This->prov_opts;
1454 return S_OK;
1457 return E_NOTIMPL;
1460 HRESULT WINAPI ProviderSimple_GetPatternProvider(IRawElementProviderSimple *iface,
1461 PATTERNID pattern_id, IUnknown **ret_val)
1463 ok(0, "unexpected call\n");
1464 return E_NOTIMPL;
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);
1477 switch (prop_id)
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;
1485 else
1487 V_VT(ret_val) = VT_I4;
1488 V_I4(ret_val) = HandleToULong(This->hwnd);
1490 break;
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;
1510 else
1512 V_VT(ret_val) = VT_I4;
1513 V_I4(ret_val) = uia_i4_prop_val;
1515 break;
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;
1523 else
1525 V_VT(ret_val) = VT_R8;
1526 V_R8(ret_val) = uia_r8_prop_val;
1528 break;
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;
1549 else
1551 V_VT(ret_val) = VT_BSTR;
1552 V_BSTR(ret_val) = SysAllocString(uia_bstr_prop_str);
1554 break;
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;
1573 else
1575 V_VT(ret_val) = VT_BOOL;
1576 V_BOOL(ret_val) = VARIANT_TRUE;
1578 break;
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();
1587 else
1589 V_VT(ret_val) = VT_ARRAY | VT_I4;
1590 V_ARRAY(ret_val) = create_i4_safearray();
1592 break;
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();
1601 else
1603 V_VT(ret_val) = VT_ARRAY | VT_R8;
1604 V_ARRAY(ret_val) = create_r8_safearray();
1606 break;
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;
1614 else
1616 V_VT(ret_val) = VT_UNKNOWN;
1617 V_UNKNOWN(ret_val) = (IUnknown *)&Provider_child.IRawElementProviderSimple_iface;
1618 IUnknown_AddRef(V_UNKNOWN(ret_val));
1620 break;
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();
1632 else
1634 V_VT(ret_val) = VT_UNKNOWN | VT_ARRAY;
1635 V_ARRAY(ret_val) = create_unk_safearray();
1637 break;
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);
1646 break;
1649 default:
1650 break;
1653 return S_OK;
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());
1665 *ret_val = NULL;
1666 if (This->hwnd)
1667 return UiaHostProviderFromHwnd(This->hwnd, ret_val);
1669 return S_OK;
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,
1688 void **ppv)
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());
1715 *ret_val = NULL;
1716 if ((direction == NavigateDirection_Parent) && This->parent)
1718 *ret_val = This->parent;
1719 IRawElementProviderFragment_AddRef(This->parent);
1721 return S_OK;
1724 static HRESULT WINAPI ProviderFragment_GetRuntimeId(IRawElementProviderFragment *iface,
1725 SAFEARRAY **ret_val)
1727 ok(0, "unexpected call\n");
1728 *ret_val = NULL;
1729 return E_NOTIMPL;
1732 static HRESULT WINAPI ProviderFragment_get_BoundingRectangle(IRawElementProviderFragment *iface,
1733 struct UiaRect *ret_val)
1735 ok(0, "unexpected call\n");
1736 return E_NOTIMPL;
1739 static HRESULT WINAPI ProviderFragment_GetEmbeddedFragmentRoots(IRawElementProviderFragment *iface,
1740 SAFEARRAY **ret_val)
1742 ok(0, "unexpected call\n");
1743 *ret_val = NULL;
1744 return E_NOTIMPL;
1747 static HRESULT WINAPI ProviderFragment_SetFocus(IRawElementProviderFragment *iface)
1749 ok(0, "unexpected call\n");
1750 return E_NOTIMPL;
1753 static HRESULT WINAPI ProviderFragment_get_FragmentRoot(IRawElementProviderFragment *iface,
1754 IRawElementProviderFragmentRoot **ret_val)
1756 ok(0, "unexpected call\n");
1757 *ret_val = NULL;
1758 return E_NOTIMPL;
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 },
1778 "Provider",
1779 NULL,
1780 0, 0, 0,
1783 static struct Provider Provider2 =
1785 { &ProviderSimpleVtbl },
1786 { &ProviderFragmentVtbl },
1788 "Provider2",
1789 NULL,
1790 0, 0, 0,
1793 static struct Provider Provider_child =
1795 { &ProviderSimpleVtbl },
1796 { &ProviderFragmentVtbl },
1798 "Provider_child",
1799 &Provider.IRawElementProviderFragment_iface,
1800 ProviderOptions_ServerSideProvider, 0, 0,
1803 static struct Provider Provider_child2 =
1805 { &ProviderSimpleVtbl },
1806 { &ProviderFragmentVtbl },
1808 "Provider_child2",
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)
1817 switch (message)
1819 case WM_GETOBJECT:
1820 if (lParam == (DWORD)OBJID_CLIENT)
1822 CHECK_EXPECT(winproc_GETOBJECT_CLIENT);
1823 if (acc_client)
1824 return LresultFromObject(&IID_IAccessible, wParam, (IUnknown *)acc_client);
1826 break;
1828 else if (lParam == UiaRootObjectId)
1830 CHECK_EXPECT(winproc_GETOBJECT_UiaRoot);
1831 if (prov_root)
1832 return UiaReturnRawElementProvider(hwnd, wParam, lParam, prov_root);
1834 break;
1837 break;
1839 default:
1840 break;
1843 return DefWindowProcA(hwnd, message, wParam, lParam);
1846 static void test_UiaHostProviderFromHwnd(void)
1848 IRawElementProviderSimple *p, *p2;
1849 enum ProviderOptions prov_opt;
1850 WNDCLASSA cls;
1851 HRESULT hr;
1852 HWND hwnd;
1853 VARIANT v;
1854 int i;
1856 cls.style = 0;
1857 cls.lpfnWndProc = test_wnd_proc;
1858 cls.cbClsExtra = 0;
1859 cls.cbWndExtra = 0;
1860 cls.hInstance = GetModuleHandleA(NULL);
1861 cls.hIcon = 0;
1862 cls.hCursor = 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);
1882 p = NULL;
1883 hr = UiaHostProviderFromHwnd(hwnd, &p);
1884 ok(hr == S_OK, "Failed to get host provider, hr %#lx.\n", hr);
1886 p2 = NULL;
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));
1904 VariantClear(&v);
1906 /* No patterns are implemented on the HWND Host provider. */
1907 for (i = UIA_InvokePatternId; i < (UIA_CustomNavigationPatternId + 1); i++)
1909 IUnknown *unk;
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));
1934 VariantClear(&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;
1951 HRESULT hr;
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);
1970 CoUninitialize();
1972 return 0;
1975 static void test_uia_reserved_value_ifaces(void)
1977 IUnknown *unk_ns, *unk_ns2, *unk_ma, *unk_ma2;
1978 IStream *stream[2];
1979 IMarshal *marshal;
1980 HANDLE thread;
1981 ULONG refcnt;
1982 HRESULT hr;
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);
2006 marshal = NULL;
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);
2042 marshal = NULL;
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)
2067 MSG msg;
2068 while(PeekMessageW(&msg, 0, 0, 0, PM_REMOVE))
2070 TranslateMessage(&msg);
2071 DispatchMessageW(&msg);
2074 CloseHandle(thread);
2076 CoUninitialize();
2079 struct msaa_role_uia_type {
2080 INT acc_role;
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 {
2152 INT acc_state;
2153 INT prop_id;
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)
2167 acc->role = role;
2168 acc->state = state;
2169 acc->child_count = child_count;
2170 acc->name = name;
2171 acc->left = left;
2172 acc->top = top;
2173 acc->width = width;
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;
2186 HRESULT hr;
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");
2200 return;
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;
2213 acc_client = NULL;
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;
2262 acc_client = NULL;
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;
2293 acc_client = NULL;
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;
2323 acc_client = NULL;
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,
2340 INT cid, int line)
2342 ILegacyIAccessibleProvider *accprov;
2343 IAccessible *accessible;
2344 INT child_id;
2345 HRESULT hr;
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;
2367 HRESULT hr;
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
2390 * and siblings.
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);
2428 acc_client = NULL;
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);
2437 /* Do nothing. */
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);
2616 acc_client = NULL;
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);
2720 if (elfrag2)
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
2771 * comparisons.
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;
2806 HRESULT hr;
2807 VARIANT v;
2808 int i, x;
2810 /* MSAA role to UIA control type test. */
2811 VariantInit(&v);
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);
2826 VariantClear(&v);
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));
2831 else
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);
2837 VariantClear(&v);
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));
2842 else
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);
2858 VariantClear(&v);
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);
2867 VariantClear(&v);
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;
2908 IAccessible *acc;
2909 IUnknown *unk;
2910 WNDCLASSA cls;
2911 HRESULT hr;
2912 HWND hwnd;
2913 VARIANT v;
2914 INT cid;
2916 CoInitializeEx(NULL, COINIT_MULTITHREADED);
2917 cls.style = 0;
2918 cls.lpfnWndProc = test_wnd_proc;
2919 cls.cbClsExtra = 0;
2920 cls.cbWndExtra = 0;
2921 cls.hInstance = GetModuleHandleA(NULL);
2922 cls.hIcon = 0;
2923 cls.hCursor = 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);
2974 acc_client = NULL;
2976 /* Skip tests on Win10v1507. */
2977 if (called_winproc_GETOBJECT_CLIENT)
2979 win_skip("UiaProviderFromIAccessible behaves inconsistently on Win10 1507, skipping tests.\n");
2980 return;
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));
3013 VariantClear(&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
3079 * compared.
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
3114 * values.
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;
3131 acc_client = NULL;
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;
3194 acc_client = NULL;
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);
3238 acc_client = NULL;
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;
3276 acc_client = NULL;
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;
3325 acc_client = NULL;
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;
3371 acc_client = NULL;
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;
3416 acc_client = NULL;
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();
3429 CoUninitialize();
3430 DestroyWindow(hwnd);
3431 UnregisterClassA("pUiaProviderFromIAccessible class", NULL);
3432 Accessible.acc_hwnd = NULL;
3433 Accessible.ow_hwnd = NULL;
3436 struct uia_lookup_id {
3437 const GUID *guid;
3438 int 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)
3624 unsigned int i;
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);
3630 if (!prop_id)
3632 win_skip("No propertyId for GUID %s, skipping further tests.\n", debugstr_guid(uia_property_lookup_ids[i].guid));
3633 break;
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 },
3643 { 0 }
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 */
3656 { 0 }
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 */
3669 { 0 }
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 */
3681 { 0 }
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 */
3706 { 0 }
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 */
3731 { 0 }
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 */
3756 { 0 }
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 },
3768 { 0 }
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;
3775 HRESULT hr;
3776 VARIANT v;
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);
3818 CoUninitialize();
3820 return 0;
3823 static void test_uia_node_from_prov_com_threading(void)
3825 HANDLE thread;
3826 HUIANODE node;
3827 HRESULT hr;
3829 /* Test ProviderOptions_UseComThreading. */
3830 Provider.hwnd = NULL;
3831 prov_root = 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.
3840 if (hr == S_OK)
3842 win_skip("Skipping ProviderOptions_UseComThreading tests for UiaNodeFromProvider.\n");
3843 UiaNodeRelease(node);
3844 return;
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)
3858 MSG msg;
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;
3871 CoUninitialize();
3873 static void test_UiaNodeFromProvider(void)
3875 WNDCLASSA cls;
3876 HUIANODE node;
3877 HRESULT hr;
3878 ULONG ref;
3879 HWND hwnd;
3880 VARIANT v;
3882 cls.style = 0;
3883 cls.lpfnWndProc = test_wnd_proc;
3884 cls.cbClsExtra = 0;
3885 cls.cbWndExtra = 0;
3886 cls.hInstance = GetModuleHandleA(NULL);
3887 cls.hIcon = 0;
3888 cls.hCursor = 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);
3925 if (SUCCEEDED(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);
3929 VariantClear(&v);
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);
3961 if (SUCCEEDED(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);
3965 VariantClear(&v);
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;
3974 prov_root = NULL;
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);
3987 if (SUCCEEDED(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);
3998 else
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);
4005 VariantClear(&v);
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);
4034 if (SUCCEEDED(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);
4045 else
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);
4051 VariantClear(&v);
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);
4078 if (SUCCEEDED(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);
4084 VariantClear(&v);
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);
4112 if (SUCCEEDED(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);
4118 VariantClear(&v);
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);
4130 CoUninitialize();
4131 DestroyWindow(hwnd);
4132 UnregisterClassA("UiaNodeFromProvider class", NULL);
4133 prov_root = 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 },
4139 { 0 }
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 },
4147 { 0 }
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 },
4162 { 0 }
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 },
4184 { 0 }
4187 static void check_uia_prop_val(PROPERTYID prop_id, enum UIAutomationType type, VARIANT *v)
4189 LONG idx;
4191 switch (type)
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);
4197 break;
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));
4206 else
4207 ok(check_variant_bool(v, TRUE), "Unexpected BOOL %#x\n", V_BOOL(v));
4208 ok_method_sequence(get_prop_seq, NULL);
4209 break;
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));
4216 else
4217 ok(V_I4(v) == uia_i4_prop_val, "Unexpected I4 %#lx\n", V_I4(v));
4218 ok_method_sequence(get_prop_seq, NULL);
4219 break;
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++)
4226 ULONG val;
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);
4232 break;
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);
4238 break;
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++)
4244 double val;
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);
4250 break;
4252 case UIAutomationType_Element:
4254 HUIANODE tmp_node;
4255 HRESULT hr;
4256 VARIANT v1;
4258 #ifdef _WIN64
4259 ok(V_VT(v) == VT_I8, "Unexpected VT %d\n", V_VT(v));
4260 tmp_node = (HUIANODE)V_I8(v);
4261 #else
4262 ok(V_VT(v) == VT_I4, "Unexpected VT %d\n", V_VT(v));
4263 tmp_node = (HUIANODE)V_I4(v);
4264 #endif
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);
4275 break;
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))
4281 break;
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++)
4287 HUIANODE tmp_node;
4288 HRESULT hr;
4289 VARIANT v1;
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);
4299 VariantClear(&v1);
4302 VariantClear(v);
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);
4306 break;
4308 default:
4309 break;
4312 VariantClear(v);
4313 V_VT(v) = VT_EMPTY;
4316 struct uia_element_property {
4317 const GUID *prop_guid;
4318 enum UIAutomationType type;
4319 BOOL skip_invalid;
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;
4382 IUnknown *unk_ns;
4383 unsigned int i;
4384 HUIANODE node;
4385 int prop_id;
4386 HRESULT hr;
4387 VARIANT v;
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;
4408 VariantClear(&v);
4409 prop_id = UiaLookupId(AutomationIdentifierType_Property, elem_prop->prop_guid);
4410 if (!prop_id)
4412 win_skip("No propertyId for GUID %s, skipping further tests.\n", debugstr_guid(elem_prop->prop_guid));
4413 break;
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);
4430 else
4431 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4432 if (SUCCEEDED(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));
4437 VariantClear(&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);
4449 CoUninitialize();
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");
4460 if (hModuleImm32) {
4461 pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
4462 if (pImmDisableIME)
4463 pImmDisableIME(0);
4465 pImmDisableIME = NULL;
4466 FreeLibrary(hModuleImm32);
4468 test_UiaHostProviderFromHwnd();
4469 test_uia_reserved_value_ifaces();
4470 test_UiaLookupId();
4471 test_UiaNodeFromProvider();
4472 test_UiaGetPropertyValue();
4473 if (uia_dll)
4475 pUiaProviderFromIAccessible = (void *)GetProcAddress(uia_dll, "UiaProviderFromIAccessible");
4476 if (pUiaProviderFromIAccessible)
4477 test_UiaProviderFromIAccessible();
4478 else
4479 win_skip("UiaProviderFromIAccessible not exported by uiautomationcore.dll\n");
4481 FreeLibrary(uia_dll);