question

vbAtom avatar image
0 Votes"
vbAtom asked Niele-0100 edited

How to find TaskBar button screen Rect of a window?

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-wpfwindows-formswindows-api-ui
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Castorix31 avatar image
1 Vote"
Castorix31 answered Castorix31 commented

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); 
                     }
                 }
             }
         }
     }




5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

vbAtom avatar image
0 Votes"
vbAtom answered

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.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Niele-0100 avatar image
0 Votes"
Niele-0100 answered Niele-0100 edited

@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.

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

It is about the same code in C++
Add at beginning :

  #include <UIAutomation.h>

then

  IUIAutomation* pUIAutomation = NULL;
  HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
  hr = CoCreateInstance(CLSID_CUIAutomation8, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pUIAutomation));

then

  /// all FindWindow stuff... then
  IUIAutomationElement* windowElement = NULL;
  hr = pUIAutomation->ElementFromHandle(hWndMSTaskListWClass, &windowElement );
  // etc..


0 Votes 0 ·

Thank you im gonna try edit :)

0 Votes 0 ·
Niele-0100 avatar image
0 Votes"
Niele-0100 answered Niele-0100 edited

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;
             }
         }
     }
    
 }
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I just tested in a C++/Win32 app,, for the Taskbar :

Taskbar buttons


0 Votes 0 ·

Ty, im currently using a software named Display Fusion, that creates a second taskbar, is also possible to read the buttons from this taskbar?

0 Votes 0 ·

Check with Inspect tool if the buttons exist in this Taskbar
and Spy++
to see where the Taskbar is positioned in the windows hierarchy


0 Votes 0 ·
Show more comments