Giving input to a GUI application through another program - windows

What i want to know is how can you give input to a GUI app that is closed source and does not have any public API.
To be more concise, let's say you open solitaire and want through a program to play it. Or, to go even to the basics, you have an GUI app with a button and you want to click it through another program.
I know the question is a little vague, but that's the best I can phrase it. Please help me with some edits or some comments to make it more specific.

Investigate SendInput(). It can be used to simulate mouse movements and key presses.
To locate a Windows application using its GUI you can use EnumWindows() to locate a Window with a particular title. This will provide a Window handle. To give that window focus, you could:
obtain the window handle via EnumWindows()
use GetWindowRect() to get the co-ordinates of the window rectangle
move the mouse to within the bounds of the window using SendInput() and simulate a mouse click using SendInput()
I have done this once, and it is infuriatingly difficult to get right. Once you start your program sit on your hands: don't touch the mouse or the keyboard.
(I have no knowledge on how to do anything like this on Linux)

Assuming its an X11 app in Linux you could connect the process to one end of a named pipe and then echo X-Input events down the other end of the pipe.

Related

Replace special character with keyboard shortcut live on input

Is there any way to replace a special character with a keyboard shortcut live?
For instance: Writing $ would actually press ctrl+n or arrow key left
Every help is much appreciated!
This is primarily speculation with a little experience and research mixed in.
This sort of thing is easy enough if you are checking in an application that currently has focus, but creating a universal keypress hook? Not so much.
I built a C#/C++ program in grad school that intercepted keystrokes intended for another application, but I was only able to do it by waiting for the desired application window to open, auto-opening my own pop-up window to receive the input, and then passing keystrokes back to the original window.
I'm not saying it can't be done, period, but my background knowledge (though slightly dated) and a little cursory research isn't turning up anything in the basic scripting world that would satisfy what you appear to be after.
The only way I know how to do it (which is likely wrong) would be to have hooks in every open application, and when a textbox on the application gained focus give focus to your own text-receiving app. Analyze the keypresses, and then pass the desired text/keypresses on to the original app/textbox. This would require prior knowledge of the "windows" (i.e. all objects) in all possible apps on the machine you're working on, so you would know when a textbox received focus.
If I recall, it might be possible to tell when keys are being pressed (if you have hooks in all apps) and re-direct from there, but you might lose the first keystroke, even then.
Again, this is primarily speculative.

How to write a program that runs another GUI program inside it

I am not sure how to ask the question so here is a picture of some idea that came to mind
So for example, when you run my "custom launcher" it displays a window with a couple buttons on the side which you can assign values to. When you click on a button, the appropriate program will run in the big panel on the right (in window mode).
This is all from the user's perspective of course. They will just see that the program they want to run appears in that panel. The actual implementation may have nothing to do with "one program running inside another program"
My own use case is limited to windows desktop platforms only, but if it is possible to generalize it that would be nice as well.
Is this actually possible? Can I write such a program that will run another program inside a panel? The program that's launched may be someone else's, such as MS paint or calculator.
Just to expand on my comment above, here is an approach that may work for you: Fake it :)
When you launch the program, intercept all windows messages to the program that control it's position on screen. That way it 'appears' to be fixed in place, but in reality it's still attached to the normal Windows desktop.
Here's some light reading for you:
Windows Event Hooks
A hook is a mechanism by which an application can intercept events,
such as messages, mouse actions, and keystrokes. A function that
intercepts a particular type of event is known as a hook procedure. A
hook procedure can act on each event it receives, and then modify or
discard the event.
I would recommend against it in a commercial application because you are modifying the behavior of software you don't own - that software may make assumptions about what its parent window is, but for experimentation there's the SetParent Win32 function.

is there a winapi call or keyboard shortcut to enter windows console into "mark" mode?

Normally user is doing it by clicking right-mouse into console title bar then selecting "edit" and finally "mark". -> http://www.megaleecher.net/Copy_Paste_Text_Dos_Window
So is there a way of doing it from a console application either by sending a message/api call/keyboard sequence to its own window ?
If this is your own application and you want the richer behaviour and flexibility of a windows app rather than a console app, then use a windows app. Otherwise, you can try to automate the steps by simulating the input via SendInput. I would advise against doing this because it requires two steps (once for right-click, once to select 'Mark'). This means if someone clicks something else between these two events, your sequence will be broken. Furthermore you are really relying on the automation of an implementation detail which is prone to change at any point.
Looking through the Console Functions, it doesn't appear as though anything exists for setting the selection. The closest is going the other way with GetConsoleSelectionInfo.
If you want to process the information that is within a console application, a better alternative is to pipe it to your own process and deal with it there.
Found: PostMessage(GetConsoleWindow(), WM_COMMAND, 65522, 0);

Show a popup menu in another application's window

How can a Delphi XE application show a popup menu inside another application's window? The idea is for a helper-type app, running in the background. On a registered hotkey the application needs to display a popup menu near the text caret or mouse cursor.
Applications that do that are common, here's a menu created by AutoHotkey and displayed in a text editor:
I guess what I'm asking is: how can I display a popup menu at an arbitrary screen location, without it being attached to a Delphi control?
Create a TPopupMenu with the appropriate menu items. When you need to show it simply call Popup passing the top left position in screen coordinates.
PopupMenu1.Popup(X, Y);
#DavidHeffernan answered your question, but you might not have asked the right question.
Let's take the example you gave: the user is running some arbirary application, and you want to be able to detect a hotkey, display a menu, and then take some action based on the menu item chosen (and maybe even the user's context, such as the word under the cursor). This is more complicated than simply displaying a menu at arbitrary screen coordinates.
My recommendation is to use AutoHotKey instead of trying to replicate this in some other programming language. In case you're not aware of this, it is possible for your code to run AutoHotKey scripts. IIRC, you can compile AHK scripts, so you wouldn't need to install AHK, just the compiled scripts. AHK may not be the most elegant of solutions, but it has depth and maturity.
If this is not possible, then I suggest you research Windows Hooks and DLL Injection. Unless you can find some preexisting code or framework, this will entail quite a bit of work.
The reason for this complexity? To augment another program smoothly (without running into problems with focus, etc.) you want to have your code run as part of that other program. The mechanics of this can be done via DLL injection. However, that's only the first step. Once your code is running in the right context, then your code has to inter-operate with the "host" program. This can be tricky (it helps if you have deep experience with Windows messaging and the Windows API). If you want this to work smoothly with any arbitrary program, it gets even harder.

Create a Program that Sits in The Windows Taskbar and, When Activated, Stops the Screensaver From Starting

I don't really know where to begin. Let's start with the stupid questions:
What language should I use for this? What is suited for the task at hand?
Next, the real ones:
Is there a way to stop the screensaver from starting, short of changing the cursor position? If not, will changing the cursor position even work?
SetThreadExecutionState will prevent the screensaver from coming on or the machine from automatically going to sleep if you pass the ES_CONTINUOUS and ES_DISPLAY_REQUIRED flags.
I wrote an app awhile ago that does exactly what you are asking for. It runs as an icon in the System Tray, not the Taskbar, and uses a global message hook to disable the WM_SYSCOMMAND/SC_SCREENSAVE notification from reaching any applications. If that notification does not reach the DefWindowProc() function, the screen saver will never run.
Your program does not need to be visible in the task bar at all.
You don't even need a program at all, if you can disable the screensaver in the registry.
What you want to do can perhaps be achieved by sending a MOUSE_MOVE event to the desktop window. If you want to use C# (the only language I am current with right now), you can look at this article, but maybe a simple C program using the WinAPI is better suited for this task.
.NET will easily allow you to put an application in the system tray (checkout the NotifyIcon object in System.Windows.Forms.Controls).
I believe you can use the SetCursorPos (http://msdn.microsoft.com/en-us/library/ms648394(VS.85).aspx) API call to prevent the screen saver, just make sure you set them to the current location so you don't actually move the mouse.

Resources