Search code examples
c#windowprogress-barfindwindow

Find a specific control on a window


Im trying to find the value of a specific ProgressBar (msctls_progress32) on a window,

I have found the window with:

[DllImport("User32.dll")]
public static extern IntPtr FindWindow(string strClassName, string strWindowName);

But i cant get the pointer of the ProgressBar with:

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string lclassName, string windowTitle);

Then once i have the pointer i want to get the value with:

public const int PBM_GETPOS = 0x0408;
[DllImport("User32.dll")]
public static extern Int32 SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

The problem is that there are multiple Progress Bars on the window and the progress bar i want the pointer of is inside multiple #32770 (Dialog)


Solution

  • I answered the question by using UIAutomation mixed with SendMessage and FindWindow

    //Get parent window.
    AutomationElement element = AutomationElement.FromHandle(Win32.FindWindow(null, "Form1"));
    //Get all descendants
    AutomationElementCollection elements =  element.FindAll(TreeScope.Descendants, Condition.TrueCondition);
    //loop through descendants
    foreach (AutomationElement elementNode in elements)
    {
        //if descendant is a progress bar
        if (elementNode.Current.NativeWindowHandle != 0 && elementNode.Current.LocalizedControlType == "progress bar")
        {
            //Show value of the bar.
            MessageBox.Show(Win32.SendMessage((IntPtr)elementNode.Current.NativeWindowHandle, Win32.PBM_GETPOS, IntPtr.Zero, IntPtr.Zero).ToString(), "Bar value");
        }
    }