On Fri Sep 30 23:04:42 2022 +0000, Connor McAdams wrote:
From a clients point of view, there is one `HUIANODE`. It acts as a container for one (or later multiple) `IWineUiaProvider` interfaces. An `IWineUiaProvider` can get its values from one of the following interfaces:
- An `IRawElementProviderSimple` interface.
- An `IWineUiaNode` interface.
If the provider gets its values directly from an `IRawElementProviderSimple` interface, it's a normal, non-nested node provider. These are created from the function `UiaNodeFromProvider()`, and also created when you call `UiaNodeFromHandle()` on a same-thread HWND. They are also created when returning a `UIAutomationType_Element` property from another non-nested node provider. If the provider gets its values from an `IWineUiaNode` interface, it's a "nested node" provider. I.e, a node within a node. These are created when calling `UiaNodeFromHandle()` on an HWND from another thread or process. The node it represents contains its own `IWineUiaProvider` which gets its values from an `IRawElementProviderSimple` interface. This is the "nested node". Nested nodes are an HUIANODE, but they're never meant to be touched directly by a client. They're tracked by the provider thread and able to be disconnected with `UiaDisconnectProvider()` and `UiaDisconnectAllProviders()`. Any properties that return a new HUIANODE to a client (i.e `UIAutomationType_Element` properties) need to return a new "nested node", that gets turned into an `IWineUiaProvider` on the client end that gets its properties from an `IWineUiaNode`. This is why I thought `is_nested_node_elprov` made more sense, because that's the distinction. An `IWineUiaProvider` that gets its values from an `IRawElementProviderSimple` inside of a nested node behaves the same way as an `IWineUiaProvider` that gets its values from an `IRawElementProviderSimple` inside of a non-nested node, the only difference is that we need to return a different kind of `HUIANODE` for `UIAutomationType_Element` properties. We need to pass them to the provider thread to be tracked, and we need to return a value that the client can use to unmarshal an `IWineUiaNode` interface and create an `IWineUiaProvider` that gets its values from an `IWineUiaNode` interface. For a non-nested node, we just return an `HUIANODE` pointer directly to the client containing an `IWineUiaProvider` that gets its values directly from an `IRawElementProviderSimple`. It's kind of complicated, and I hope that has cleared things up a bit. :/ A more simplified way of thinking about it might be:
- A nested node provider calls: `IWineUiaProvider->IWineUiaNode->IWineUiaProvider->IRawElementProviderSimple`
- A normal provider calls: `IWineUiaProvider->IRawElementProviderSimple`
I think you're going to need a separate name for those internal nodes to make it clearer.