Not able to get all child elements from a modal window - c#

I am trying to get access to a checkbox present in the modal window.
And check- uncheck it by using UI-automation/uiacomwrapper.
I am able to do it, but in some application, it is failing.
For example, say Team Viewer. I am not able to get access to the checkbox present in the modal window.
var testi = win.GetWindowByName("TeamViewer");
var child_win = win.GetChildWindow();
var window = (AutomationElement)child_win.Element;
var cb = window.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Start TeamViewer with Windows"));
it should return some value in cb, but it is returning null.
The same code is running fine with other windows form and WPF applications.
Only in case of Team Viewer, it is returning null.enter image description here

I am not 100% sure here as I do not use Team Viewer.
NameProperty would find elements whose Name matches your input. Usually the name is something that makes sense to the programmer. You might have to iterate over the elements and pick one whose caption matches your query.

Related

How to get the clicked element using webview2 in windows forms

I have a query in windows. forms I am new to this.
I have developed a form where users can open any website from it and upon right click of any element I am displaying the element name, id, and few attribute values in a data grid. For this, I have used webbrowser control.
However, I was facing some errors for a few of the sites so I tried to move to webview2. But here comes the issue
Earlier I used to get the element using the below code
HtmlElement element = webbrowser1.Document.GetElementFromPoint(e.ClientMousePosition);
But now I am unable to retrieve an element by using webview2.
Can someone please help me with this?
You will need to use JavaScript. You will need async methods.
Then, you can get the element by passing a javeScript string.
Point p = e.ClientMousePosition;
string jElement = await webBrowser1.ExecuteScriptAsync($"document.elementFromPoint({p.X},{p.Y})");
The result is JSON. You will need to parse the result to get the element name.
I am trying to figure out the same thing.

In Visual Studio how to access the source control history window programmatically?

I am developing a Visual Studio Extension. I need to access the Source Control's History window to check what history items are selected or not.
I've tried several methods including the findWindowPane() method and the activeWindow object, but none of them worked. (I didn't know all the parameters for findWindowPane() and the activeWindow doesn't have any info about specific tool window data)
Update
So I've checked the solution on this page: Show item history windows with TFS SDK
Unfortunately, when I'm trying to get the type of the history window, the result is null.
Type _dialogHistoryType;
Assembly tfsAssembly = typeof(Microsoft.TeamFoundation.VersionControl.Controls.LocalPathLinkBox).Assembly;
_dialogHistoryType = tfsAssembly.GetType("Microsoft.TeamFoundation.VersionControl.Controls.DialogHistory");
var historyWindow = package.FindToolWindow(_dialogHistoryType, 0, false);
My main goal is to get the selected history item's id from the history window during runtime.
Any suggestion, how to get the type?

Linking words to windows Explorer c#

