Reputation: 103
I have an application which on focus change should be able to retrieve the URL of the currently active tab if the opened program is a browser otherwise should just return the name of the program.
For example let say I have notepad opened in the foreground and then I alt-tab to my browser where I have 2 tabs opened I want the application to extract the URL of the active tab. The code below works to find the name of the tab but the code in the try catch which should be finding the URL of the tab doesn't work it just prints empty string.
I want to have the URL of the site so I can have a constant reference to it as the tab name could be different in the same site
private void OnFocusChangedHandler(object src, AutomationFocusChangedEventArgs args)
{
Debug.WriteLine("Focus changed!");
AutomationElement element = src as AutomationElement;
if (element != null)
{
string name = element.Current.Name;
string id = element.Current.AutomationId;
int processId = element.Current.ProcessId;
try
{
using (Process process = Process.GetProcessById(processId))
{
AutomationElement elm = AutomationElement.FromHandle(process.MainWindowHandle);
AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns();
if (patterns.Length > 0)
{
ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0]);
Debug.WriteLine("URL found: " + val.Current.Value);
}
}
}
catch { }
Debug.WriteLine(" Name: {0}, Id: {1}", name, id);
}
}
I have tried everything along similar lines in stackoverflow and different websites but is either really outdated or it just doesn't work.
Thanks in Advance.
Upvotes: 3
Views: 3012
Reputation: 103
I have found solution which works for me for all browsers tested on (Yandex (chromium based) Chrome and Firefox it works on all three).
First I changed from using System.Windows.Automation
to IUIAutomation
because the former was really slow.
So for everyone looking for solution to similar problem first go to dependencies and right click to dependencies and press "Add COM Reference..":
Then find UIAutomationClient you could put UI in the search bar top right to find it easily:
After you have added it here is the code:
private readonly CUIAutomation _automation;
public YourMainClass()
{
_automation = new CUIAutomation();
_automation.AddFocusChangedEventHandler(null, new FocusChangeHandler(this));
}
public class FocusChangeHandler : IUIAutomationFocusChangedEventHandler
{
private readonly YourMainClass _listener;
public FocusChangeHandler(YourMainClass listener)
{
_listener = listener;
}
public void HandleFocusChangedEvent(IUIAutomationElement element)
{
if (element != null)
{
using (Process process = Process.GetProcessById(element.CurrentProcessId))
{
try
{
IUIAutomationElement elm = this._listener._automation.ElementFromHandle(process.MainWindowHandle);
IUIAutomationCondition Cond = this._listener._automation.CreatePropertyCondition(30003, 50004);
IUIAutomationElementArray elm2 = elm.FindAll(TreeScope.TreeScope_Descendants, Cond);
for (int i = 0; i < elm2.Length; i++)
{
IUIAutomationElement elm3 = elm2.GetElement(i);
IUIAutomationValuePattern val = (IUIAutomationValuePattern)elm3.GetCurrentPattern(10002);
if (val.CurrentValue != "")
{
Debug.WriteLine("URL found: " + val.CurrentValue);
}
}
}
catch { }
}
}
}
}
And at the very top put these two lines
using UIAutomationClient;
using TreeScope = UIAutomationClient.TreeScope;
And also you should change "YourMainClass" with your own class as needed.
Upvotes: 6