1

J'ai une application pour laquelle j'écris un petit assistant. Il a automatisé une petite partie de l'application en déplaçant la souris sur les boutons appropriés, les menus et en cliquant dessus pour que l'utilisateur puisse regarder.Comment faire pour sélectionner par programme un élément de menu contextuel dans Windows?

Jusqu'à présent, il déplace la souris sur un élément de l'arborescence et envoie un clic-droit. Cela ouvre un menu via TrackPopupMenu. Ensuite, je déplace la souris vers l'élément approprié dans le menu contextuel. Ce que je ne peux pas comprendre, c'est comment sélectionner l'élément de menu.

J'ai essayé d'envoyer un clic gauche de la fenêtre propriétaire du menu, essayé d'envoyer WM_COMMAND au propriétaire du menu, etc. Rien ne fonctionne.

Je suppose que le menu est une fenêtre en lui-même, mais je ne sais pas comment obtenir le HWND pour lui de la HMENU que j'ai.

Toute réflexion sur la façon de postMessage un clic dans le menu contextuel?

PS J'utilise un thread séparé pour conduire les messages de la souris et après, donc pas de problèmes avec TrackPopupMenu étant synchrone.

Répondre

2

Je n'ai pas trouvé un moyen préfet de le faire, mais les travaux suivants assez bien:

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

La fonction ci-dessus était appelé à un clic droit de l'élément d'arborescence. Le code ci-dessous s'exécute dans un thread séparé pour faire le clic

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

Je pense que vous pouvez générer les messages clic nécessaires en appelant SendInput. Déplacez la souris sur l'emplacement du menu, puis cliquez sur.

Vous pourriez vouloir jeter un coup d'oeil au crochet WH_JOURNALPLAYBACK. Je pense que c'est conçu pour faire exactement ce que vous essayez de faire manuellement.