?
Solved

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

Posted on 2007-08-07
7
Medium Priority
?
410 Views
Last Modified: 2011-09-20
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.
0
Comment
Question by:Kanivorous
  • 3
  • 2
  • 2
7 Comments
 
LVL 11

Expert Comment

by:Deepu Abraham
ID: 19643824
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
 

Author Comment

by:Kanivorous
ID: 19643861
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
 
LVL 11

Expert Comment

by:Deepu Abraham
ID: 19643975
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 86

Expert Comment

by:jkr
ID: 19645712
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
 
LVL 86

Accepted Solution

by:
jkr earned 1500 total points
ID: 19645838
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
 

Author Comment

by:Kanivorous
ID: 19649071
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
 

Author Comment

by:Kanivorous
ID: 19658217
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

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unable to change the program that handles the scan event from a network attached Canon/Brother printer/scanner. This means you'll always have to choose which program handles this action, e.g. ControlCenter4 (in the case of a Brother).
MS Outlook undoubtedly is the most widely used email client.Its user-friendliness, cost effectiveness, and availability with Microsoft Office Suite make it the most popular email application.  Its compatibility with Microsoft applications like Exch…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
With the advent of Windows 10, Microsoft is pushing a Get Windows 10 icon into the notification area (system tray) of qualifying computers. There are many reasons for wanting to remove this icon. This two-part Experts Exchange video Micro Tutorial s…

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question