I was wondering if there was any way through C# or C++ to send to fake or otherwise trick a program into thinking it has focus? I'm thinking that there's a message you can send to it using SendMessage/PostMessage that'll trick it into having focus.
There is no guaranteed way to trick it into thinking it has focus because there are multiple ways it can check if it has focus. For example, it could be checking for WM_SETFOCUS and then checking it is out of focus when it receives WM_KILLFOCUS. So you could trick it in this case by sending intercepting all WM_KILLFOCUS messages with a window hook.
However, it might also be checking for if it has focus by calling GetFocus. So to trick it in that scenario, you would need to detour GetFocus and fake the return value. You can try both of these methods and they might work and they might not, but I wouldn't expect them to work reliably.
I hooked WM_NCACTIVATE to let the game know that it is still in focus. It worked fine on two games I worked.
Related
I am trying to hide all the windows of my app when a users session time's out. That works great; however, when a MessageBox is left open when the app times out the message box still is there. I want to be able to close the message box or at least hide it. I've looked up hwnds and hinstances and I don't quite know if thats what I am looking for to accomplish this. I thought this would be fairly easy as I thought MessageBox inherited from Window and of course it doesn't. And a top of that you cannot create an instance of message box to keep track of it. At this point I am not sure what to actually do or what to actually search for.
I am in the process of trying to figure some stuff out using reflection. I can create an instance of MessageBox using reflection but don't think I can call Show() using an instance.
Short answer: just create your own window that looks like a message box
Long answer:
Message boxes are normal WinAPI windows (they have an HWND and can be manipulated by the native API windowing functions) however they are not WPF windows and don't have an associated Window object.
Since they are normal windows you can get their HWND (using FindWindow/ FindWindowEx/ EnumWindows) and trick them into closing (for example, by simulating a Cancel button click)
However, because message boxes are not designed to be manipulated like that this trick has some nasty pitfalls you have to take care of.
And, because message boxes are so simple and you can easily create a message box clone it's just easier to create the close and not take care of all the message boxes corner cases.
So I'm trying to create a program that will lock the host computer. The way it works so far is it has a main form, where a password can be created, and the computer can be locked. When the password is created, it's stored in a location within the user's AppData, in MD5.
I have the password creation and checking bits finished just fine, but I can't manage to figure out how to make the lock work the way I want. Normally, the computers this would be run on would be locked via Windows (i.e. WinKey+L), but a need has arisen for monitoring of a different program which will always be running. However, as at times these computers may be in a public place, I am looking for a way to only allow access to input after the user's identity has been verified.
I can prevent the program from being terminated just fine, but it's somewhat problematic to detect clicks and keystrokes outside the GUI's boundaries for me. I tried handling the Deactivate event, but that doesn't work because I can't cancel the click that happens with it. I also tried using MouseMove, but then realized that the event is only raised when the mouse is moved within the form's boundaries. I also tried listening for the Leave event, but that also didn't work.
For keystrokes, I've tried checking a KeyPress event's arguments for e.KeyChar != '\t' && e.KeyChar != '\r' (is \r what the Enter key would be?) and cancelling the event, and even just bluntly using the statement e.Handled = true;, but that doesn't work either. Either way, I can still alt-tab.
Also, with the issue of keystroke checking, I realize that I can just use a Deactivate check instead, and handle FormClosing as well; however, my Deactivate event handler doesn't work either, where the only code it contains is:
this.BringToFront();
this.Focus();
At this point, I'm sure what I'm doing for the keystroke and the deactivation handlers are small errors, but I have no idea what to do for the clicking issue. Any help would be greatly appreciated.
What you are looking for is a more powerful set of Interfaces that is provided by the operating system. You can do a platform invocation of these functions, but you have to know how to marshal the API's. This is because a lot of the libraries that allow you greater control is written in C++. If you use native C++ it is more natural to invoke these commands, but C++ requires more careful attention and will take longer to learn.
If you are looking to cancel or override keystrokes or clicks, you can do so by using global hooks. Here's an article about it http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
But it only scratches the surface on the subject. You'll have to learn a bit about windows internals and the windows API. There are some books on this topic and it is very deep.
When my code is running I have a messagebox popup from excel that has a retry I just want my code to be able to simulate hitting the enter key if it pops up which it does everytime. This is the Messagebox that come up and freezes my code.
I turned off one of them using the OLE message, but I still get this messagebox any way to simulate a click on retry or enter key,?
//Turn off OLE Error Message
oXL.DisplayAlerts = false;
You can try sendkeys, to send a key stroke to the message box
InputSimulator is a very flexible (and reliable) wrapper that is capable of simulating keyboard and mouse events.
It wraps SendInput under the hood but abstracts away all the PInvoke calls and other complexity. It's a drop in DLL that (for your situation) should only take one line of code.
InputSimulator.SimulateKeyPress(VirtualKeyCode.ENTER);
I'm wondering if the problem is caused because you have a large loop that never makes use of the Application.DoEvents() call? As for dismissing the message that seems like a poor way to handle the problem to me.
A while ago I wrote a simple app, which surrounds selected text in any input field in any application with some unicode symbols when user presses some hotkey. Basically, app's logic is as follows:
Register global hotkey.
Hotkey fired, now set clipboard monitor and invoke clipboard copy to see if some text was selected.
If clipboard has changed and now contains text, surround said text with symbols and then invoke clipboard paste, so input field will be updated with modified text.
The problem is, I can't get copy/paste functionality from other apps in a reliable way. What I have tried to date:
If I send WM_COPY/WM_PASTE, it's more often ignored than not, depending on the application.
If I use SendInput, keybd_event or any other keyboard-messing stuff to press/unpress usual clipboard hotkeys, it will often tamper with user-pressed keys: copy/paste uses control or shift, which are also quite popular for all generic hotkeys in all apps, my app included.
If I use Journal Hook to directly inject keyboard messages into system input queue, sometimes it will work fine, and sometimes weird glitches will occur. Also, other applications may be using JournalHook for themselves, and that will mess my app badly. Not to mention that default security policies make journal hook hard to use.
I've been trying to get/set text in the input fields using Windows UI automation instead of clipboard magic, but it rarely works.
So, if you know other ways to make other applications reliably use copy/paste functionality, or can even devise entirely different approach, I'd really appreciate you telling me :)
I think your approach isn't that bad, maybe you can start with WM_DRAWCLIPBOARD so you can monitor the clipboard. A nice sample code can be found here.
Next I'd take a look at SendKeys class - Attention: Flush, Buffer, etc. Use this to send ctrl+c/v instead of a windows message! You should get a notification from your monitor if it worked.
Now I'd use the Cliboard class to maniplulate the Data and paste it back.
Oh, it seems that I could only find more or less reliable way of invoking copy-paste without SendInput or journal hook, but I have to deal with it :-) So here it is, in case someone find it useful:
Remember and reset keyboard modifiers via AttachThreadInput(yourAppThreadId, targetAppThreadId) + SetKeyboardState(keyStateWithoutKeyboardModifiers).
Set Ctrl key modifier via SetKeyboardState(keyStateWithControl) for Ctrl+C/V hotkey.
Then PostMessage to focused control handle with WM_KEYDOWN message for C or V key, whether you want it to copy or paste.
Call Thread.CurrentThread.Join(20) to let other app process messages — and that's the most retarded moment in the whole deal, since I couldn't find the sure way to know when other app will have empty message queue.
Restore remembered keyboard modifiers.
Also, every time you do SetKeyboardState, call SetForegroundWindow(focusedControlHandle) and SetFocus(focusedControlHandle) afterwards.
I am using the RegisterHotKey Win32 API to listen to the Ctrl_V key combination and using the WndProc method to handle this hot key notification. Now, even if I don't perform any operations in this method apart from calling base.WndProc(ref mesg), the Paste operation doesnt seem to be getting passed onto Windows and hence, paste is not working. I managed to get paste of text working by explicitly calling SendKeys("^V") but it is not working for non-text data. I also tried SendMessage Win32 API as below
SendMessage(foregroundWindowHandle, 0x302, 0, 0);
but even this is not working.
I am unable to figure out how to execute my code and then let Windows perform the paste for images, files etc. Any help in resolving this will be very timely and highly appreciated.
UPDATE: I figured out the problem was that the window where the Paste command was being generated wasnt getting the focus back. After correcting this, Paste is working fine for Notepad. Also, I am using Alt_Shift_V as the hot key now to avoid clashing with the default paste command. So pasting non-text data works fine. However, pasting text into Visual studio and Office applications is not working. SendKeys("^V") seems to be interpreted in a different way in these applications. Any idea on how to get this working?
Instead of registering a hotkey, register a global hook.
I have used global hooks to do something similar to what you are doing in the past and it works quite well.
Code for a simple and handy global hook implementation can be found at:
http://www.codeproject.com/KB/cs/globalhook.aspx
This would not interfere with the pasting operation :)
I think you should intercept the Ctrl-V Key message (through WndProc), do what you need and then let the base.WndProc handle the key message. You could also handle the OnKeyDown event.
In WinForms, you can set Form.KeyPreview to true in order to see messages before child controls.
Registering a hotkey isn't the solution if you just want to take some action and then pass on the message. It sounds like you'd need a keyboard hook instead (the SetWindowsHookEx API).