@SteveMylo, the answer is yes and no. First some explanations for why the cached version code should be faster:
1) Reason number 1 is not related to caching at all, but to using FindElements instead of multiple FindElement (or FindFirstBy in the case of UIA_Interface). FindElements traverses the whole tree just once and returns all the found elements, whereas calling FindElement multiple times might need to traverse more of the tree in sum. For example, if the target element is right in the middle of the tree, than a single FindElement will be faster than a single FindElements. Calling FindElement twice will be as fast as FindElements; calling it three times is already slower than FindElement once. So while it depends on where the elements are in the tree, I usually try to use FindElements instead of FindElement if I need to call it more than once, or I use FindElement and specify the startingElement argument. In this case, since I don't know the order of the elements I opted for FindElements.
2) Caching the properties will make reading them faster and also prevents problems such as the element being invalidated in the time between finding it and accessing its properties.
3) Using AutomationElementMode.None ("None" in the CreateCacheRequest call) will not return the live element at all, which also gets big speed improvements.
ElementFromPath is essentially calling FindElement with TreeScope.Children for each condition in the condition path. Caching all these elements only to not use them afterwards doesn't make sense, but if you wish to cache the found element (and its properties) then you can use
Element.BuildUpdatedCache() to do that.
Another way would be to cache the whole tree and then walk the path using cached properties (the corresponding function is CachedElementFromPath). This may or may not give a speed improvement depending on how many times you plan to use ElementFromPath. Since ElementFromPath uses Type, AutomationId, ClassName and Name, then you need to cache these along with any other property you want to use. Something like this:
Code: Select all
static cacheRequest := UIA.CreateCacheRequest(["Type", "AutomationId", "ClassName", "Name", "BoundingRectangle"],,5, "None") ; 5 == Descendants + Element
if !(dvEl := GetDavinciElement())
return
cachedEl := dvEl.BuildUpdatedCache(cacheRequest)
found := cachedEl.CachedElementFromPath(({T:11,CN:"UiMenuItemAction", i:15})
IsMouseInElement would need to use CachedBoundingRectangle as well, like in my example.
If you want to also access the live element (along with live properties, use patterns etc) then omit the "None" from the cacheRequest. That will make the caching significantly slower though.