2009-04-27 4 views
0

Je n'arrive pas à obtenir SendMessage pour activer un menu sur un autre programme. Lorsque l'on regarde à travers Spy ++ lorsqu'un utilisateur clique sur le menu ce qui suit se produit:SendMessage pour cliquer sur les éléments non-client

 
000A0628 P WM_NCLBUTTONDOWN nHittest:HTMENU xPos:1706 yPos:395 [wParam:00000005 lParam:018B06AA time:27:23:56.156 point:(1706, 395)] 
000A0628 S WM_SYSCOMMAND uCmdType:SC_MOUSEMENU xPos:1706 yPos:395 [wParam:0000F095 lParam:018B06AA] 
000A0628 S WM_ENTERMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 
000A0628 R WM_ENTERMENULOOP lResult:00000000 
000A0628 S WM_SETCURSOR hwnd:000A0628 nHittest:HTCAPTION wMouseMsg:0000 [wParam:000A0628 lParam:00000002] 
000A0628 R WM_SETCURSOR fHaltProcessing:False [lResult:00000000] 
000A0628 S WM_INITMENU hmenuInit:00200355 [wParam:00200355 lParam:00000000] 
000C0672 S EM_GETSEL lpdwStart:0010EFA0 lpdwEnd:0010EFA4 [wParam:0010EFA0 lParam:0010EFA4] 
000C0672 R EM_GETSEL wStart:26 wEnd:26 lpdwStart:0010EFA0 (684) lpdwEnd:0010EFA4 (276) [lResult:001A001A] 
000C0672 S WM_GETTEXTLENGTH wParam:00000000 lParam:00000000 
000C0672 R WM_GETTEXTLENGTH cch:26 [lResult:0000001A] 
000C0672 S EM_CANUNDO wParam:00000000 lParam:00000000 
000C0672 R EM_CANUNDO fCanUndo:True [lResult:00000001] 
000A0628 R WM_INITMENU lResult:00000000 
000A0628 S WM_MENUSELECT uItem:0 fuFlags:MF_POPUP | MF_HILITE | MF_MOUSESELECT hmenu:00200355 [wParam:80900000 lParam:00200355] 
000A0628 R WM_MENUSELECT lResult:00000000 
000A0628 S WM_INITMENUPOPUP hmenuPopup:00150595 uPos:0 fSystemMenu:False [wParam:00150595 lParam:00000000] 
000A0628 R WM_INITMENUPOPUP lResult:00000000

Alors que lorsque je tente la même chose en utilisant SendMessage avec WM_NCLBUTTONDOWN ce qui suit arrive à la place:

 
000A0628 P WM_NCLBUTTONDOWN nHittest:HTMENU xPos:1700 yPos:400 [wParam:00000005 lParam:019006A4 time:27:25:02.156 point:(1700, 400)] 
000A0628 S WM_SYSCOMMAND uCmdType:SC_MOUSEMENU xPos:1700 yPos:400 [wParam:0000F095 lParam:019006A4] 
000A0628 S WM_ENTERMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 
000A0628 R WM_ENTERMENULOOP lResult:00000000 
000A0628 S WM_EXITMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 
000A0628 R WM_EXITMENULOOP lResult:00000000 
000A0628 S WM_MENUSELECT uItem:0 fuFlags:FFFF (menu was closed) hmenu:00000000 [wParam:FFFF0000 lParam:00000000] 
000A0628 R WM_MENUSELECT lResult:00000000 
000A0628 S WM_EXITMENULOOP fIsTrackPopupMenu:False [wParam:00000000 lParam:00000000] 
000A0628 R WM_EXITMENULOOP lResult:00000000 
000A0628 R WM_SYSCOMMAND lResult:00000000 

Est-ce que quelqu'un sait comment obtenir ceci pour fonctionner correctement?

Vive

Ross

+0

en pensant à cette question, je me demande s'il pourrait y avoir une solution alternative. Pouvez-vous nous dire exactement ce que vous essayez d'atteindre (c'est-à-dire, pourquoi essayez-vous d'activer un menu dans un autre programme)? – jdigital

+0

J'essaie de faire un testeur "Monkey". En tant que partie de ceci, j'ai besoin que le singe soit assez intelligent pour ne pas cliquer sur tout ce qu'il identifie comme une option de menu/bouton de quitter/quitter ce qui est bien sauf qu'il clique si vite qu'il peut cliquer quelque part avant qu'une boîte de dialogue apparaisse et la boîte de dialogue recevra toujours l'entrée et si la boîte de dialogue a un bouton Quitter dessus sous l'endroit où la souris se trouve, elle déclenche le programme ciblé pour quitter. Ce n'est pas l'effet désiré, donc une méthode de détection de l'apparition d'une boîte de dialogue est nécessaire. SendMessage bloque et fournit cette capacité. – Ross

Répondre

1

Je suppose que la boucle de menu teste l'état du bouton de la souris. Cependant, vous n'avez pas simulé en appuyant sur le bouton de la souris, tout ce que vous faites est d'envoyer un message disant que le bouton est en panne.

Si vous avez besoin d'un comportement synchrone, je suggère un windows hook et ayez votre bloc de fil au bon moment. (En d'autres termes, vous pouvez utiliser une approche asynchrone, puis l'enrouler de manière à bloquer et à agir comme un appel synchrone, mais si vous insistez sur le comportement synchrone de quelque chose qui est intrinsèquement asynchrone, c'est votre meilleure solution.)

+0

La principale raison pour laquelle il doit être synchrone est que tous les menus contextuels/boîtes de dialogue modales ont la chance d'apparaître et d'être détectés. Je ne suis pas sûr si je pourrais accomplir ceci avec un crochet de fenêtres car le programme ne va pas avoir la connaissance préalable d'où il clique. Y a-t-il un moyen de tromper la boucle du menu en pensant que le bouton est vraiment en panne et l'accomplir encore en utilisant SendMessage? – Ross

+0

Vous ne savez pas comment simuler le bouton, mais si vous le pouviez, comment sauriez-vous quand simuler le bouton? – jdigital

1

Vous ne devriez pas utiliser SendMessage pour simuler les clics de souris et touches. Utilisez SendInput à la place.

+0

Je sais que je pourrais utiliser SendInput mais SendInput ne bloque pas tant que le message n'a pas été traité et c'est l'une des propriétés de SendMessage que je dois utiliser pour ce que je suis en train de programmer. – Ross

0

Vous pouvez parfaitement utiliser SendMessage(), en particulier pour les menus (voir MSDN et Google Groupes pour des exemples de code)
(et les crochets ont rien à voir ici)

+0

L'affiche originale a déjà essayé SendMessage. Cela ne fonctionne pas ici car l'application regarde l'état de la souris mais le bouton de la souris n'est pas vraiment enfoncé. SendMessage ne fait que la moitié du travail. – jdigital

Questions connexes