How do I programmatically select a pop-up menu item in Windows?

I have an application for which I am writing a little wizard. He automated a small part of the application by moving the mouse over the appropriate buttons, menus and clicking on them so that the user can watch.

While it moves the mouse to the tree item and dispatches the right click. This brings up the menu via TrackPopupMenu. Then I move the mouse to the appropriate item in the popup menu. I can't figure out how to select a menu item.

I tried to send left clicks to the menu owner window, tried to send WM_COMMAND to the menu owner, etc. Nothing works.

I suppose the menu is a window by itself, but I don't know how to get the HWND for it from the HMENU I have.

Any thoughts on how to post a message to a popup menu?

PS I am using a separate thread for mouse and message control, so no problem with TrackPopupMenu being synchronous.

+1


source to share


2 answers


I haven't found a prefect way to do this, but the following works very well:

//in my case, the menu is a popup from a tree control created with:
CMenu menu;
menu.CreatePopupMenu();
//add stuff to the menu...
pTreeCtrl->SetMenu(&menu);
m_hMenu = menu.GetSafeHmenu();
CPoint  pt;
GetCursorPos(&pt);
menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, pt.x, pt.y, _pTreeCtrl);
menu.Detach();
m_hMenu = NULL;

      



The above function was invoked by right clicking a tree item. The below code runs on a separate thread to make the click

CRect rc;
GetMenuItemRect(pTreeCtrl->GetSafeHwnd(), m_hMenu, targetMenuItemIndex, &rc);
if(FALSE == rc.IsRectEmpty())
{
   CPoint target = rc.CenterPoint();
   //this closes the menu
  ::PostMessage(pTreeCtrl->GetSafeHwnd(), WM_CANCELMODE, 0, 0);
  DestroyMenu(m_hMenu);
  m_hMenu = NULL;
  //now simulate the menu click
  ::PostMessage(pTreeCtrl->GetSafeHwnd(), WM_COMMAND, targetMenuItemID, 0);
}

      

+2


source


I expect you to be able to create the required click messages by calling SendInput

. Hover your mouse over where the menu is and click.



You might want to take a look at WH_JOURNALPLAYBACK . I think it is meant to do what you are trying to do manually.

+1


source







All Articles