WPF: How to interact with inactive window? - c#

Is it possible to interact with an inactive window from another window? I want to focus a textbox in a window without making it active, and then send keystrokes and mouse events to it. It seem to be possible to send messages to inactive windows using SendMessage but could it be possible to also focus a textbox in the window and send keystrokes to it, without ever making the window active?

Have a look at the same question worded a little different here
Quote #Kevin Montrose: "Windows assumes that the activate window is the one getting keyboard input. The proper way to fake keyboard input is with SendInput, and you'll notice that it sends messages to the active window only."

Did you have a look at UI Automation?
Getting a pattern and invoking it isn't that hard. The only thing I am not sure about is whether or not the window will get the focus.
Of course this will only work in the same process.

Related

Shockwave Flash Object doesn't support MouseWheel Event

I've a Windows Form Application that does a simple task : the user selects a video in the main form, and the application pops up a new form with a Shockwave Flash Object reproducing it.
What i would like to do now is to move in the Movie timeline when the user scrolls the mouse wheel. The problem is, the Flash object steals the focus from the form as soon as it pops up, and it doesn't support a mousewheel event.
Is there a way to do it, other than hooking the MouseWheel event and redirect it to the application when the popup has the focus?
The window displayed by Flash is owned by a different process. That makes messing with messages difficult, you'll at least need a low-level mouse hook to see the mouse message before it disappears into the other process.
The boilerplate code is available here. Beware that it has a bug that prevents it from working on .NET 4 and up, see this answer for the workaround.

Does NotifyIcon have a MouseDown equivalent?

I have a NotifyIcon in the system tray. How can I detect when the user has left-clicked down on it? I assumed the MouseDown event would be what I want to use but it only handles right click and middle-button click. For left-click, it only fires after the user has let go (as in they've just performed a normal click). Is there a way to get the MouseDown event only?
This is by design, the shell synthesizes the MouseDown message from the up event. You'll see why it works this way when you click and hold the button down and then start dragging. Note how the notification area overflow window pops up and lets you drag the icon into it to remove it from the visible area. It can't work both ways.
Technically you could hook the window owned by Explorer.exe to get a crack at the messages before Explorer does with SetWindowsHookEx(). That however requires a kind of DLL that you cannot write in C#, it needs to be injected into Explorer. Very destabilizing and hard to beat the competition that is trying to do the same thing. Also the kind of code that causes sleepless nights for the Microsoft appcompat team.
It appears that the underlying Win32 API Shell_NotifyIcon sends a WM_LBUTTONDOWN message when the user clicks the icon. According to MSDN anyway.
Examining the Windows Forms source code for NotifyIcon reveals standard mouse down event handling, so if the Win32 message was being sent at the "correct" time it would work as you want/expect.
I have to agree with a previous comment that NotifyIcon will be swallowing WM_LBUTTONDOWN since it needs to do mouse capture to allow the user to drag the icons about.
It's possible that this article about creating a tray icon for WPF will be useful since it shows how to use SetWindowsHookEx etc from C#.

How to know which control window got focus right now in Modal dialog using Win32 API?

I am trying to do something with the Modal dialog in Win7. To do that I need to know which control window has got focus right now by using Win32 API. If I could know which control is now got focus then I can send message to this window to do some specific task.
Could any one suggest me how should I know which control has got focus right now using win 32?
If you want to know which window has keyboard focus and you're only interested in windows belonging to your own thread use GetFocus.
Finding out which window in the entire system has focus requires a few steps:
GetForegroundWindow
GetWindowThreadProcessId
GetGUIThreadInfo

How do I block all keyboard and mouse input to my WinForms app?

I have a WinForms app that is retrieving data from a web service on a worker thread and I need to disable all input to my app until the data is loaded.
Currently, I create a semi-transparent form and place it over my application. When the data call completes I close this overlay form. This works fine accept that it causes considerable performance problems for users running the application over terminal services. I tried making the overlay entirely transparent but that still triggers two redraws of the entire window so this did not help at all.
I know that a common recommendation for handling this is to disable all the controls, but that would also redraw much of the screen so I'm looking for another way to block all user input. Any assistance would be greatly appreciated!
UPDATE: I should have mentioned that we have considered the modal dialog. Currently we show the overlay, start the data access thread then construct the form. If there is no better way to block input (App.BlockInput() might be nice) then we could use the modal dialog idea, but we would need to wait until the form construction had completed and there isn't currently a nice, central location to do this.
You could display a small modal (modalForm.ShowDialog(yourForm)) form with progress bar rolling on top of your app. This won't cause big areas to be redrawed.
If your app really is blocked while the operation is running, I'd do what Microsoft frequently does: open a modal dialog box with some kind of throbber animation or ProgressBar, and a Cancel button. Redraw is limited because you're only drawing the size of the new dialog, and input to the rest of your application is blocked because the dialog is modal. Also, users are much more willing to wait when you have some kind of status updates and or animation, because it looks like the computer is "working".
However, if there are operations your user can do while your web service request is running, it's better to leave the controls accessible. At very least, there should always be a way to interrupt/abort the process.
Update: Since you now changed the question: How long is it taking to construct the modal dialog? Why not simply construct the dialog empty, and then populate its controls? If all you have is a small dialog box with a single button and a single ProgressBar, then calling dialog.ShowDialog() should happen faster than your user can interact with your UI. Is that not the case?
One thing you could try for keyboard input is setting the KeyPreview property of the form to True. This will pass all keyboard events to the Form object first instead of to the individual controls. Create an event handler for the KeyPress event of the form and in there you can set the Handled property of the KeyPressEventArgs to True to prevent the key stroke from being passed to any of the controls. If you're currently retrieving data from the web service, set the Handled property True otherwise set it to False and the key stroke will be passed to the controls.
If someone has a good idea on how to handle the mouse input yet you're set.
I'd typically create a LockUI() and UnlockUI() functions in my form that toggle controls and flip a local form field that acts a flag to indicate a long running process. This approach works really well if you use a command pattern.
As previously mentioned, you could toggle keyboard input by using the KeyPreview property of the form (as suggested by TLiebe).
As far as mouse input is concerned, you could disable mouse activity by hooking the WinProc messages and intercepting mouse input messages. This is basically what KeyPreview does.

Desktop Development : Remember Target After Losing Focus

Is it possible to take focus from another program to respond to an event, but then once the response has been handled, switch back to the previous program and restore the cursor where it was?
This sounds like a weird question, but think of it along the lines of
User is typing in a text box in Program A.
A window for Program B pops up and user presses a few buttons to confirm something.
Program B returns control to Program A and restores the selection of the textbox.
If there is a complete C# solution, then great, but this sounds like it might require a little more effort than usual.
Any thoughts?
Personally, doing this could very likely result in the user selecting undesired values in the popup window. For example, someone is typing away in Word. Your application pops up a window, where hitting "Enter" selects a value ... such as the default button. Without wanting to, the user "selected" an incorrect value on your form.
Windows itself tends to do this, and it's very annoying. Quickly double-clicking a desktop shortcut to open an application and then switching back to (for example) an e-mail before the app launches, will tend to remove focus from the focused e-mail window and put focus in the just-opened application, causing your e-mail text or keyboard strokes to go to the just-opened window.
In my experience windows programs work just this way. It often appears that they don't because the user is returning focus with a mouse-click, which itself resets the focus. If it's a winforms app you can probably do something with the lost focus/got focus events at the form level.

Categories

Resources