Question: How can I make a list of link buttons so that when a user clicks on a link it opens it up in windows explorer.
So I have a rich text box that contains a list of all folder names and I have a list of all the folder paths. I want to be able to click on the folder name and have it linked using the path to the correct folder in windows explorer.
LinkLabel link = new LinkLabel();
link.Text = transfer2;
//link.Text = "something";
link.Name = dirName;
link.LinkClicked += new LinkLabelLinkClickedEventHandler(this.link_LinkClicked);
LinkLabel.Link data = new LinkLabel.Link();
data.LinkData = #"C:\";
link.Links.Add(data);
link.AutoSize = true;
link.Location =
this.Display_Rich_Text_Box.GetPositionFromCharIndex(this.Display_Rich_Text_Box.TextLength);
this.Display_Rich_Text_Box.Controls.Add(link);
this.Display_Rich_Text_Box.AppendText(link.Text + " ");
this.Display_Rich_Text_Box.SelectionStart = this.Display_Rich_Text_Box.TextLength;
I started with this code. I am using a foreach statement to get the folder names and path. I tried to change the name of link so it will appear to the user that they are clicking on folder A, but when you click on folder A it uses the path to open the windows explorer where the folder is from.
Any ideas or help would be greatly appreciated.
Update
I changed the code a little so now it will display, but I cant scroll down. It appears to be only on the surface as I ran something in the rich textbox and it was scrollable while the link stayed on the surface.
I also added a picture so you can see what the problem is. I scrolled a little bit so it would b easy to see.
LinkLabel link = new LinkLabel();
link.Text = dirName;
//link.Text = "something";
link.Name = transfer2;
//link.LinkClicked += new LinkLabelLinkClickedEventHandler(this.link_LinkClicked);
LinkLabel.Link data = new LinkLabel.Link();
data.LinkData = #"C:\";
link.Links.Add(data);
link.AutoSize = true;
link.Location =
this.Display_Rich_Text_Box.GetPositionFromCharIndex(this.Display_Rich_Text_Box.TextLength);
this.Display_Rich_Text_Box.Controls.Add(link);
this.Display_Rich_Text_Box.AppendText(link.Text + "\n");
this.Display_Rich_Text_Box.SelectionStart = this.Display_Rich_Text_Box.TextLength;
Update: I am trying to make essentially a list of hyperlinks so I don't think I can use linklabel as I think it is in a fixed position.
For the first part of your problem, opening Explorer, you can do this on the click event for each item in the list (or the click event of the whole list area, as I describe later):
System.Diagnostics.Process.Start("explorer.exe", "\"" + path + "\"");
(the quote/slash thing is to make sure paths with spaces work)
For the UI bits, I've never even seen LinkLabels before, so I don't know how you got on the road to that, lol! I'm not sure whether you're using WinForms or WPF but in either you'd generally want to use something like a ListBox (or a custom control that behaves/looks precisely how you want, but I'd guess you aren't ready for that). In WPF you could set the ListBox's ItemsSource to your data and DisplayMemberPath to whatever property the text comes from (if it is only strings then just don't set DisplayMemberPath). You'd then set up an event for clicking on the ListBox and respond to that by checking what item is selected and running the code above to open Explorer.
If you want to get your UI working with minimal changes, try replacing the LinkLabels with Buttons (you can style them to look like links if you want, at least in WPF) since those work the same way.

MS UI Automation - How to get text from ControlType.text

I have a small windows application that has a series of labels on it. This application will be globalized and there is a possibility that the text on these labels might get truncated. I am trying to automate to identify truncated text on these labels.
For other controls, I can use TextPattern.Pattern through which I can find the visible text and the actual text inside the control. But for the labels (ControlType.text) the TextPattern is not supported. How do I find the visible text for these lables using UI automation.
Here is the code I tried. If I pass control type as Document it works. But with Text control type it gives a unsupported pattern exception.
private String TextFromSelection(AutomationElement target, Int32 length)
{
// Specify the control type we're looking for, in this case 'Document'
PropertyCondition cond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text);
// target --> The root AutomationElement.
AutomationElement textProvider = target.FindFirst(TreeScope.Descendants, cond);
TextPattern textpatternPattern = textProvider.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
if (textpatternPattern == null)
{
Console.WriteLine("Root element does not contain a descendant that supports TextPattern.");
return null;
}
var test = textpatternPattern.DocumentRange.GetText(-1).TrimEnd('\r');
var tpr = textpatternPattern.GetVisibleRanges();
var txt = tpr[0].GetText(-1);
return txt;
}
Whether the text pattern is supported by the label element will be affected by which UI framework is being used. For example, the labels in the Win32 Run dlg don't support the Text pattern, but labels in the Windows 10 XAML Calculator do. The image below shows the Inspect SDK tool reporting that the Text pattern is supported by the "There's no history yet" label.
It's important to note that whether the UI framework (or the app if the app implements the UIA Text pattern directly) includes the truncated text in the data it returns to you when you call IUIAutomationTextPattern::GetVisibleRanges(), is up to the framework (or app) itself. For example, WordPad running on Windows 10 doesn't include the text that's clipped out of view, but Word 2013 does return the clipped text.
Thanks,
Guy
You should be able to simply use element.Current.Name (element being the instance of AutomationElement for the label).
Here is an example of UISpy retrieving the text for a label:

How to fill textbox of thirdparty app using c# winforms?

My app written in c# (winforms) launches a third party using Process.start().
After launch, I need to fill in some information in Search Textbox of Third party app. So how to identify the textbox of thirdpaty app? how to fill info in it?
Any clue or guidance? Keywords to search for?
You can do this using the UI Automation Library.
Using either UISPY.exe of Inspect.exe find the automationid , name etc any
parameter that can uniquely indentify the TextBox. One you have done this
you can do something like this, assuming you know the automation id.
string automationId = "ThirdyPartBox";
string newTextBoxValue = "foobar";
var condition = new PropertyCondition(AutomationElement.AutomationIdProperty, automationId);
var textBox = AutomationElement.RootElement.FindFirst(TreeScope.SubTree , condition);
ValuePattern vPattern = (ValuePattern)textBox.GetCurrentPattern(ValuePattern.Pattern);
vPattern.SetValue(newTextBoxValue);
Maybe the textbox is not uniquely identifiable by itself , you can use conditions like process id , parent container id etc to pin point it.
To Click a Button. Find the automation element first using a condition of your choice and then
InvokePattern clickButton = (InvokePattern)buttonElement.GetCurrentPattern(InvokePattern.Pattern);
clickButton.Invoke();

Categories