Как программно выбрать пункт всплывающего меню в Windows?

У меня есть приложение, для которого я пишу маленького волшебника. Он автоматизировал небольшую часть приложения, перемещая мышь к соответствующим кнопкам, меню и щелкая их, чтобы пользователь мог наблюдать.

Пока что он перемещает мышь к элементу дерева и посылает щелчок правой кнопкой мыши. Это выскакивает меню через TrackPopupMenu. Затем я перемещаю мышь к соответствующему пункту во всплывающем меню. Что я не могу понять, так это как выбрать пункт меню.

Я попытался отправить щелчок левой кнопкой мыши в окне владельца меню, попытался отправить WM_COMMAND владельцу меню и т. Д. Ничего не работает.

Я предполагаю, что меню само по себе является окном, но я не знаю, как получить HWND для него из HMENU, который у меня есть.

Любые мысли о том, как PostMessage нажмите на всплывающее меню?

PS Я использую отдельную ветку, чтобы управлять мышью и публиковать сообщения, поэтому никаких проблем с синхронностью TrackPopupMenu нет.

2 ответа

Решение

Я не нашел идеальный способ сделать это, но следующее работает довольно хорошо:

//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;

Вышеуказанная функция была вызвана по щелчку правой кнопкой мыши элемента дерева. Приведенный ниже код запускается в отдельном потоке, чтобы сделать клик

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

Я ожидаю, что вы можете сгенерировать необходимые клики, позвонив SendInput, Наведите указатель мыши на то место, где находится меню, и затем нажмите.

Возможно, вы захотите взглянуть на хук WH_JOURNALPLAYBACK. Я думаю, что он предназначен для того, чтобы делать именно то, что вы пытаетесь сделать вручную.

Другие вопросы по тегам