I would like to know if it is possible to SendMessage and PostMessage to/in other application even if it is not activated, or somehow to interact with that application without disturbing the user....
So far all I want to do is detect Pixels at specific coordinates than to Click on specific coordinates.
Note: Please do not misunderstood, the reason I want to detect Pixels and than Click, is because the button does not has Class ID.
It is possible to use SendMessage and PostMessage to send mouse clicks at specific coordinates to a window. The messages to send would be like WM_LBUTTONDOWN, WM_LBUTTONUP, and WM_LBUTTONDBLCLK. These messages can be sent with the window minimized or hidden.
If you have Visual Studio, there is an included application called Spy++ (and Spy++ 64 Bit). If you use those programs and have them monitor the window messages to your target application, you can see the exact window messages that are sent when you manually click on the button.
It is difficult if not impossible to detect pixels when the window is not visible either due to being minimized, hidden, or just covered by another window. If the application will be running in Vista or later, you might try creating a DWM Live Thumbnail of the application inside your app and scanning the pixels from there to determine the button's location.
Hopefully this information will get you started or at least let you know how complicated this may be so you can make an informed decision to continue or not.
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.
I have desktop app that is in background. I later want to try this a a service too.
How can I perform mouse click when certain time and date is reached.
I don't want to move user mouse or something. Just send left mouse click from background.
Controling an application via simulated Mouse or Keyboard input goes into the Area of Desktop Automation. There are many existing solutions for it. I advise agaisnt making your own custom hack.
That asumes you do not have control over the target application of course. If that was the case, using a Timer is the obvious way.
As for doing this from a Service: That is nigh impossible. Ever since Windows Vista, Service do not get interactive Sessions by default.This is a rather important part of the UAC security. While getting around it is possible it will propably raise some red flags.
I'm working on an open-source .NET clone (GitHub) of DeskPins by Elias Fotinis (direct download off Google Drive). Its main function is to make other windows always-on-top. When they are on top, a pin icon is added to the title bar, which looks like this:
The pin icon moves with the window during drag and drop, and really looks like a part of it. It even responds to click event, which cancels always on top status and removes the icon from display.
Question. Is it possible to implement something like this in C# (and p/invoke, I'd assume)?
Research
I tried to run this project.
Add Your Control On Top Another Application # CodeProject
It's a WPF demo, which is supposed to add a custom control to the title bar. Does not seem to work on Windows 7 x64. Not sure if it's the OS or otherwise. Problem - z-order is not consistent, title bar appears on top of other windows as well, and it does not move with the window, it tries, but lots of visual artifacts and flicker.
Tried to apply this solution to #1:
Attach form window to another window in C#
Basically replacing relevant call to SetWindowLong with this pattern:
SetWindowLong(guestHandle, GWL_STYLE, GetWindowLong(guestHandle, GWL_STYLE) | WS_CHILD);
SetParent(guestHandle, hostHandle);
This change broke everything, so nothing was added to the title bar. Could be that it's not meant for title bars, only for the user area of the form.
In any case, if there is a simple solution, please share your wisdom. If not, I would appreciate any hints and/or links for me to investigate the topic further.
Here's how I've done this in DeskPins.
Each pin is a popup window with a custom HRGN defining its shape. I did experiment with injecting a DLL into processes using hooks and drawing on the caption, but that was too messy for me back then.
DeskPins creates the pin using WS_POPUP, WS_EX_TOPMOST and WS_EX_TOOLWINDOW, with 0 as the parent window. Then it immediately sends it a message (WM_PIN_ASSIGNWND), passing the target window to be pinned and the polling rate in msec. After that, the pin runs independently from DeskPins and they only send information messages to each other.
The pin handles WM_PIN_ASSIGNWND by setting the target window as its parent, making it top-most and starting a polling timer. To set the parent it uses:
SetWindowLong(hPin, GWL_HWNDPARENT, (LONG)hPinned);
Note that Microsoft warns against setting the parent like this and instead suggests using SetParent(). However, SetParent() does some internal processing which prevents it from working across processes. Using SetWindowLong(GWL_HWNDPARENT) essentially tricks the window manager to accept this. It's a bit of a hack, but, hey... it works.
The polling timer runs continuously and tests whether the target window is destroyed, hidden, moved or had its WS_EX_TOPMOST flag changed and responds appropriately.
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?
How can I print screen minimized windows? I believe it's possible, since Windows task-bar can create a preview of a window even if it is minimized.
This guy managed to do exactly what you are after: http://www.codeproject.com/Articles/20651/Capturing-Minimized-Window-A-Kid-s-Trick
I know this question is really old, but it can still be valid for someone.
I'm pretty confident that this is not possible, at least by an external application like yours. When an application window is minimized, the window cannot (and does not) receive WM_PAINT messages, meaning that it is impossible to ask the window to redraw itself while it is minimized (or, "take a picture of it"). This is a limitation (or a rule) of the Windows API.
The taskbar "gets around this" by displaying a cached image (which is the last snapshot the DWM took of the window before it was minimized) and so it is not in fact taking a current picture of the window. You can test this by running an application which periodically updates itself, and then minimizing it -- you will see that the preview image will not be updated until it is restored.
The only way you could get around this is to do what the taskbar does -- periodically take a picture of the window you want, and when it is minimized, use the cached image instead. Of course, this means your app will have had to have been following the target window some time in advance (this obviously won't work if the first time you want to take a snapshot of the window is while it is minimized).