Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
cee22e0c
Commit
cee22e0c
authored
Mar 23, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Apr 17, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Implement UIA_ControlTypePropertyId for default HWND provider.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
07c0cd6b
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
138 additions
and
0 deletions
+138
-0
uiautomation.c
dlls/uiautomationcore/tests/uiautomation.c
+86
-0
uia_provider.c
dlls/uiautomationcore/uia_provider.c
+52
-0
No files found.
dlls/uiautomationcore/tests/uiautomation.c
View file @
cee22e0c
...
...
@@ -12361,12 +12361,49 @@ static void test_node_hwnd_provider_(HUIANODE node, HWND hwnd, const char *file,
winetest_pop_context
();
}
enum
{
PARENT_HWND_NULL
,
PARENT_HWND_HWND
,
PARENT_HWND_DESKTOP
,
};
struct
uia_hwnd_control_type_test
{
DWORD
style
;
DWORD
style_ex
;
int
exp_control_type
;
int
parent_hwnd_type
;
};
static
const
struct
uia_hwnd_control_type_test
hwnd_control_type_test
[]
=
{
{
WS_OVERLAPPEDWINDOW
,
0
,
UIA_WindowControlTypeId
,
PARENT_HWND_NULL
},
/* Top-level window (parent is desktop window) is always a window control. */
{
WS_CHILD
,
0
,
UIA_WindowControlTypeId
,
PARENT_HWND_DESKTOP
},
/* Not a top-level window, considered a pane. */
{
WS_CHILD
,
0
,
UIA_PaneControlTypeId
,
PARENT_HWND_HWND
},
/* Not a top-level window, but WS_EX_APPWINDOW is always considered a window. */
{
WS_CHILD
,
WS_EX_APPWINDOW
,
UIA_WindowControlTypeId
,
PARENT_HWND_HWND
},
/*
* WS_POPUP is always a pane regardless of being a top level window,
* unless WS_CAPTION is set.
*/
{
WS_CAPTION
|
WS_POPUP
,
0
,
UIA_WindowControlTypeId
,
PARENT_HWND_DESKTOP
},
{
WS_BORDER
|
WS_POPUP
,
0
,
UIA_PaneControlTypeId
,
PARENT_HWND_DESKTOP
},
{
WS_POPUP
,
0
,
UIA_PaneControlTypeId
,
PARENT_HWND_DESKTOP
},
/*
* Top level window with WS_EX_TOOLWINDOW and without WS_CAPTION is
* considered a pane.
*/
{
WS_CHILD
,
WS_EX_TOOLWINDOW
,
UIA_PaneControlTypeId
,
PARENT_HWND_DESKTOP
},
{
WS_CHILD
|
WS_CAPTION
,
WS_EX_TOOLWINDOW
,
UIA_WindowControlTypeId
,
PARENT_HWND_DESKTOP
},
};
static
void
test_default_clientside_providers
(
void
)
{
HUIANODE
node
;
HRESULT
hr
;
HWND
hwnd
;
VARIANT
v
;
int
i
;
CoInitializeEx
(
NULL
,
COINIT_MULTITHREADED
);
hwnd
=
create_test_hwnd
(
"test_default_clientside_providers class"
);
...
...
@@ -12411,6 +12448,55 @@ static void test_default_clientside_providers(void)
ok
(
Provider
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider
.
ref
);
ok
(
Provider_nc
.
ref
==
1
,
"Unexpected refcnt %ld
\n
"
,
Provider_nc
.
ref
);
method_sequences_enabled
=
FALSE
;
VariantInit
(
&
v
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
hwnd_control_type_test
);
i
++
)
{
const
struct
uia_hwnd_control_type_test
*
test
=
&
hwnd_control_type_test
[
i
];
HWND
hwnd2
,
parent
;
if
(
test
->
parent_hwnd_type
==
PARENT_HWND_HWND
)
parent
=
hwnd
;
else
if
(
test
->
parent_hwnd_type
==
PARENT_HWND_DESKTOP
)
parent
=
GetDesktopWindow
();
else
parent
=
NULL
;
hwnd2
=
CreateWindowExA
(
test
->
style_ex
,
"test_default_clientside_providers class"
,
"Test window"
,
test
->
style
,
0
,
0
,
100
,
100
,
parent
,
NULL
,
NULL
,
NULL
);
initialize_provider
(
&
Provider_nc
,
ProviderOptions_ClientSideProvider
|
ProviderOptions_NonClientAreaProvider
,
hwnd2
,
TRUE
);
initialize_provider
(
&
Provider
,
ProviderOptions_ClientSideProvider
,
hwnd2
,
TRUE
);
Provider_nc
.
ignore_hwnd_prop
=
Provider
.
ignore_hwnd_prop
=
TRUE
;
Provider
.
ret_invalid_prop_type
=
Provider_nc
.
ret_invalid_prop_type
=
TRUE
;
/* If parent is hwnd, it will be queried for an override provider. */
if
(
test
->
style
==
WS_CHILD
&&
(
parent
==
hwnd
))
SET_EXPECT_MULTI
(
winproc_GETOBJECT_UiaRoot
,
2
);
else
SET_EXPECT
(
winproc_GETOBJECT_UiaRoot
);
/* Only sent on Win7. */
SET_EXPECT
(
winproc_GETOBJECT_CLIENT
);
hr
=
UiaNodeFromProvider
(
&
Provider_nc
.
IRawElementProviderSimple_iface
,
&
node
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx.
\n
"
,
hr
);
ok
(
Provider
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider
.
ref
);
ok
(
Provider_nc
.
ref
==
2
,
"Unexpected refcnt %ld
\n
"
,
Provider_nc
.
ref
);
if
(
hwnd_control_type_test
[
i
].
style
==
WS_CHILD
&&
(
parent
==
hwnd
))
todo_wine
CHECK_CALLED_MULTI
(
winproc_GETOBJECT_UiaRoot
,
2
);
else
CHECK_CALLED
(
winproc_GETOBJECT_UiaRoot
);
called_winproc_GETOBJECT_CLIENT
=
expect_winproc_GETOBJECT_CLIENT
=
0
;
hr
=
UiaGetPropertyValue
(
node
,
UIA_ControlTypePropertyId
,
&
v
);
ok
(
hr
==
S_OK
,
"Unexpected hr %#lx
\n
"
,
hr
);
ok
(
V_VT
(
&
v
)
==
VT_I4
,
"Unexpected VT %d
\n
"
,
V_VT
(
&
v
));
ok
(
V_I4
(
&
v
)
==
test
->
exp_control_type
,
"Unexpected control type %ld
\n
"
,
V_I4
(
&
v
));
VariantClear
(
&
v
);
UiaNodeRelease
(
node
);
DestroyWindow
(
hwnd2
);
}
method_sequences_enabled
=
TRUE
;
DestroyWindow
(
hwnd
);
UnregisterClassA
(
"test_default_clientside_providers class"
,
NULL
);
...
...
dlls/uiautomationcore/uia_provider.c
View file @
cee22e0c
...
...
@@ -1229,6 +1229,45 @@ static HRESULT uia_send_message_timeout(HWND hwnd, UINT msg, WPARAM wparam, LPAR
return
S_OK
;
}
static
BOOL
is_top_level_hwnd
(
HWND
hwnd
)
{
return
(
GetAncestor
(
hwnd
,
GA_PARENT
)
==
GetDesktopWindow
())
?
TRUE
:
FALSE
;
}
static
HRESULT
get_uia_control_type_for_hwnd
(
HWND
hwnd
,
int
*
control_type
)
{
LONG_PTR
style
,
ex_style
;
*
control_type
=
0
;
if
((
ex_style
=
GetWindowLongPtrW
(
hwnd
,
GWL_EXSTYLE
))
&
WS_EX_APPWINDOW
)
{
*
control_type
=
UIA_WindowControlTypeId
;
return
S_OK
;
}
SetLastError
(
NO_ERROR
);
if
(
!
(
style
=
GetWindowLongPtrW
(
hwnd
,
GWL_STYLE
))
&&
(
GetLastError
()
!=
NO_ERROR
))
return
uia_get_hr_for_last_error
();
/*
* Non-caption HWNDs that are popups or tool windows aren't considered full
* windows, only panes.
*/
if
(((
style
&
WS_CAPTION
)
!=
WS_CAPTION
)
&&
((
ex_style
&
WS_EX_TOOLWINDOW
)
||
(
style
&
WS_POPUP
)))
{
*
control_type
=
UIA_PaneControlTypeId
;
return
S_OK
;
}
/* Non top-level HWNDs are considered panes as well. */
if
(
!
is_top_level_hwnd
(
hwnd
))
*
control_type
=
UIA_PaneControlTypeId
;
else
*
control_type
=
UIA_WindowControlTypeId
;
return
S_OK
;
}
/*
* Default ProviderType_BaseHwnd IRawElementProviderSimple interface.
*/
...
...
@@ -1366,6 +1405,19 @@ static HRESULT WINAPI base_hwnd_provider_GetPropertyValue(IRawElementProviderSim
break
;
}
case
UIA_ControlTypePropertyId
:
{
int
control_type
;
hr
=
get_uia_control_type_for_hwnd
(
base_hwnd_prov
->
hwnd
,
&
control_type
);
if
(
SUCCEEDED
(
hr
))
{
V_VT
(
ret_val
)
=
VT_I4
;
V_I4
(
ret_val
)
=
control_type
;
}
break
;
}
default:
break
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment