SendInput to minimized window - c#

Is it possible to utilize the sendInput function on windows that currently do not have focus, and maybe through the use of multithreading, sendinput to multiple minimized windows at the same time, or send input to one window while you're working on another window?
I'd like to do something like this in c#
thanks in advance.

You can only use SendInput to send input to the HWND with keyboard focus. Furthermore the window must be attached to the calling thread's message queue, so one cannot simply SetFocus either.
You'll need to get the window's thread id with GetProcessIdOfThread.
When you have the thread id you can use the AttachThreadInput function to attach your thread to the other threads input processing.
After all this you can probably use SetFocus and SendInput.
You'll probably want to detach your thread when you've sent your input.
To get access to these method you'll have to use P/Invoke for C# or C++/CLI. PInvoke.net is very handy as a reference. It will be a small chore importing all those functions, but when you are done you should be able to send input to whatever "window" you want.
Also as a side note, I'm not sure if you are aware of this, but in pure Win32 everything is regarded as a window, even a button. If you are unlucky you may have to send the input to the handle of the text control belonging to the notepad application.

That is not possible with SendInput. What you probably want to do is find the messages that were sent to the window by the OS when that particular event was performed then emulate them. You can use Spy++ to attach to the target window and perform your event. Then use SendMessage() and PostMessage() to reproduce the messages that were generated by your event. This will work fine for notepad.
If you do use this method, note that you need to send messages to notepad's child window which you can find with FindWindowEx() with a classname of "edit". For example to type text you could try WM_KEYDOWN. You should note that this method is not necessarily reliable:
http://blogs.msdn.com/b/oldnewthing/archive/2005/05/30/423202.aspx

Related

Perform Ctrl-C on specific window without focusing it

I have an application to which I want to send the Ctrl-C keys combination. I am trying with SendMesssage, but I know that the application checks for Ctrl-C combination using GetKeyState and GetAsyncKeyState so SendMessage is pretty useless... How can I send the Ctrl-C combination to this window without calling SetForegroundWindow(hWnd)? I need a solution which works without focusing/bringing to front the window.
I am temporarily using this code (but requires focus):
SetForegroundWindow(hWnd);
SendKeys.SendWait("^(c)");
I am using C#, but C++ code is ok.
A long time ago, back when I was doing Sys Admin automation.. I used AutoIT. It's been a long time, but if you don't mind picking up their .dll...
This is the method I'd use.. it mentions you can send directly to a window/control without focus.. in some cases you can't..
AutoIT ControlSend Method

Handling minimized programs

I need help handling minimized programs when using a custom/self made explorer.exe file .. because unless properly handled, minimized programs will just shrink to something like 100x50px and stay on screen. I worked out a Timer in C# to check for "iconic" processes, list their mainWindowHandler, and move them outside the screen with "MoveWindow". To bring them back I use the handler and the "ShowWindow" function wich works AWESOME .. but as I said, it involves a constantly running Timer, so there must be a cleaner/easier way of achieving this.
Any ideas? Some way to hook and raise an event when a window is minimized?
*please note: show and movewindow are functions from user32.dll. I'm not trying to catch when MY forms are minimized, but when the OTHERS programs are.
You can create a hook to check when windows are being minimized.
I found a CodeProject article that uses hooks to check when the user opens a system menu (ALT+SPACE) on any window, and then appends an extra item to it. You can use that code to check when the user hits the minimize button, and run whatever code you need there.
The CodeProject article is written in C++, but you can adapt the same method for C# (or use P/Invoke).

how to close a window from a different process

I have a c# application which I want to instruct to shutdown nicely, from a different process.
I also want to be able to ask it to open its main window.
I have a reference to its main window handle.
I know I can do it using elaborate schemes such as remoting or WCF.
the question is can I do it using simpler mechanisms such as window messages, or the OnClose event handlers of the window in the c# application
Pinvoke SendMessage() to send the WM_CLOSE message to the app's main window. Asking it to open its main window is probably going to be quite difficult, you cannot obtain the window handle until the window is created. Process.Start() would be the normal way.
A low cost alternative to WCF and superior to pinvoke is a named pipe or a socket to interface with the app. This requires being able to modify the source code of the app.
Process.CloseMainWindow
http://msdn.microsoft.com/en-us/library/system.diagnostics.process.closemainwindow.aspx
I think that you could probably use FindWindow to find the correct child window and then SendMessage or PostMessage to send a WM_CLOSE.
Here's another StackOverflow question that deals with doing this in C#.
Edit: Though as the other answer says in that question, you might be able to use Process.CloseMainWindow instead.
I would first make my target application "aware" of the fact that some other process might like to trigger its closing or opening of a window or doing any action. This should be implemented similar to calling any method on another process through the target app's api or public methods. ..unless you are trying to do something with 3rd party applications, I think you shouldn't attempt to directly send them messages to close or shutdown.

What is an alternative to Sendkeys for closing a legacy application?

I want my C# program to shut down a certain legacy application before proceeding. The legacy app may be shut down immediately using ctrl+x. I could do this using Sendkeys, but I've been told that sendkeys can be a little flaky. Is there an alternative way for me to send this key combination and shut the legacy app down?
If you know what the window's title is on the caption bar, such as 'Foo', then you can use p/invoke to find the window and get the handle from it 'FindWindow'. Once you get the handle, then you can use 'SendMessage' to that handle sending a 'WM_KEYUP' that denotes Ctrl+X together.
Hope this helps,
Best regards,
Tom.
If this is a GUI application. It may also respond to Alt+F4 via SendKeys.
Unlike ctrl+x, Alt+F4 will not depend on which window has focus. This is a standard accelerator for windows applications and most older GUI applications will support it. The main reason SendKey is considered flakey is because keystrokes get delivered to the focus window, which may or may not understand them. But Alt+F4 is an accelerator, so it should work regardless of which window has focus.
If you can get the handle to the main window. (use FindWindow if you don't have it already). You can
PostMessage(hwndApp, WM_SYSCOMMAND, SC_CLOSE, 0);
This is equivalent to choosing the close option from the system menu on the window. SendMessage should work as well, but PostMessage is safer since your application doesn't wait for the message to be delivered.
WM_SYSCOMMAND
Other options include:
System.Diagnostics.Process.Kill
System.Diagnostics.Process.CloseMainWindow
If the latter works, use it. If not, and you lose nothing by killing the process directly, then Kill().

detecting window text change with pinvoke

Is there any way to see if the contents of a 'window' have changed, that is referenced only by a handle? Such as one obtained from a pinvoke FindWindow?
If you want to be notified that the text changed, then no. Some windows send notifications of changes to their parent windows, but you would have to be in the process to intercept those messages, and not all windows even send notifications. (I presume by the fact that you are using FindWindow that you are not in-process)
If you want to get the text and check for yoursef, you can do that with a pinvoke to GetWindowText or to SendMessage(hwnd, WM_GETTEXT, ...); (GetWindowText is just a helpful wrapper around a SendMessage)

Categories

Resources