views:

563

answers:

3

I am having trouble getting SendMessage to activate a menu on another program. When looking through Spy++ when a user clicks on the menu the following occurs:

 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
Whereas when I attempt the same using SendMessage with WM_NCLBUTTONDOWN the following happens instead:
 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

Does anyone know how to get this to work properly?

Cheers

Ross

+1  A: 

You shouldn't use SendMessage to simulate mouse clicks and key presses. Use SendInput instead.

Michael
I know i could use SendInput however SendInput does not block until the message has been processed and this is one of the properties of SendMessage that I need to utilise for what I am programming.
Ross
+1  A: 

I'd guess that the menu loop tests for the state of the mouse button. However, you haven't simulated pressing the mouse button, all you're doing is sending a message saying that the button is down.

If you need synchronous behavior, I would suggest a windows hook and have your thread block until the right time. (In other words, you can use an asynchronous approach and then wrap it so that it blocks and acts as a synchronous call. It's extra work, but if you insist on synchronous behavior from something that is inherently asynchronous, it's your best solution.)

jdigital
The primary reason it has to be synchronous is so that any popup menus / modal dialogs have the chance to appear and be detected. I'm not sure if I could accomplish this with a windows hook as the program is not going to have prior knowledge of where it is clicking. Is there a way to trick the menu loop into thinking the button really is down and still accomplish it using SendMessage?
Ross
Not sure how to simulate the button down, but if you could, how would you know when to simulate the button up?
jdigital
A: 

You can perfectly use SendMessage(), in particular for menus (see MSDN and Google Groups for code samples)
(and hooks have nothing to do here)

The original poster already tried SendMessage. It doesn't work here because the application is looking at the state of the mouse but the mouse button isn't really down. SendMessage is only doing half the job.
jdigital