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
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?
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.
Related
My goal is to disable some tool-tip-like thing in window of another process. My thoughts are to block WM_MOUSEMOVE if the coordinates of mouse movement is in certain rectangle of the window.
I can use SetWindowsHookEx to receive that messages (WH_CALLWNDPROC and WH_GETMESSAGE), but it doesn't allow to block them. I can return 1 instead of calling CallNextHookEx, but it doesn't prevent WndProc of window to receive the message. However, this approach works for blocking events in MOUSE_LL/KEYBOARD_LL.
SetWindowsHookEx is also not good, because it installs hook to all windows across the system.
How I can prevent window of another process from receiving certain windows messages?
The WH_GETMESSAGE message hook doesn't let you "block" or cancel the message but you can modify it. So simply change lpMsg->message to WM_NULL to prevent the mouse move message from being processed by the target window.
Situation: I am working on an overlay application that needs to intercept the input headed to another process and block that input if necessary.
Previous Attempts: So far I have created a low level mouse hook that blocks mouse input to some target processes; however, the process I am interested in is not affected. I believe this is because the process uses Raw Input instead of usual windows messages.
Question: How can I swallow these Raw Input mouse messages?
We have a MFC Visual-C++ application that is not reacting to any user input.
(Note: Currently only known on one machine. The behavior does recur occasionally, but only after the App has been running for several days!)
The application is redrawn when we switch to it via Alt-Tab (or the Task Bar), but we cannot, for example, activate it's main window by clicking on the title bar.
We have already pulled 4 dumps with WinDbg and checked the active instructions. We always were in some redraw code or somesuch inside the main thread (the GUI thread). We definitely were/are not in a modal message loop and the main thread's stack always looked "OK". (Most/all worker threads were idling, waiting for some event, no suspicious code there either.)
When investigating the problem with Spy++, we see the behavior specified also in this separate question, namely that we seem to get paint and activation messages, but no user input is routed to the application. When I have the application window on the screen, and select it to show messages of the main window,
it will only show "generic" "referesh" messages and nothing else
If I drill deeper, and select all messages for the whole process,
this is what we see:
The app is apparently only processing messages on one hidden sub-window (00CB09F0), and what we see there is a constant stream of 200 WM_PAINT messages per second.
Normally this Sub Window isn't processing any messages at all (except refresh WM_PAINT etc. when Windows sends them). It is normally used as a drawing area and the drawing happens through a WM_TIMER message on it's parent (010A09B8) window. (This WM_TIMER message isn't shown on the hanging app either though.)
The performance profile as shown in process explorer looks like this (100% kernel time, more or less):
I'd say that you have a redraw loop in that window that receives the WM_PAINT flood.
That usually happens if you call Invalidate or similar from the processing of the WM_PAINT message, directly or indirectly.
Other posibility is that, since you say that you are using a timer to redraw the window, the actual drawing is taking more time that the time it self, so the messages pile up in the queue.
Yet another posibility is that you are invalidating the window from a different thread than the one making the painting.
Anyway, you should ensure that you are calling Invalidate*() properly (you showed no code), and never from the OnPaint event. And avoid calling UpdateWindow() as this function can mess things if called without a little care.
I've seen this problem when an exception is thrown from a dialog. MFC's DoModal function disables the main program window then reenables it when the dialog returns; exceptions bypass the reenabling part and the main window remains disabled forever.
Can SendInput be used to simulate a drap & drop operation?
I've got an application that accepts files of a certain format that are dropped on it, but not from the command line, and I want to associate it with a file. I thought I'd create a small tool that finds the window, and simulates a drag & drop of the file - is this at all possible? Do I need to use SendInput or possibly SendMessage? What would be the parameters?
Yes, pretty likely. SendInput injects mouse events at a very low level. SendMessage won't work.
You'll need a thread since DoDragDrop is a blocking call. Fake the mouse down first, start the thread, call DoDragDrop. The thread should sleep to give enough time for DoDragDrop to get started, then fake mouse move and mouse up. Keep fingers crossed that it works the first time, it is impossible to debug if it doesn't.
The shell already has a function that simulates a drop: SHDoDragDrop, no need for hacks like faking mouse input.
Since you are talking about the commandline, XP added support for simulating D&D for applications/registered file types: How do I accept files to be opened via IDropTarget instead of on the command line?
Base question: TStatusBar flickers when calling Update procedure. Ways to painlessly fix this
The executed code is in the questions first posts first part ( you can see light grey separating line ) ...
But - problem is that while this code is executed, form does not automatically activate and focus on the top of all other applications.
I have read these articles:
http://www.installationexcellence.com/articles/VistaWithDelphi/Original/Index.html
http://delphi.about.com/od/formsdialogs/l/aa073101b.htm
but according to them it should be working no matter what. I tried all the TApplicationEvents and TForm events with Show; Visible: Repaint; Refresh; BringToFront; ... nothing works.
So - I think I have two options - multithreading or trapping WM_SYSCOMMAND message and in the SC_ACTIVE event simply repaint form. Could this scenario become successful?
None of your linked articles deal with the problem you are having. What you see is the behaviour of a program that does not process Windows messages, so consequently it will not redraw parts that become invalid, and it will not react to keyboard or mouse input (for example moving or resizing with the mouse, or app activation using the taskbar button).
In your code you call StatusBar1.Update, so at least the status bar text is redrawn, but apart from coming to the foreground your application is probably also ignoring move or resize requests.
You need to process Windows messages in a timely manner, so any execution path that takes more than say 200 or 300 milliseconds needs to make sure that messages are handled, otherwise the application will appear unresponsive or hung.
You have basically three options:
Keep the long running code, and insert calls to Application.ProcessMessages - this will allow Windows messages to be processed. Make sure that you keep the code from being entered again, for instance by disabling all the controls that are used to start the operation.
Rework your code in a way that it appears as a sequence of steps, each taking no more than a few 10 milliseconds. Put calls to the code in a timer event handler, or call it from the Application.OnIdle handler.
Call your code in a worker thread, and post messages to the main GUI thread to update your UI.
All these options have their own pros and cons, and for multithreading especially there is a lot of questions and answers already here on SO. It is the most difficult but best option overall when you are working on anything more than a toy program.