How to find TaskBar button screen Rect of a window?

vb 276 Reputation points
2020-10-02T19:03:12.77+00:00

Every WPF(&Win32) app window, using "ShowInTaskbar", are represented by TaskBar button at the TaskList.
How to programmatically (c#, c++, Win32, WPF) find screen rectangle of app TaskBar button?
One can easily find application Notify Icon position & rect...how to do it with app TaskBar button?

Thanks!
Vladimir

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,835 questions
Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,676 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,426 questions
{count} votes

Accepted answer
  1. Castorix31 81,741 Reputation points
    2020-10-03T03:09:08.347+00:00

    You can use IUIAutomation

    Test in C# WinForms on Windows 10 ( add a button for the Click) :

    // Add reference to : c:\Windows\system32\UIAutomationCore.dll
    // Add : using UIAutomationClient;
    
    
    
        public partial class Form1 : Form
        {
            [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                IntPtr hWndTray = FindWindow("Shell_TrayWnd", null);
                IntPtr hWndTrayNotify = FindWindowEx(hWndTray, IntPtr.Zero, "TrayNotifyWnd", null);
                IntPtr hWndSysPager = FindWindowEx(hWndTrayNotify, IntPtr.Zero, "SysPager", null);
                IntPtr hWndToolbar = FindWindowEx(hWndSysPager, IntPtr.Zero, "ToolbarWindow32", null);
    
                IntPtr hWndRebar = FindWindowEx(hWndTray, IntPtr.Zero, "ReBarWindow32", null);
                IntPtr hWndMSTaskSwWClass = FindWindowEx(hWndRebar, IntPtr.Zero, "MSTaskSwWClass", null);
                IntPtr hWndMSTaskListWClass = FindWindowEx(hWndMSTaskSwWClass, IntPtr.Zero, "MSTaskListWClass", null); 
    
                IUIAutomation pUIAutomation = new CUIAutomation();
    
                // Taskbar
                IUIAutomationElement windowElement = pUIAutomation.ElementFromHandle(hWndMSTaskListWClass);
                if (windowElement != null)
                {
                    IUIAutomationElementArray elementArray = null;
                    IUIAutomationCondition condition = pUIAutomation.CreateTrueCondition();
                    elementArray = windowElement.FindAll(TreeScope.TreeScope_Descendants | TreeScope.TreeScope_Children, condition);
                    if (elementArray != null)
                    {
                        Console.WriteLine("Taskbar");
                        int nNbItems = elementArray.Length;
                        for (int nItem = 0; nItem <= nNbItems - 1; nItem++)
                        {
                            IUIAutomationElement element = elementArray.GetElement(nItem);
                            string sName = element.CurrentName;
                            string sAutomationId = element.CurrentAutomationId;
                            tagRECT rect = element.CurrentBoundingRectangle;
                            Console.WriteLine("\tName : {0} - AutomationId : {1}  - Rect({2}, {3}, {4}, {5})", sName, sAutomationId, rect.left, rect.top, rect.right, rect.bottom);
                        }
                    }
                }
    
                // Tray icons
                IUIAutomationElement windowElementTray = pUIAutomation.ElementFromHandle(hWndToolbar);
                if(windowElementTray != null) 
                {
                    IUIAutomationElementArray elementArray = null;
                    IUIAutomationCondition condition = pUIAutomation.CreateTrueCondition();
                    elementArray = windowElementTray.FindAll(TreeScope.TreeScope_Descendants | TreeScope.TreeScope_Children, condition);
                    if (elementArray != null)
                    {
                        Console.WriteLine("Tray Icons");
                        int nNbItems = elementArray.Length;
                        for (int nItem = 0; nItem <= nNbItems - 1; nItem++)
                        { 
                            IUIAutomationElement element = elementArray.GetElement(nItem);
                            string sName = element.CurrentName;
                            string sAutomationId = element.CurrentAutomationId;
                            tagRECT rect = element.CurrentBoundingRectangle;
                            Console.WriteLine("\tName : {0} - AutomationId : {1}  - Rect({2}, {3}, {4}, {5})", sName, sAutomationId, rect.left, rect.top, rect.right, rect.bottom); 
                        }
                    }
                }
            }
        }
    
    1 person found this answer helpful.

3 additional answers

Sort by: Most helpful
  1. vb 276 Reputation points
    2020-10-03T13:06:25.95+00:00

    WOW! Thanks man!

    Just tried code and conceptually works!!!

    I have to adjust for my code for other secondary taskbars using class name "Shell_SecondaryTrayWnd"

    find Classname("Shell_SecondaryTrayWnd") =>find Classname("WorkerW") => find Classname("MSTaskListWClass")

    etc...in case "Combine taskbar buttons" TaskBar settings enabled...probably to find object per HWND for, you must re-search automation children elements.


  2. Leonardo 91 Reputation points
    2021-09-04T09:46:09.417+00:00

    @Castorix31 do you mind sharing the same code to c++? I don't know much about c# either c++ but this function would help me as I would add it to another program, in which is written in c++, thank you.


  3. Leonardo 91 Reputation points
    2021-09-04T12:18:30.08+00:00

    I got till IUIAutomationCondition *condition = from here on i don't understand well

    -Edit- Sorry for my dumbness, its my first time using the website, i thought i was posting in the comment section instead of as a new answer.
    I tried to delete my previous comment but looks like it remain even after deleting.

    void button1_Click(int sender, EventArgs *e)
    {
    
        IUIAutomation* pUIAutomation = NULL;
        HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    
        HWND hWndTray = FindWindow(L"Shell_TrayWnd", nullptr);
        HWND hWndTrayNotify = FindWindowEx(hWndTray, 0, L"TrayNotifyWnd", nullptr);
        HWND hWndSysPager = FindWindowEx(hWndTrayNotify, 0, L"SysPager", nullptr);
        HWND hWndToolbar = FindWindowEx(hWndSysPager, 0, L"ToolbarWindow32", nullptr);
    
        HWND hWndRebar = FindWindowEx(hWndTray, 0, L"ReBarWindow32", nullptr);
        HWND hWndMSTaskSwWClass = FindWindowEx(hWndRebar, 0, L"MSTaskSwWClass", nullptr);
        HWND hWndMSTaskListWClass = FindWindowEx(hWndMSTaskSwWClass, 0, L"MSTaskListWClass", nullptr);
    
        // Taskbar
        IUIAutomationElement* windowElement = NULL;
        hr = pUIAutomation->ElementFromHandle(hWndMSTaskListWClass, &windowElement );
    
        if (windowElement != nullptr)
        {
            IUIAutomationElementArray *elementArray = nullptr;
            IUIAutomationCondition *condition = pUIAutomation->CreateTrueCondition();
            elementArray = windowElement->FindAll(TreeScope::TreeScope_Descendants | TreeScope::TreeScope_Children, condition);
            if (elementArray != nullptr)
            {
                std::wcout << L"Taskbar" << std::endl;
                int nNbItems = elementArray->Length;
                for (int nItem = 0; nItem <= nNbItems - 1; nItem++)
                {
                    IUIAutomationElement *element = elementArray->GetElement(nItem);
                    std::wstring sName = element->CurrentName;
                    std::wstring sAutomationId = element->CurrentAutomationId;
                    tagRECT *rect = element->CurrentBoundingRectangle;
                    std::wcout << L"\tName : " << sName << L" - AutomationId : " << sAutomationId << L"  - Rect(" << rect->left << L", " << rect->top << L", " << rect->right << L", " << rect->bottom << std::endl;
                }
            }
        }
    
        // Tray icons
        IUIAutomationElement *windowElementTray = pUIAutomation->ElementFromHandle(hWndToolbar);
        if (windowElementTray != nullptr)
        {
            IUIAutomationElementArray *elementArray = nullptr;
            IUIAutomationCondition *condition = pUIAutomation->CreateTrueCondition();
            elementArray = windowElementTray->FindAll(TreeScope::TreeScope_Descendants | TreeScope::TreeScope_Children, condition);
            if (elementArray != nullptr)
            {
                std::wcout << L"Tray Icons" << std::endl;
                int nNbItems = elementArray->Length;
                for (int nItem = 0; nItem <= nNbItems - 1; nItem++)
                {
                    IUIAutomationElement *element = elementArray->GetElement(nItem);
                    std::wstring sName = element->CurrentName;
                    std::wstring sAutomationId = element->CurrentAutomationId;
                    tagRECT *rect = element->CurrentBoundingRectangle;
                    std::wcout << L"\tName : " << sName << L" - AutomationId : " << sAutomationId << L"  - Rect(" << rect->left << L", " << rect->top << L", " << rect->right << L", " << rect->bottom << std::endl;
                }
            }
        }
    
    }