mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-16 04:36:58 +00:00
uiautomationcore: Implement IUIAutomation::CreateNotCondition.
Signed-off-by: Connor McAdams <cmcadams@codeweavers.com>
This commit is contained in:
parent
6b4ad50c83
commit
078a2c8831
|
@ -10089,16 +10089,46 @@ static void test_CUIAutomation_value_conversion(IUIAutomation *uia_iface)
|
|||
SafeArrayDestroy(sa);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI Object_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid, &IID_IUnknown))
|
||||
*ppv = iface;
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Object_AddRef(IUnknown *iface)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG WINAPI Object_Release(IUnknown *iface)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static IUnknownVtbl ObjectVtbl = {
|
||||
Object_QueryInterface,
|
||||
Object_AddRef,
|
||||
Object_Release
|
||||
};
|
||||
static IUnknown Object = {&ObjectVtbl};
|
||||
|
||||
static void test_CUIAutomation_condition_ifaces(IUIAutomation *uia_iface)
|
||||
{
|
||||
IUIAutomationPropertyCondition *prop_cond;
|
||||
enum PropertyConditionFlags prop_flags;
|
||||
IUIAutomationBoolCondition *bool_cond;
|
||||
IUIAutomationNotCondition *not_cond;
|
||||
IUIAutomationCondition *cond;
|
||||
PROPERTYID prop_id;
|
||||
BOOL tmp_b;
|
||||
HRESULT hr;
|
||||
VARIANT v;
|
||||
ULONG ref;
|
||||
|
||||
hr = IUIAutomation_CreateTrueCondition(uia_iface, NULL);
|
||||
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
|
||||
|
@ -10202,7 +10232,53 @@ static void test_CUIAutomation_condition_ifaces(IUIAutomation *uia_iface)
|
|||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
ok(prop_flags == PropertyConditionFlags_None, "Unexpected flags %#x.\n", prop_flags);
|
||||
|
||||
IUIAutomationPropertyCondition_Release(prop_cond);
|
||||
/*
|
||||
* IUIAutomationNotCondition tests.
|
||||
*/
|
||||
cond = (void *)0xdeadbeef;
|
||||
|
||||
/*
|
||||
* Passing in an interface that isn't a valid IUIAutomationCondition
|
||||
* interface.
|
||||
*/
|
||||
hr = IUIAutomation_CreateNotCondition(uia_iface, (IUIAutomationCondition *)&Object, &cond);
|
||||
ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
|
||||
ok(!cond, "cond != NULL\n");
|
||||
|
||||
/* NULL input argument tests. */
|
||||
cond = (void *)0xdeadbeef;
|
||||
hr = IUIAutomation_CreateNotCondition(uia_iface, NULL, &cond);
|
||||
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
|
||||
ok(!cond, "cond != NULL\n");
|
||||
|
||||
hr = IUIAutomation_CreateNotCondition(uia_iface, (IUIAutomationCondition *)prop_cond, NULL);
|
||||
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
/* Create the IUIAutomationNotCondition with our property condition. */
|
||||
cond = NULL;
|
||||
hr = IUIAutomation_CreateNotCondition(uia_iface, (IUIAutomationCondition *)prop_cond, &cond);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
ok(!!cond, "cond == NULL\n");
|
||||
|
||||
/* IUIAutomationNotCondition holds a reference to the passed in condition. */
|
||||
ref = IUIAutomationPropertyCondition_Release(prop_cond);
|
||||
ok(ref == 1, "Unexpected ref %ld\n", ref);
|
||||
|
||||
hr = IUIAutomationCondition_QueryInterface(cond, &IID_IUIAutomationNotCondition, (void **)¬_cond);
|
||||
IUIAutomationCondition_Release(cond);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
ok(!!not_cond, "not_cond == NULL\n");
|
||||
|
||||
hr = IUIAutomationNotCondition_GetChild(not_cond, NULL);
|
||||
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
|
||||
|
||||
cond = NULL;
|
||||
hr = IUIAutomationNotCondition_GetChild(not_cond, &cond);
|
||||
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
|
||||
ok(iface_cmp((IUnknown *)cond, (IUnknown *)prop_cond), "cond != prop_cond\n");
|
||||
IUIAutomationCondition_Release(cond);
|
||||
|
||||
IUIAutomationNotCondition_Release(not_cond);
|
||||
}
|
||||
|
||||
struct uia_com_classes {
|
||||
|
|
|
@ -23,6 +23,112 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
|
||||
|
||||
static HRESULT get_uia_condition_struct_from_iface(IUIAutomationCondition *condition, struct UiaCondition **cond_struct);
|
||||
|
||||
/*
|
||||
* IUIAutomationNotCondition interface.
|
||||
*/
|
||||
struct uia_not_condition {
|
||||
IUIAutomationNotCondition IUIAutomationNotCondition_iface;
|
||||
LONG ref;
|
||||
|
||||
IUIAutomationCondition *child_iface;
|
||||
struct UiaNotCondition condition;
|
||||
};
|
||||
|
||||
static inline struct uia_not_condition *impl_from_IUIAutomationNotCondition(IUIAutomationNotCondition *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, struct uia_not_condition, IUIAutomationNotCondition_iface);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI uia_not_condition_QueryInterface(IUIAutomationNotCondition *iface, REFIID riid, void **ppv)
|
||||
{
|
||||
*ppv = NULL;
|
||||
if (IsEqualIID(riid, &IID_IUIAutomationNotCondition) || IsEqualIID(riid, &IID_IUIAutomationCondition) ||
|
||||
IsEqualIID(riid, &IID_IUnknown))
|
||||
*ppv = iface;
|
||||
else
|
||||
return E_NOINTERFACE;
|
||||
|
||||
IUIAutomationNotCondition_AddRef(iface);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static ULONG WINAPI uia_not_condition_AddRef(IUIAutomationNotCondition *iface)
|
||||
{
|
||||
struct uia_not_condition *uia_not_condition = impl_from_IUIAutomationNotCondition(iface);
|
||||
ULONG ref = InterlockedIncrement(&uia_not_condition->ref);
|
||||
|
||||
TRACE("%p, refcount %ld\n", uia_not_condition, ref);
|
||||
return ref;
|
||||
}
|
||||
|
||||
static ULONG WINAPI uia_not_condition_Release(IUIAutomationNotCondition *iface)
|
||||
{
|
||||
struct uia_not_condition *uia_not_condition = impl_from_IUIAutomationNotCondition(iface);
|
||||
ULONG ref = InterlockedDecrement(&uia_not_condition->ref);
|
||||
|
||||
TRACE("%p, refcount %ld\n", uia_not_condition, ref);
|
||||
if (!ref)
|
||||
{
|
||||
IUIAutomationCondition_Release(uia_not_condition->child_iface);
|
||||
heap_free(uia_not_condition);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI uia_not_condition_GetChild(IUIAutomationNotCondition *iface, IUIAutomationCondition **child)
|
||||
{
|
||||
struct uia_not_condition *uia_not_condition = impl_from_IUIAutomationNotCondition(iface);
|
||||
|
||||
TRACE("%p, %p\n", iface, child);
|
||||
|
||||
if (!child)
|
||||
return E_POINTER;
|
||||
|
||||
IUIAutomationCondition_AddRef(uia_not_condition->child_iface);
|
||||
*child = uia_not_condition->child_iface;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const IUIAutomationNotConditionVtbl uia_not_condition_vtbl = {
|
||||
uia_not_condition_QueryInterface,
|
||||
uia_not_condition_AddRef,
|
||||
uia_not_condition_Release,
|
||||
uia_not_condition_GetChild,
|
||||
};
|
||||
|
||||
static HRESULT create_uia_not_condition_iface(IUIAutomationCondition **out_cond, IUIAutomationCondition *in_cond)
|
||||
{
|
||||
struct uia_not_condition *uia_not_condition;
|
||||
struct UiaCondition *cond_struct;
|
||||
HRESULT hr;
|
||||
|
||||
if (!out_cond)
|
||||
return E_POINTER;
|
||||
|
||||
*out_cond = NULL;
|
||||
hr = get_uia_condition_struct_from_iface(in_cond, &cond_struct);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
uia_not_condition = heap_alloc_zero(sizeof(*uia_not_condition));
|
||||
if (!uia_not_condition)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
uia_not_condition->IUIAutomationNotCondition_iface.lpVtbl = &uia_not_condition_vtbl;
|
||||
uia_not_condition->condition.ConditionType = ConditionType_Not;
|
||||
uia_not_condition->condition.pConditions = cond_struct;
|
||||
uia_not_condition->ref = 1;
|
||||
uia_not_condition->child_iface = in_cond;
|
||||
IUIAutomationCondition_AddRef(in_cond);
|
||||
|
||||
*out_cond = (IUIAutomationCondition *)&uia_not_condition->IUIAutomationNotCondition_iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* IUIAutomationPropertyCondition interface.
|
||||
*/
|
||||
|
@ -265,6 +371,39 @@ static HRESULT create_uia_bool_condition_iface(IUIAutomationCondition **out_cond
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT get_uia_condition_struct_from_iface(IUIAutomationCondition *condition, struct UiaCondition **cond_struct)
|
||||
{
|
||||
*cond_struct = NULL;
|
||||
if (!condition)
|
||||
return E_POINTER;
|
||||
|
||||
if (condition->lpVtbl == (IUIAutomationConditionVtbl *)&uia_bool_condition_vtbl)
|
||||
{
|
||||
struct uia_bool_condition *cond;
|
||||
|
||||
cond = impl_from_IUIAutomationBoolCondition((IUIAutomationBoolCondition *)condition);
|
||||
*cond_struct = &cond->condition;
|
||||
}
|
||||
else if (condition->lpVtbl == (IUIAutomationConditionVtbl *)&uia_property_condition_vtbl)
|
||||
{
|
||||
struct uia_property_condition *cond;
|
||||
|
||||
cond = impl_from_IUIAutomationPropertyCondition((IUIAutomationPropertyCondition *)condition);
|
||||
*cond_struct = (struct UiaCondition *)&cond->condition;
|
||||
}
|
||||
else if (condition->lpVtbl == (IUIAutomationConditionVtbl *)&uia_not_condition_vtbl)
|
||||
{
|
||||
struct uia_not_condition *cond;
|
||||
|
||||
cond = impl_from_IUIAutomationNotCondition((IUIAutomationNotCondition *)condition);
|
||||
*cond_struct = (struct UiaCondition *)&cond->condition;
|
||||
}
|
||||
else
|
||||
return E_FAIL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* IUIAutomationElement interface.
|
||||
*/
|
||||
|
@ -1531,8 +1670,9 @@ static HRESULT WINAPI uia_iface_CreateOrConditionFromNativeArray(IUIAutomation6
|
|||
static HRESULT WINAPI uia_iface_CreateNotCondition(IUIAutomation6 *iface, IUIAutomationCondition *cond,
|
||||
IUIAutomationCondition **out_condition)
|
||||
{
|
||||
FIXME("%p, %p, %p: stub\n", iface, cond, out_condition);
|
||||
return E_NOTIMPL;
|
||||
TRACE("%p, %p, %p\n", iface, cond, out_condition);
|
||||
|
||||
return create_uia_not_condition_iface(out_condition, cond);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI uia_iface_AddAutomationEventHandler(IUIAutomation6 *iface, EVENTID event_id,
|
||||
|
|
Loading…
Reference in a new issue