According to this article on msdn, it is possible to set a specific window as the foreground window, and then send keystrokes to it... but I need to send keystrokes to a window in the background, so that whatever the user is doing can continue uninterrupted.
Maybe you should just catch the keystrokes in your foreground window and pass them to the background window (delegate). Or if they are somewhat complex you could use global hotkeys. Anyways passing the keys from your foreground form to your background form should be the better solution.
I found a nice example it's not about hotkeys but the concept should apply in your case as well.
http://www.codeproject.com/KB/cs/pass_data_between_forms.aspx
So basically a keystroke listener? Java has a robot class that listens for keystrokes and can act upon them (ex. me typing "Hello World" and the class will automatically write that to a file or other window).
I've created something similar in the past. You can create a java program to run in the background in a constant while loop and just listen for keystrokes. Set the program to write each keystroke to a file or specific place. Because this is a short while loop and only reacts when a key is pressed, it takes up almost no processing power and does not affect the performance of the program in the foreground.
I do this with shortcut keys. I have an application that has multiple child windows along the side. The main window enables the Form.KeyPreview property of the child windows and then registers for the appropriate event (KeyPress, KeyDown or KeyUp) on that child window. With this setup the main window can process all the keys from the child windows.
The technique I've used on Windows Mobile/CE is to hook the keyboard and then simply use PostMessage() to send them to the target window to be handled as normal. This technique should also work on the desktop. There are several examples on Code Project of hooking the keyboard - http://www.codeproject.com/KB/system/globalsystemhook.aspx. Your question was not clear if the foreground window was part of your application or not. If it is, wouldn't you simply subscribe to one of foreground form key events from the background form?
Related
My app screencaptures another window that runs on a second monitor. Now I'd also like to forward mouse clicks made in my app to that window. I tried using SendMessage in user32.dll for this, but this also makes window focus switch, which causes some issues, like the two windows rapidly fighting for focus. Is there are way to place those mouse events without making the hidden window active and losing focus on the main app?
Is there are way to place those mouse events without making the hidden window active and losing focus on the main app?
No, there is not even a way to forward mouse input to another receiver. Messages are only part of the input processing. The system also does internal bookkeeping and you cannot replicate that.
The only reliable way to inject input is by calling SendInput. Doing so doesn't allow you to specify a receiver. Input goes to whichever thread is determined to be the receiver by the system.
Although, more often than not, this question is asked when the problem that needs to be solved is a different one altogether: How do you automate a UI? The answer to that question is UI Automation.
Summary
How do you prevent the shift-key, which is part of a global hotkey, from interfering when sending text to the active window in Windows, by calling System.Windows.Forms.SendKeys.Send("abc") from another process when a shift-containing-global-hotkey is activated?
The problem
The window which is active when the hotkey is activated misinterpret the text sent to since the shift-key, which is part of the hotkey, is still pressed while it receives and process the the text sent to it. It is humanly impossible to release the shift-key fast enough so it is still not pressed when the text is received.
It is not possible to change the hotkey to not contain shift, and even if were possible, the ctrl-key would interfere with the processing in a similar way.
The sending application is run as a normal user without admin privileges, and UAC is enabled.
There is a background application running in windows. It is a normal .NET C# WinForm application, started by the user and running without a visible GUI.
The background application has registered a global hotkey, that is, a hotkey that can be pressed anywhere in Windows, no matter which application is currently active.
The hotkey is: <shift>+F9 (RegisterHotKey(hWnd, hotkeyId, 4/*MOD_SHIFT*/, 120 /*Keys.F9*/);
When the hotkey is activated, the background application calls System.Windows.Forms.SendKeys.Send("abc")
The active window receives the text "abc", but since the shift-key from the hotkey is still pressed, the result end up as "ABC".
The question
What are the possible ways to make sure the text sent end up the same after the receiving window get, process and interpret it?
That is, when sending "abc" to a running instance of notepad.exe by pressing <shift>+F9, the text showing up in notepad should be "abc" and not "ABC".
As far as I can tell,
Check the Shift modifier status, and only send your keys after you verify that it is not pressed
Don't use SendKeys
I think that #1 is pretty self explanatory, but keep in mind that even if you verify that Shift is not pressed before you start sending keys, Its possible that the user can still press Shift or another modifier while you are sending keys, or even worse its possible for the active window to lose focus and stop it completely. If you're designing a program that simply inserts user-defined text after a hotkey press and the user is expecting it, then this is not a big deal and is the appropriate way to to this.
You have a few options for #2, I'd suggest looking into using SendMessage with An apropriate message (WM_CHAR, WM_SETTEXT, WM_KEYDOWN, or etc) to send a message directly to the window in question.
After everything is said, its important to realise that this is a really uncertain process. You can never guarantee that simulating keyboard inputs or sending key messages will register as you would like them to and it may largely depend on the application your sending messages to (esp in the case of SendMessage).
What I am trying to do is have a helper application that a user can use touch input to affect a second application. I have been able to send keystrokes to the second application, but the problem I am having is when I want to hold a button down.
For example on my application, I want to be able to hold down a button which would simulate a ctrl key down. And while this button is touched, I want to be able to interact with the second application. And if the user lets go of the button, then the ctrl key is undressed. I can kind of get this working, except when the user does anything on the second application, the button that was held down is unpressed (because the other application gained focus).
I don't care if I have to go WPF or windows forms, just as long as I can get it working. Windows 8 or 8.1 only is acceptable as well (all clients will be 8.1).
Any help would be appreciated!
Note I added to a comment below.
The second application is one I haven't created, it could be anything really. A scenario would be my application having a ctrl button that you could hold press and hold, for example, and in outlook click a link. Or pressing and holding a shift button in my app, while drawing with a pen in photoshop to draw a straight line. I am able to send key strokes, but just can't handle the "hold" touch command.
Since it's been so long, I'm creating a new answer. I did the research, and I'm pretty sure I know what's going on. But I'm going to mention all the official resources I examined before coming to my conclusion.
Possible packaged solutions
First off, the new Windows Input Simulator might fix all your troubles right out of the box. If you need the Windows API, which I'll be talking about below, check PInvoke.net first to see if they have documentation for the call you're trying to make.
The Windows API way
The best place to start is the User Interaction article on MSDN. There's a bunch of new Winu8 Touch APIs there, but you're probably interest in the legacy Keyboard input article.
Every window for an application must have a Windows Procedure (a.k.a WindowsProc) that's responsible for reacting to messages it cares about (e.g. a button click, a message indicating the Window needs to draw its GUI, or the WM_QUIT event that alerts it to gracefully dispose of the resources held by the Window. This procedure is also responsible for handling messages from input devices, like mouse-clicks and keys on the keyboard.
In your case, you're more interested in making the Window think there's a message from the keyboard when there isn't. That's what the SendInput API call is for; it lets you insert an array of INPUT messages, be they keyboard, mouse, or other input device directly into the queue, bypassing the need for the user to physically act. This easy API call specifically accepts MOUSEINPUT, KEYBDINPUT, or HARDWAREINPUT messages.
For the keyboard, you'll get a message when a key is pressed (WM_KEYDOWN) and when it is released (WM_KEYUP), so to determine hotkeys like CTRL+C, you have to watch for WM_KEYDOWN message for the letter C that were received after a WM_KEYDOWN for the CTRL key but before its WM_KEYUP message.
Managing input device messages
To simulate input devices, use SendInput to pass along the WM_KEYDOWN and/or WM_KEYUP message(s) to the target Window. But don't forget that an application can have more than one window. There are API calls to get the different Windows, but it'll be up to you to write code to find it before you can use SendInput on it.a
To find out what a window believes about an input device, use GetAsyncKeyState. You may not be able to trust it if you've meddled with APIs related to input devices.
There is a BlockInput call on a window which denies all messages except SendInput calls from the thread which blocked it. In most cases, re-enabling input as soon as possible is the right thing. The documentation say that if the blocking thread dies, BlockInput is disabled. A similar but less harsh call is EnableWindow which prevents a window from receiving input focus.
The API for windows includes the ability to register hooks, which let you specify kinds of messages and/or certain windows to be reviewed by a user-specified function.
I would really like to know why you need this to be in two different applications, but here's the best I can think of.
In the applications, you should be able to subscribe to KeyDown, KeyUp, Focus, and Blur (lost focus). I'm not clear on if this is an actual button or if its touch input, but whatever the case may be, assume KeyDown is whatever event fires when the user is "simulating" the ctrl key being pressed, and KeyUp is whatever event fires when the user is ceases to "simulate" the ctrl key being down.
Set up the App1 so when it gains focus, it communicates with the App2 the state: depressed, or not depressed. Every time KeyDown or KeyUp fires, send a message to App2.
When App1's Blur event fires, stop sending messages to App2. Even though App1 will no longer have the button depressed, App2 won't know it and can continue to behave as though the button was depressed until App2 regains focus and can go back to sending messages again.
If it were me, I would have App2 have all the same logic as App1, so the moment App2 gets in Focus, it begins handling the up/down state itself. You may want to have the two applications do some kind of "handshake" when a blur/focus event happens to make sure the state is preserved when switching between. When App2 gets the Blur event, it transfers to App1 the state and they shake hands again, so App1 knows its now responsible for managing the state.
This is basically having the apps cooperate via "tag-team." They keep some state synchronized between each other, "handing off" the responsibility when the blur/focus events fire. Since you cannot know that Blur will fire on one app before Focus fires on the other, you will need to use the same mechanism that communicates the state of this "simulated button" to coordinate the apps so they never interfere with each other.
Something tells me that this doesn't completely solve your problem, but hearing why it doesn't will certainly get everyone closer to thinking out the rest of the way. Let me know the twist ending, eh?
I need to be able to issue keyboard input to a particular window in the background on a periodic basis without interrupting the user. How could this be done?
Use case:
I have two windows open: one window is waiting for the input (window A), and I'm actively working in another window (window B). While working in window B, periodic commands are issued to window A through the keyboard without interrupting the interactivity going on in window B.
I'm hoping to accomplish this using Python or C#...whichever gets the job done cleanest and fastest (or a nice hybrid thereof).
Check winGuiAuto.py. If you can find the hwnd for the control whose input you want to change, you can send it to it even if it's not the active window.
Even it doesn't solve your problem directly, the source code is a good lesson on using the win32api with Python and should help you anyway.
How do I prevent the start menu from opening by using the keyboard shortcuts / combo (aka windows key and CTRL + ESC) ?
I am able to hide the taskbar, and receive the keys but I don't know how do I disable them, I need to disable it until the user is authenticated with the system.
Is there a policy I can use to disable them or how do I do it ?
This sounds like a job for hooks
http://www.codeproject.com/KB/cs/globalhook.aspx
Update:
From MSDN:
A global hook monitors messages for
all threads in the same desktop as the
calling thread. A thread-specific hook
monitors messages for only an
individual thread. A global hook
procedure can be called in the context
of any application in the same desktop
as the calling thread, so the
procedure must be in a separate DLL
module. A thread-specific hook
procedure is called only in the
context of the associated thread.
In other words, if you use a global hook like in the link, you can capture system events and either process them like normal events or suppress them.
Another Update: Here is another example which was created with the Windows key and CTRL+ESC in mind.
Would the example here be what you are looking for?
http://geekswithblogs.net/aghausman/archive/2009/04/26/disable-special-keys-in-win-app-c.aspx
I've never done this myself, but I heard that you should replace explorer shell with your program for that kind of application. Look into it, maybe it's the way to go..
http://www.ehow.com/how_5688935_replace-window-shells.html
https://groups.google.com/group/microsoft.public.windows.server.scripting/browse_frm/thread/fa1760ad06c77259?hl=en&pli=1