0
votes

Using Inspect.exe I can see a button exists in the tree structure of an application's components, but I can't find a way to get a handle to that button. Here's the Inspect.exe output for the control:

How found:  Selected from tree...
Name:   "Options"
ControlType:    UIA_ButtonControlTypeId (0xC350)
LocalizedControlType:   "Button"
BoundingRectangle:  {l:805 t:286 r:821 b:302}
IsEnabled:  true
IsOffscreen:    false
IsKeyboardFocusable:    true
HasKeyboardFocus:   false
ProcessId:  4380
RuntimeId:  [2A.103FA.2.F6EBAC8.0]
AutomationId:   ""
ClassName:  "NetUISimpleButton"
IsControlElement:   true
IsContentElement:   false
ProviderDescription:    "[pid:4380,hwnd:0x0 Main(parent link):Unidentified Provider (unmanaged:mso.dll)]"
IsPeripheral:   [Not supported]
LiveSettingProperty:    [Not supported]
HelpText:   "Options"
FlowsFrom:  [Not supported]
OptimizeForVisualContent:   [Not supported]
Annotation.AnnotationAuthor:    [Not supported]
Annotation.AnnotationTypeId:    [Not supported]
Annotation.Author:  [Not supported]
Annotation.DateTime:    [Not supported]
Annotation.Target:  [Not supported]
Drag.DropEffect:    [Not supported]
Drag.DropEffects:   [Not supported]
Drag.GrabbedItems:  [Not supported]
Drag.IsGrabbed: [Not supported]
DropTarget.DropTargetEffect:    [Not supported]
DropTarget.DropTargetEffects:   [Not supported]
LegacyIAccessible.ChildId:  0
LegacyIAccessible.DefaultAction:    "Press"
LegacyIAccessible.Description:  ""
LegacyIAccessible.Help: "Options"
LegacyIAccessible.KeyboardShortcut: ""
LegacyIAccessible.Name: "Options"
LegacyIAccessible.Role: push button (0x2B)
LegacyIAccessible.State:    focusable (0x100000)
LegacyIAccessible.Value:    ""
ObjectModel.UnderlyingObjectModel:  [Error: calling getter for this property: hr=0xFFFFFFFF80070057 - The parameter is incorrect.]
SpreadsheetItem.AnnotationObjects:  [Not supported]
SpreadsheetItem.AnnotationTypes:    [Not supported]
SpreadsheetItem.Formula:    [Not supported]
Style.ExtendedProperties:   [Not supported]
Style.FillColor:    [Not supported]
Style.FillPatternColor: [Not supported]
Style.FillPatternStyle: [Not supported]
Style.Shape:    [Not supported]
Style.StyleId:  [Not supported]
Style.StyleName:    [Not supported]
Transform2.CanZoom: [Not supported]
Transform2.ZoomLevel:   [Not supported]
Transform2.ZoomMinimum: [Not supported]
Transform2.ZoomMaximum: [Not supported]
IsAnnotationPatternAvailable:   [Not supported]
IsDragPatternAvailable: [Not supported]
IsDockPatternAvailable: false
IsDropTargetPatternAvailable:   [Not supported]
IsExpandCollapsePatternAvailable:   false
IsGridItemPatternAvailable: false
IsGridPatternAvailable: false
IsInvokePatternAvailable:   true
IsItemContainerPatternAvailable:    false
IsLegacyIAccessiblePatternAvailable:    true
IsMultipleViewPatternAvailable: false
IsObjectModelPatternAvailable:  [Not supported]
IsRangeValuePatternAvailable:   false
IsScrollItemPatternAvailable:   true
IsScrollPatternAvailable:   false
IsSelectionItemPatternAvailable:    false
IsSelectionPatternAvailable:    false
IsSpreadsheetItemPatternAvailable:  [Not supported]
IsSpreadsheetPatternAvailable:  [Not supported]
IsStylesPatternAvailable:   [Not supported]
IsSynchronizedInputPatternAvailable:    false
IsTableItemPatternAvailable:    false
IsTablePatternAvailable:    false
IsTextChildPatternAvailable:    [Not supported]
IsTextEditPatternAvailable: [Not supported]
IsTextPatternAvailable: false
IsTextPattern2Available:    [Not supported]
IsTogglePatternAvailable:   false
IsTransformPatternAvailable:    false
IsTransform2PatternAvailable:   [Not supported]
IsValuePatternAvailable:    false
IsVirtualizedItemPatternAvailable:  false
IsWindowPatternAvailable:   false
FirstChild: "" Image
LastChild:  "" Image
Next:   "Show Menu" Button
Previous:   [null]
Other Props:    Object has no additional properties
Children:   "" Image
Ancestors:  "" SplitButton
    "Contacts" Pane
    "" Pane
    "" Custom Control
    "" Pane
    "" pane
    "Lync" window
    "Desktop" pane
    [ No Parent ]

The peculiar thing about this button is that it has no hwnd value. (hwnd:0x0). Here is what I have tried to get a reference to the button:

currentWindow = FindWindowEx((IntPtr)hwnd, IntPtr.Zero, null, "Options");

In this example the hwnd variable is a handle to the main window of the application that contains the button.

In reading the documentation for FindWindowEx it looks as though there are a variety of ways of using the different arguments and I feel like I have tried them all. I've tried "NetUISimpleButton" in the class argument, as well as "Button". I've tried null in the window name as well as the name of the control "Options" as seen above. I've tried every combination of those values in those two fields. I've also tried specifying a value for child after to be a child of the main window. I've even tried putting IntPtr.Zero for both of the first arguments.

I'm starting to think that this hwnd:0x0 is a foreboding omen that means I won't have an option for getting access to this button at all. If that's the case, do I have any other options? I'm just trying to get a secondary window in the application open so that I can do a few more button clicks and radio selects.

1
Some buttons are not windows so they don't have handles. You need to use UI Automation.arx
Awesome arx. That worked great! I'll post my code in the answer below.omatase

1 Answers

6
votes

It was super easy with UI Automation. Here's the code I used in case anyone is interested.

int hwnd = FindWindow("CommunicatorMainWindowClass", null);

AutomationElement lync = AutomationElement.FromHandle((IntPtr)hwnd);
AutomationElement optionsButton = lync.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Options"));
((InvokePattern)optionsButton.GetCurrentPattern(InvokePattern.Pattern)).Invoke();