Как программно выбрать пункт всплывающего меню в 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. Я думаю, что он предназначен для того, чтобы делать именно то, что вы пытаетесь сделать вручную.