I can not find controls in the desktop Viber application. I use Winspector, but he sees only the process and control of the "Default IME". I need to find buttons in it, text boxes and so on. For example, the notepad ++ application in the inspector is viewed normally. enter image description here

The form elements and their classes are visible.

That's what the vibe enter image description here

For what I need it - I want to programmatically define this control here. enter image description here

Well, then use the functions user32.dll to check the presence of this control in the window.

  • 2
    Or maybe there are no Windows controls? - Igor

1 answer 1

There are many frameworks that do not use native Windows controls, and “draw” controls on the window themselves. So do, for example, WPF and Qt. Desktop Viber is written just on Qt.

Try using UI Automation instead for your purposes. For example, this program works for me with VLC controls, which is written in Qt:

class Program { static void Main(string[] args) { // находим процесс var vlcProcess = Process.GetProcessesByName("vlc").FirstOrDefault(); // и его главное окно var window = AutomationElement.FromHandle(vlcProcess.MainWindowHandle); // находим в нём меню var menuBar = window.FirstChildByType(ControlType.MenuBar); // в нём пункт "Медиа" var mediaMenu = menuBar.FirstDescendantByTypeAndName( ControlType.MenuItem, "Медиа"); // раскрываем его mediaMenu.GetPattern<InvokePattern>().Invoke(); // даём приложению успеть раскрыть меню и создать подэлементы Thread.Sleep(100); // находим в меню "Медиа" пункт "Выход" var exitMenu = mediaMenu.FirstDescendantByTypeAndName( ControlType.MenuItem, "Выход"); // и выбираем его exitMenu.GetPattern<InvokePattern>().Invoke(); Thread.Sleep(100); } } static class AutomationHelpers { static public T GetPattern<T>(this AutomationElement element) where T : BasePattern { var pattern = (AutomationPattern)typeof(T).GetField("Pattern").GetValue(null); return (T)element.GetCurrentPattern(pattern); } static public AutomationElement FirstChildByType( this AutomationElement element, ControlType ct) { return element.FindFirst( TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ct)); } static public AutomationElement FirstDescendantByTypeAndName( this AutomationElement element, ControlType ct, string name) { return element.FindFirst( TreeScope.Descendants, new AndCondition( new PropertyCondition(AutomationElement.ControlTypeProperty, ct), new PropertyCondition(AutomationElement.NameProperty, name))); } static public AutomationElement FindWindowFrom(AutomationElement control) { var walker = TreeWalker.ControlViewWalker; while (control.Current.ControlType != ControlType.Window) control = walker.GetParent(control); return control; } } 

To view controls that support UI Automation, you need the Inspect utility .

  • Tell me what to do in this case: I found the necessary control element f4.s.qip.ru/rg8it9vc.png , but what type to choose here var menuBar = window.FirstChildByType (ControlType.MenuBar); ? It is not in the list of ControlType types. - Artem Balan
  • @ArtemBalan: Have you tried ControlType.Button ? - VladD
  • found nothing - Artem Balan
  • one
    @ArtemBalan: Strange. Then look for the name "Top up." This is similar to FirstDescendantByTypeAndName , but remove the condition on the type. - VladD