tags:

views:

75

answers:

2
+1  Q: 

Win32 call order

Hi all,

I have two windows that I send scripted input to. The procedure goes as this

BringWindowToTop( window1 );
i = Build input structures( window1 );
SendInput(i);

BringWindowToTop( window2 );
i = Build input structures( window2 );
SendInput(i);

I was having trouble with inputs not being sent and the correct time. I put delays after each call and saw that input from the first SendInput() was processed after window2 is brought to top. Same thing at the end of the loop as well.

Are SendInput calls buffered? If so, how can I make sure of a serial execution of this code?

Thanks

A: 

From the MSDN page:

The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.

So SendInput is inserting into the input stream where, presumably, BringWindowToTop is executing serially, or inserting into an events queue that is processed first. Perhaps you could find an event to call the second SendInput from, which will be executed after the first window is brought to the front.

Justin Ethier
+1  A: 

Input, like most messages in Win32, goes through two phases. First it is posted into a queue. At this point the destination window is already determined. Then when the receiving program is idle it is processed. Even though the input might not be processed until after the second window is brought forward in the Z-order, the input messages should have been queued to the first window.

Does the behavior rely only on which window the input goes to, or does the program also have to be frontmost when the message is fully processed?

Anyway, since you are trying to send input to specific windows and not whatever the user made active, why not PostMessage the events such as WM_BUTTONDOWN and WM_KEYPRESS directly to their destinations?

Ben Voigt
Not all applications respond to windows messages. Some ignore it and check for the current state of input devices in a loop.And yes it is important that the input goes to correct windows.
DD
@DD: Programs like that do exist, but they're pretty rare. You have to go out of your way to get current state (e.g. GetAsyncKeyState vs GetKeyState). Also, there'd be a different function to send input directly to a console window. Maybe if you describe your particular case a little better the community can give better advice.
Ben Voigt
First window is an FLTK window.I tried posting: WM_MOUSEMOVE WM_LBUTTONDOWN WM_MOUSEMOVE WM_LBUTTONUPin order, and it responds to none of them.All I'm trying to do is send mouse/keyboard input to a specific window. Namely, trying to write this function: SendInputToWindow( HWND h, INPUT i );
DD
Did you send the messages to the right child window? ChildWindowFromPoint may help here. http://msdn.microsoft.com/en-us/library/ms632677(v=VS.85).aspx
Ben Voigt
Works on some and doesn't work on others. Microsoft Excel 2010 is one where dragging doesn't work. I can click on cells but I can't click and drag to choose multiple cells for instance, it doesn't respond to it. Same drag code works on other applications with sliders. Sadly, Excel is a big need.
DD
Are you sending the entire drag operation to a single window? Usually the mouse down event causes a SetCapture, which causes subsequent messages to go to the same window even when the cursor moves outside its bounds.
Ben Voigt
m.x = 215; m.y = 300; childH = findChild( w->getHandle(), m ); PostMessage( childH, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM( m.x, m.y ) ); SetCapture(childH); PostMessage( childH, WM_MOUSEMOVE, MK_LBUTTON, MAKELPARAM( m.x, m.y + 220 ) ); PostMessage( childH, WM_LBUTTONUP, 0, MAKELPARAM( m.x, m.y + 220 ) ); ReleaseCapture();I tried it without SetCapture and still no good. Also according to MSDN 'only foreground window can capture the mouse', I also want to be able to send input to background windows.
DD
Not what I meant, really. The input source doesn't call SetCapture, the receiving window might or might not. And where you send the messages depends on whether the target window calls SetCapture in its handler. This is something you really don't have insight into, if you need a generic method for controlling ANY program you were on the right track with SendInput. If you were looking for a way to control a particular program without messing with focus and z-order complications, then PostMessage would work better.
Ben Voigt
I am looking for a way to control any program without messing with focus and z-order. Yes that is what I need to do.Also interesting thing is I can drag an Excel plot for instance or any object using the code above, I just can't select cells.
DD
If you call ChildWindowFromPoint for both coordinates of the drag (i.e. mouse down and then mouse up), does it return the same window or two different ones? You could also use Spy++ to see what other messages are sent to Excel by mouse activity that you might not be duplicating.
Ben Voigt
Yes it returns the same window, including when I track the tree down to the leaf.I have been using Spy to duplicate the messages. The messages that I send from my application are the 1-to-1 copies (except the variables) of the messages that show up in Spy if I do dragging by hand. I even send the WM_PARENTNOTIFY to the parent. And the fact that I can drag the graph but can't select cells makes me think that Excel just does something beyond purely responding to Windows messages, which would prove my point before - not all applications handle messages the way you'd expect them to.
DD
It seems like Excel only selects cells if it has the focus. I see the same messages for dragging with or without focus, but if it didn't already have the focus, no selection is made.
Ben Voigt
And that is the end of discussion. I can't believe how incomplete the input/message API is. You would think after so many iterations of OS, oh well.
DD
Well, set focus is itself an event. And it's the application design that requires focus, not the OS (or more properly windowing toolkit) message architecture. But I can see how this might royally interfere with what you're trying to accomplish. Note that Excel does have an OLE Automation interface which has lots of capability, including setting the selection (or applying formatting to ranges without changing the selection first), but now you're getting deep into application-specific logic.
Ben Voigt
Yes anything application-specific is no good in my case.Such a concept as 'focus' is flawed as it applies to this. Focus should be device-specific not for visual purposes. I should be able to kill focus of a window to mouse but let it receive keyboard inputs, or joystick or whatever. And the framework should treat the input sent through the messaging or SendInput API as a separate input device and should always have focus to it unless it is disabled.
DD