Enumerate menu items from pop-up menu of system tray icon

Hi I'm looking for any way to enumerate or get the strings and attributes (checked or not) of menu items from a pop-up menu when you right click on a system tray icon for a certain application.

I've searched for many weeks and code I stumble upon always seem to teach how to make menus yourself, in which case it seems easier to get a handle of.

Help is very, very appreciated.
KanivorousAsked:
Who is Participating?
 
jkrConnect With a Mentor Commented:
Ooops, make that

HMENU hMenu = GetMenu(hWnd);

int nCount = GetMenuItemCount(hMenu);

for (int i = 0; i < nCount; ++nCount) {

    TCHAR acMenu[255];
    MENUITEMINFO mii;
    ZeroMemory(&mii,sizeof(mii));
    mii.cbCount = sizeof(mii);

    GetMenuItemInfo(hMenu,i,TRUE,&mii); // state info etc.
    GetMenuString(hMenu,i,acMenu,sizeof(acMenu)/sizeof(TCHAR),MF_BYPOSITION);
}
0
 
Deepu AbrahamR & D Engineering ManagerCommented:
Try the following member funtions of CMenu,

GetMenuInfo
 Retrieves information on a specific menu.
 
GetMenuItemCount
 Determines the number of items in a pop-up or top-level menu.
 
GetMenuItemID
 Obtains the menu-item identifier for a menu item located at the specified position.
 
GetMenuItemInfo
 Retrieves information about a menu item.
 
GetMenuState
 Returns the status of the specified menu item or the number of items in a pop-up menu.

Best Regards,
DeepuAbrahamK
GetMenuString
 Retrieves the label of the specified menu item.
 
0
 
KanivorousAuthor Commented:
My apologies, I should have mentioned that I am looking for a Non-MFC solution. Although yes they still have those functions for non-mfc as well.

I've come across these functions, but I'm not sure what the ids are for my menu items. So, if I was to get the ID first and call GetMenuItemID, how would I specify the position? How would I know the position?
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Deepu AbrahamR & D Engineering ManagerCommented:
In MFC way,
You can get no of menu items by calling GetMenuItemCount()
after that you could call GetMenuItemID
Obtains the menu-item identifier for a menu item located at the specified position.
Best Regards,
DeepuAbrahamK
0
 
jkrCommented:
Use

HMENU hMenu = GetMenu(hWnd);

int nCount = GetMenuItemCount(hMenu);

for (int i = 0; i < nCount; ++nCount) {

    TCHAR acMenu[255];
    MENUITEMINFO mii;
    ZeroMemory(&mii,sizeof(mii));
    mii.cbCount = sizeof(mii)
    GetMenuItemInfo(hMenu,i,TRUE,&mii);
    GetMenuString(hMenu,i,acMenu,sizeof(acMenu)/sizeof(TCHAR),MF_BYPOSITION);
}
0
 
KanivorousAuthor Commented:
I tried combining the code above with my code which basically gets the HWND of all system tray icons so I can pass them to GetMenu(hWnd) function, but that returns a NULL every time. Maybe my HWND is not valid? What is the best way to get a HWND for my case so I can combine it with the code above?

This is how I got my HWND.

HWND hWndTray = FindWindow("Shell_TrayWnd", NULL);
if(hWndTray)
{
      hWndTray = FindWindowEx(hWndTray,NULL,"TrayNotifyWnd", NULL);
      if(hWndTray)
      {
            hWndTray = FindWindowEx(hWndTray,NULL,"SysPager", NULL);
            if(hWndTray)
            {                        
                  hWndTray = FindWindowEx(hWndTray, NULL,"ToolbarWindow32", "Notification Area");
            }
      }
}
if( hWndTray == NULL )
      return 0;

DWORD dwTrayProcessID = -1;
GetWindowThreadProcessId(hWndTray, &dwTrayProcessID);
HANDLE hTrayProc = OpenProcess(PROCESS_ALL_ACCESS, 0, dwTrayProcessID);

int iconCount = SendMessage(hWndTray, TB_BUTTONCOUNT, 0, 0);

LPVOID lpData = VirtualAllocEx(hTrayProc, NULL, sizeof(TBBUTTON), MEM_COMMIT, PAGE_READWRITE);

for(int i=0; i<iconCount; i++)
{
      DWORD dwBytesRead = -1;
      TBBUTTON buttonData;
      SendMessage(hWndTray, TB_GETBUTTON, i, (LPARAM)lpData);

      ReadProcessMemory(hTrayProc, lpData, &buttonData, sizeof(TBBUTTON), &dwBytesRead);

      DWORD dwExtraData[2] = { 0,0 };
      ReadProcessMemory(hTrayProc, (LPVOID)buttonData.dwData, dwExtraData, sizeof(dwExtraData), &dwBytesRead);

      HWND hWndOfIconOwner = (HWND) dwExtraData[0];
      int  iIconId         = (int)  dwExtraData[1];
                               
      int nCount = -9999;

      HMENU hMenu = GetMenu(hWndOfIconOwner);
      nCount = GetMenuItemCount(hMenu);
}
      
0
 
KanivorousAuthor Commented:
People tend to run away when I ask that question about getting the handle to the system tray icon ^^;. I'll keep trying to look for the last half of the solution. I've asked experienced programmers that I actually know this question about the HWND of system tray icons and even they get stuck on it, so I wonder if it is even possible sometimes. In any case, thanks for the answer on the menu items.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.